Files
codex-bot b6a9ff2d10
Specs security / security (push) Successful in 8s
Specs verify / verify (push) Successful in 11s
spec: require RUB-only behavior (WealthLedger/main#55) (#86)
2026-11-11 09:20:25 +03:00

192 lines
8.3 KiB
YAML

openapi: 3.1.0
info:
title: WealthLedger investment performance (target contract, WealthLedger/main#54)
version: 1.0.0
description: |
Целевой контракт новых маршрутов. После реализации исполняемым источником
становится backend-generated OpenAPI, который MUST быть семантически
совместим с этим файлом. Общие схемы `MoneyDto`, `ProblemDetailsDto` и
`InvestmentDependencyDto` остаются в опубликованном OpenAPI и здесь только
упоминаются.
paths:
/api/v1/brokerage-accounts/{accountId}/performance:
get:
operationId: getBrokerageAccountPerformance
summary: Результат инвестирования счёта за всё время
parameters:
- name: accountId
in: path
required: true
schema: { type: string, minLength: 1 }
responses:
'200': { $ref: '#/components/responses/Performance' }
'401': { $ref: '#/components/responses/Problem' }
'404': { $ref: '#/components/responses/Problem' }
'503': { $ref: '#/components/responses/Problem' }
/api/v1/brokerage-accounts/all/performance:
get:
operationId: getAllBrokerageAccountsPerformance
summary: Результат инвестирования режима «Все счета»
responses:
'200': { $ref: '#/components/responses/Performance' }
'401': { $ref: '#/components/responses/Problem' }
'503': { $ref: '#/components/responses/Problem' }
components:
responses:
Problem:
description: Ошибка доступа, подключения или технический сбой (существующий Problem Details; коды из PROBLEM_CODES)
content:
application/problem+json:
schema: { $ref: 'openapi.json#/components/schemas/ProblemDetailsDto' }
Performance:
description: Результат либо явная недоступность. Недоступность расчёта — не ошибка HTTP.
content:
application/json:
schema: { $ref: '#/components/schemas/PerformanceResource' }
schemas:
Decimal:
type: string
pattern: '^-?(0|[1-9][0-9]*)(\.[0-9]*[1-9])?$'
description: Точное десятичное значение без экспоненты и незначащих нулей
Rate:
allOf: [{ $ref: '#/components/schemas/Decimal' }]
description: Доля, не проценты. 0.151 = 15,1 %. Округление до 6 знаков, half away from zero.
Money:
$ref: 'openapi.json#/components/schemas/MoneyDto'
UnavailableReason:
type: string
enum:
- HISTORY_START_UNKNOWN
- OPERATIONS_HISTORY_INCOMPLETE
- UNVALUED_SECURITIES_TRANSFER
- UNCONFIRMED_TRANSFER
- ACCOUNT_VALUATION_DATES_DIFFER
- PORTFOLIO_VALUATION_INCOMPLETE
- NO_SOLUTION
- AMBIGUOUS_RETURN
- INDEX_HISTORY_UNAVAILABLE
description: |
Новые значения MAY добавляться; клиент MUST показывать неизвестное
значение как общую недоступность, а не как ошибку.
ReturnValue:
type: object
required: [value, basis, unavailableReason]
properties:
value:
oneOf: [{ $ref: '#/components/schemas/Rate' }, { type: 'null' }]
basis:
type: string
enum: [annual, period]
description: annual при period.days >= 365, иначе period (доля за весь период)
unavailableReason:
oneOf: [{ $ref: '#/components/schemas/UnavailableReason' }, { type: 'null' }]
IndexResult:
type: object
required: [code, value, return, asOf, unavailableReason]
properties:
code:
type: string
enum: [MCFTRR, IMOEX]
value:
oneOf: [{ $ref: '#/components/schemas/Money' }, { type: 'null' }]
description: Стоимость тех же потоков в индексе на конец периода (RUB)
return: { $ref: '#/components/schemas/ReturnValue' }
asOf:
oneOf: [{ type: string, format: date }, { type: 'null' }]
description: Дата последнего использованного закрытия индекса (Europe/Moscow)
unavailableReason:
oneOf: [{ $ref: '#/components/schemas/UnavailableReason' }, { type: 'null' }]
Outperformance:
type: object
required: [percentagePoints, money]
properties:
percentagePoints:
$ref: '#/components/schemas/Rate'
description: Разница долей return пользователя и benchmark (того же basis)
money: { $ref: '#/components/schemas/Money' }
SeriesPoint:
type: object
required: [date, netInvested, benchmarkValue, referenceValue]
properties:
date: { type: string, format: date }
netInvested: { $ref: '#/components/schemas/Decimal' }
benchmarkValue: { $ref: '#/components/schemas/Decimal' }
referenceValue:
oneOf: [{ $ref: '#/components/schemas/Decimal' }, { type: 'null' }]
description: Значения RUB на торговый день MCFTRR; валюта точки всегда RUB
ExcludedAccount:
type: object
required: [accountId, name, reason]
properties:
accountId: { type: string }
name: { type: string }
reason: { $ref: '#/components/schemas/UnavailableReason' }
Performance:
type: object
required:
- accountId
- period
- netInvested
- currentValue
- profit
- return
- benchmark
- reference
- outperformance
- series
- completeness
- excludedAccounts
- calculatedAt
properties:
accountId: { type: string, description: 'id счёта или all' }
period:
type: object
required: [from, to, days]
properties:
from: { type: string, format: date }
to: { type: string, format: date, description: 'дата последней полной оценки Portfolio' }
days: { type: integer, minimum: 0 }
netInvested: { $ref: '#/components/schemas/Money' }
currentValue: { $ref: '#/components/schemas/Money' }
profit: { $ref: '#/components/schemas/Money' }
return: { $ref: '#/components/schemas/ReturnValue' }
benchmark:
allOf: [{ $ref: '#/components/schemas/IndexResult' }]
description: code = MCFTRR
reference:
allOf: [{ $ref: '#/components/schemas/IndexResult' }]
description: code = IMOEX; только справка
outperformance:
oneOf: [{ $ref: '#/components/schemas/Outperformance' }, { type: 'null' }]
description: null, если недоступен return пользователя или benchmark
series:
type: array
items: { $ref: '#/components/schemas/SeriesPoint' }
description: Пусто, если benchmark недоступен
completeness:
type: string
enum: [complete, incomplete]
excludedAccounts:
type: array
items: { $ref: '#/components/schemas/ExcludedAccount' }
description: Только для all; incomplete <=> непустой массив
calculatedAt: { type: string, format: date-time }
PerformanceResource:
type: object
required: [data, meta]
properties:
data:
oneOf: [{ $ref: '#/components/schemas/Performance' }, { type: 'null' }]
description: null, если результат недоступен целиком
meta:
type: object
required: [dependencies, unavailable]
properties:
dependencies:
type: array
items: { $ref: 'openapi.json#/components/schemas/InvestmentDependencyDto' }
unavailable:
type: array
description: Непусто <=> data = null; причины по каждому счёту
items: { $ref: '#/components/schemas/ExcludedAccount' }