feat: add all-accounts portfolio pages

Reuse account sections and group securities with per-account holdings.

Use Mantine Select to preserve filters and reset pagination on scope changes.

Document component reuse guardrails and cover routes, grouping and scope switching.
This commit is contained in:
2026-09-09 20:36:49 +03:00
parent c906dfa2e2
commit daf1dca666
36 changed files with 1962 additions and 117 deletions
+483
View File
@@ -680,6 +680,139 @@
]
}
},
"/api/v1/brokerage-accounts/all/operations": {
"get": {
"operationId": "BrokerageOperationsController_all",
"parameters": [
{
"name": "from",
"required": false,
"in": "query",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "to",
"required": false,
"in": "query",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "categories",
"required": false,
"in": "query",
"schema": {
"type": "array",
"items": {
"type": "string",
"enum": [
"trade",
"income",
"tax",
"fee",
"transfer",
"other"
]
}
}
},
{
"name": "cursor",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"schema": {
"minimum": 1,
"maximum": 1000,
"default": 100,
"type": "number"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BrokerageOperationsPageDto"
}
}
}
},
"400": {
"description": "Invalid request",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"401": {
"description": "Authentication required",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"404": {
"description": "Resource not found",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"503": {
"description": "Upstream service unavailable",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
}
},
"security": [
{
"bearer": []
}
],
"tags": [
"brokerage-accounts"
]
}
},
"/api/v1/brokerage-accounts/{accountId}/operations": {
"get": {
"operationId": "BrokerageOperationsController_get",
@@ -821,6 +954,82 @@
]
}
},
"/api/v1/brokerage-accounts/all/portfolio": {
"get": {
"operationId": "PortfolioController_all",
"parameters": [],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PortfolioDto"
}
}
}
},
"400": {
"description": "Invalid request",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"401": {
"description": "Authentication required",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"404": {
"description": "Resource not found",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"503": {
"description": "Upstream service unavailable",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
}
},
"security": [
{
"bearer": []
}
],
"tags": [
"brokerage-accounts"
]
}
},
"/api/v1/brokerage-accounts/{accountId}/portfolio": {
"get": {
"operationId": "PortfolioController_get",
@@ -906,6 +1115,82 @@
]
}
},
"/api/v1/brokerage-accounts/all/events": {
"get": {
"operationId": "UpcomingEventsController_all",
"parameters": [],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpcomingEventsDto"
}
}
}
},
"400": {
"description": "Invalid request",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"401": {
"description": "Authentication required",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"404": {
"description": "Resource not found",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"503": {
"description": "Upstream service unavailable",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
}
},
"security": [
{
"bearer": []
}
],
"tags": [
"brokerage-accounts"
]
}
},
"/api/v1/brokerage-accounts/{accountId}/events": {
"get": {
"operationId": "UpcomingEventsController_get",
@@ -991,6 +1276,177 @@
]
}
},
"/api/v1/brokerage-accounts/all/income-summary": {
"get": {
"operationId": "IncomeAnalyticsController_allSummary",
"parameters": [],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IncomeSummaryDto"
}
}
}
},
"400": {
"description": "Invalid request",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"401": {
"description": "Authentication required",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"404": {
"description": "Resource not found",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"503": {
"description": "Upstream service unavailable",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
}
},
"security": [
{
"bearer": []
}
],
"tags": [
"brokerage-accounts"
]
}
},
"/api/v1/brokerage-accounts/all/income-analytics": {
"get": {
"operationId": "IncomeAnalyticsController_allAnalytics",
"parameters": [
{
"name": "from",
"required": false,
"in": "query",
"schema": {
"format": "date",
"type": "string"
}
},
{
"name": "to",
"required": false,
"in": "query",
"schema": {
"format": "date",
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IncomeAnalyticsDto"
}
}
}
},
"400": {
"description": "Invalid request",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"401": {
"description": "Authentication required",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"404": {
"description": "Resource not found",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
},
"503": {
"description": "Upstream service unavailable",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetailsDto"
}
}
}
}
},
"security": [
{
"bearer": []
}
],
"tags": [
"brokerage-accounts"
]
}
},
"/api/v1/brokerage-accounts/{accountId}/income-summary": {
"get": {
"operationId": "IncomeAnalyticsController_summary",
@@ -1367,9 +1823,27 @@
"portfolioSummary"
]
},
"AccountReferenceDto": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
]
},
"BrokerageOperationDto": {
"type": "object",
"properties": {
"account": {
"$ref": "#/components/schemas/AccountReferenceDto"
},
"id": {
"type": "string"
},
@@ -1508,6 +1982,9 @@
"PortfolioPositionDto": {
"type": "object",
"properties": {
"account": {
"$ref": "#/components/schemas/AccountReferenceDto"
},
"figi": {
"type": "string",
"nullable": true
@@ -1625,6 +2102,9 @@
"UpcomingEventDto": {
"type": "object",
"properties": {
"account": {
"$ref": "#/components/schemas/AccountReferenceDto"
},
"type": {
"type": "string",
"enum": [
@@ -1900,6 +2380,9 @@
"IncomeAnalyticsEntryDto": {
"type": "object",
"properties": {
"account": {
"$ref": "#/components/schemas/AccountReferenceDto"
},
"id": {
"type": "string"
},