fix: resolve frontend audit findings
Frontend security / security (push) Successful in 10s
Frontend verify / verify (push) Successful in 4m57s
Conventional commits / commits (pull_request) Successful in 28s
Frontend security / security (pull_request) Successful in 10s
Frontend verify / verify (pull_request) Successful in 5m10s

Repair investment recovery, draft preservation, date validation,
currency presentation, accessibility, and route error recovery.
Correct Docker and dependency checks and consume explicit income roles.
This commit is contained in:
2026-09-27 11:38:20 +03:00
parent b34c1c860a
commit f6db28defa
50 changed files with 2017 additions and 215 deletions
+285 -35
View File
@@ -2668,6 +2668,7 @@
"name": "from",
"required": false,
"in": "query",
"description": "Inclusive calendar date in Europe/Moscow. Supply both from/to or neither.",
"schema": {
"format": "date",
"type": "string"
@@ -2677,6 +2678,7 @@
"name": "to",
"required": false,
"in": "query",
"description": "Inclusive calendar date in Europe/Moscow, no later than today. Supply both from/to or neither.",
"schema": {
"format": "date",
"type": "string"
@@ -2878,6 +2880,7 @@
"name": "from",
"required": false,
"in": "query",
"description": "Inclusive calendar date in Europe/Moscow. Supply both from/to or neither.",
"schema": {
"format": "date",
"type": "string"
@@ -2887,6 +2890,7 @@
"name": "to",
"required": false,
"in": "query",
"description": "Inclusive calendar date in Europe/Moscow, no later than today. Supply both from/to or neither.",
"schema": {
"format": "date",
"type": "string"
@@ -2984,7 +2988,7 @@
"name": "from",
"required": false,
"in": "query",
"description": "Inclusive start date (YYYY-MM-DD). Defaults to today in UTC.",
"description": "Inclusive UTC calendar start date (YYYY-MM-DD). May be supplied independently; defaults to today in UTC.",
"schema": {
"format": "date",
"type": "string"
@@ -2994,7 +2998,7 @@
"name": "to",
"required": false,
"in": "query",
"description": "Inclusive end date (YYYY-MM-DD). Defaults to 30 days after from.",
"description": "Inclusive UTC calendar end date (YYYY-MM-DD). May be supplied independently; defaults to 30 days after from. Timestamp queries use the start of the following UTC day as the exclusive end.",
"schema": {
"format": "date",
"type": "string"
@@ -3100,7 +3104,7 @@
"name": "from",
"required": false,
"in": "query",
"description": "Inclusive start date (YYYY-MM-DD). Defaults to today in UTC.",
"description": "Inclusive UTC calendar start date (YYYY-MM-DD). May be supplied independently; defaults to today in UTC.",
"schema": {
"format": "date",
"type": "string"
@@ -3110,7 +3114,7 @@
"name": "to",
"required": false,
"in": "query",
"description": "Inclusive end date (YYYY-MM-DD). Defaults to 30 days after from.",
"description": "Inclusive UTC calendar end date (YYYY-MM-DD). May be supplied independently; defaults to 30 days after from. Timestamp queries use the start of the following UTC day as the exclusive end.",
"schema": {
"format": "date",
"type": "string"
@@ -5001,7 +5005,31 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InvestmentScreenDto"
"oneOf": [
{
"$ref": "#/components/schemas/IncomeInvestmentScreenDto"
},
{
"$ref": "#/components/schemas/EventsInvestmentScreenDto"
},
{
"$ref": "#/components/schemas/TimestampInvestmentScreenDto"
}
],
"discriminator": {
"propertyName": "screen",
"mapping": {
"income": "#/components/schemas/IncomeInvestmentScreenDto",
"events": "#/components/schemas/EventsInvestmentScreenDto",
"accounts": "#/components/schemas/TimestampInvestmentScreenDto",
"account": "#/components/schemas/TimestampInvestmentScreenDto",
"operations": "#/components/schemas/TimestampInvestmentScreenDto",
"stocks": "#/components/schemas/TimestampInvestmentScreenDto",
"bonds": "#/components/schemas/TimestampInvestmentScreenDto",
"stock": "#/components/schemas/TimestampInvestmentScreenDto",
"bond": "#/components/schemas/TimestampInvestmentScreenDto"
}
}
}
}
}
@@ -6878,6 +6906,129 @@
"entries"
]
},
"IncomeDependencyDto": {
"type": "object",
"properties": {
"dataRevision": {
"type": "string"
},
"stateVersion": {
"type": "string"
},
"unavailableReason": {
"type": "string"
},
"coverage": {
"$ref": "#/components/schemas/InvestmentCoverageDto"
},
"resourceKey": {
"type": "string"
},
"availability": {
"type": "string",
"enum": [
"missing",
"partial",
"complete"
]
},
"freshness": {
"type": "string",
"enum": [
"unknown",
"fresh",
"stale"
]
},
"lastSuccessfulAt": {
"type": "string",
"format": "date-time",
"nullable": true
},
"sync": {
"$ref": "#/components/schemas/InvestmentSyncDto"
},
"role": {
"type": "string",
"enum": [
"selected",
"previous",
"year"
]
}
},
"required": [
"dataRevision",
"stateVersion",
"resourceKey",
"availability",
"freshness",
"lastSuccessfulAt",
"sync",
"role"
]
},
"IncomeAnalyticsMetaDto": {
"type": "object",
"properties": {
"dataRevision": {
"type": "string"
},
"stateVersion": {
"type": "string"
},
"unavailableReason": {
"type": "string"
},
"coverage": {
"$ref": "#/components/schemas/InvestmentCoverageDto"
},
"resourceKey": {
"type": "string"
},
"availability": {
"type": "string",
"enum": [
"missing",
"partial",
"complete"
]
},
"freshness": {
"type": "string",
"enum": [
"unknown",
"fresh",
"stale"
]
},
"lastSuccessfulAt": {
"type": "string",
"format": "date-time",
"nullable": true
},
"sync": {
"$ref": "#/components/schemas/InvestmentSyncDto"
},
"dependencies": {
"description": "Dependencies identified by role, not array order or resourceKey. A missing role is unavailable.",
"type": "array",
"items": {
"$ref": "#/components/schemas/IncomeDependencyDto"
}
}
},
"required": [
"dataRevision",
"stateVersion",
"resourceKey",
"availability",
"freshness",
"lastSuccessfulAt",
"sync",
"dependencies"
]
},
"IncomeAnalyticsResourceDto": {
"type": "object",
"properties": {
@@ -6891,7 +7042,7 @@
]
},
"meta": {
"$ref": "#/components/schemas/InvestmentResourceMetaDto"
"$ref": "#/components/schemas/IncomeAnalyticsMetaDto"
}
},
"required": [
@@ -8677,6 +8828,62 @@
"token"
]
},
"IncomeInvestmentScreenDto": {
"type": "object",
"properties": {
"accountId": {
"type": "string"
},
"screen": {
"type": "string",
"enum": [
"income"
]
},
"from": {
"type": "string",
"format": "date",
"description": "Inclusive start calendar date in Europe/Moscow (YYYY-MM-DD). Supply both from and to, or neither for the current Moscow month."
},
"to": {
"type": "string",
"format": "date",
"description": "Inclusive end calendar date in Europe/Moscow (YYYY-MM-DD). Supply both from and to, or neither. Timestamp queries use the start of the following Moscow day as the exclusive end, capped at now."
}
},
"required": [
"accountId",
"screen"
]
},
"EventsInvestmentScreenDto": {
"type": "object",
"properties": {
"accountId": {
"type": "string"
},
"screen": {
"type": "string",
"enum": [
"events"
]
},
"from": {
"type": "string",
"format": "date",
"description": "Inclusive UTC calendar start date (YYYY-MM-DD). May be supplied independently; defaults to today in UTC."
},
"to": {
"type": "string",
"format": "date",
"description": "Inclusive UTC calendar end date (YYYY-MM-DD). May be supplied independently; defaults to 30 days after from. Timestamp queries use the start of the following UTC day as the exclusive end."
}
},
"required": [
"accountId",
"screen"
]
},
"SyncCandleRangeDto": {
"type": "object",
"properties": {
@@ -8694,34 +8901,12 @@
"to"
]
},
"InvestmentScreenDto": {
"TimestampInvestmentScreenDto": {
"type": "object",
"properties": {
"screen": {
"type": "string",
"enum": [
"accounts",
"account",
"operations",
"income",
"events",
"stocks",
"bonds",
"stock",
"bond"
]
},
"accountId": {
"type": "string"
},
"from": {
"type": "string",
"format": "date-time"
},
"to": {
"type": "string",
"format": "date-time"
},
"instrumentUid": {
"type": "string",
"format": "uuid"
@@ -8759,6 +8944,28 @@
"type": "number",
"minimum": 1,
"maximum": 1000
},
"screen": {
"type": "string",
"enum": [
"accounts",
"account",
"operations",
"stocks",
"bonds",
"stock",
"bond"
]
},
"from": {
"type": "string",
"format": "date-time",
"description": "Start instant for operations."
},
"to": {
"type": "string",
"format": "date-time",
"description": "End instant for operations."
}
},
"required": [
@@ -8773,7 +8980,31 @@
"format": "uuid"
},
"scope": {
"$ref": "#/components/schemas/InvestmentScreenDto"
"oneOf": [
{
"$ref": "#/components/schemas/IncomeInvestmentScreenDto"
},
{
"$ref": "#/components/schemas/EventsInvestmentScreenDto"
},
{
"$ref": "#/components/schemas/TimestampInvestmentScreenDto"
}
],
"discriminator": {
"propertyName": "screen",
"mapping": {
"income": "#/components/schemas/IncomeInvestmentScreenDto",
"events": "#/components/schemas/EventsInvestmentScreenDto",
"accounts": "#/components/schemas/TimestampInvestmentScreenDto",
"account": "#/components/schemas/TimestampInvestmentScreenDto",
"operations": "#/components/schemas/TimestampInvestmentScreenDto",
"stocks": "#/components/schemas/TimestampInvestmentScreenDto",
"bonds": "#/components/schemas/TimestampInvestmentScreenDto",
"stock": "#/components/schemas/TimestampInvestmentScreenDto",
"bond": "#/components/schemas/TimestampInvestmentScreenDto"
}
}
},
"now": {
"type": "string",
@@ -8813,13 +9044,32 @@
"format": "uuid"
},
"scope": {
"nullable": true,
"type": "object",
"allOf": [
"oneOf": [
{
"$ref": "#/components/schemas/InvestmentScreenDto"
"$ref": "#/components/schemas/IncomeInvestmentScreenDto"
},
{
"$ref": "#/components/schemas/EventsInvestmentScreenDto"
},
{
"$ref": "#/components/schemas/TimestampInvestmentScreenDto"
}
]
],
"discriminator": {
"propertyName": "screen",
"mapping": {
"income": "#/components/schemas/IncomeInvestmentScreenDto",
"events": "#/components/schemas/EventsInvestmentScreenDto",
"accounts": "#/components/schemas/TimestampInvestmentScreenDto",
"account": "#/components/schemas/TimestampInvestmentScreenDto",
"operations": "#/components/schemas/TimestampInvestmentScreenDto",
"stocks": "#/components/schemas/TimestampInvestmentScreenDto",
"bonds": "#/components/schemas/TimestampInvestmentScreenDto",
"stock": "#/components/schemas/TimestampInvestmentScreenDto",
"bond": "#/components/schemas/TimestampInvestmentScreenDto"
}
},
"nullable": true
},
"now": {
"type": "string",