Files
specs/openspec/changes/archive/2026-11-02-account-top-positions/analysis/system-analysis.md
T
codex-bot 3821d9ed58
Specs security / security (push) Successful in 7s
Specs verify / verify (push) Successful in 14s
refactor: group canonical specs by domain and archive account-top-positions (#74)
2026-11-02 21:50:49 +03:00

40 KiB
Raw Blame History

Системный анализ

Контекст и статус

Цель — передать в Portfolio сектор инструмента и бренд его актива, чтобы frontend строил четыре разреза концентрации одного счёта без конвертации валют. Основание: specs/openspec/changes/account-top-positions/proposal.md:11-18,60-63; Issue main#48. Рабочая ветка specs — feature/48-account-top-positions.

Документ приведён в соответствие с решениями владельца 3081 и 3082. G2 по комплекту Specs, system-analysis, data-mapping и failure-model approved (process-record.md, Gate Log, последняя строка G2). Технологии, внутренние компоненты и форма хранения здесь не проектируются.

Обозначения. PC — specs/openspec/changes/account-top-positions/specs/portfolio/portfolio-concentration/spec.md; PVΔ — specs/openspec/changes/account-top-positions/specs/portfolio/portfolio-view/spec.md. Requirement указываются по названию заголовка: PC «Название», PVΔ «Название». Пути с backend/, frontend/, docs/, specs/ отсчитываются от workspace WealthLedger.

Покрытие требований (Requirement Coverage)

Покрыты все 32 Requirement: 28 в PC и 4 в PVΔ (2 MODIFIED, 2 ADDED). Заголовки в первом столбце приведены дословно (проверено сопоставлением с файлами). Требования «Последнее известное значение сектора и эмитента» и «Ошибки получения сектора и эмитента» из Specs удалены: их содержание вошло в PVΔ «Свежесть и fallback полного Portfolio Snapshot» и PVΔ «Результат получения сектора и эмитента».

Requirement Flow / контракт Модуль
PC Вкладка «Концентрация» страницы счёта F3: только страница одного счёта; /all вкладки не получает; вкладка по умолчанию прежняя Hub
PC Вкладка в состояниях страницы F2 → F3: нет вкладки при загрузке, ошибке, недоступности и пустом Portfolio; есть при ≥1 позиции или денежном остатке; только остатки → пустой разрез Hub; failure-model F12
PC Переключение разрезов F3: четыре разреза одного ответа, один видимый; T-Bank не вызывается Hub
PC Начальное состояние вкладки F3: разрез и валюта сохраняются, пока User на странице; сброс при новом заходе, переключении счёта и перезагрузке; на сервер не передаётся Hub
PC Состав разрезов F3: Секторы — STOCK/BOND/FUND, Эмитенты — STOCK/BOND; issuer у FUND приходит в API, разрез его отбрасывает data-mapping: «Применимость по типу», I3
PC Названия элементов F2 → F3: displayName, подпись sector, issuer.name; группировка эмитента по issuer.id data-mapping
PC Название эмитента при разных названиях бренда F3: имя — issuer.name позиции с наибольшим currentValue в выбранной валюте; при равных — меньшее по алфавитному порядку PC «Порядок элементов с равной суммой»; выбор на клиенте data-mapping: I8
PC Позиции, учитываемые в разрезе F3: только currentValue > 0 в выбранной валюте data-mapping: I4
PC Сноска о не учтённых позициях F3: null в любой валюте и отрицательные в выбранной data-mapping: I12
PC Одна валюта за раз F3: одна валюта на все разрезы, без конвертации data-mapping: I11
PC Доступные валюты вкладки F3: ненулевые оценки STOCK/BOND/FUND, ISO-порядок; при одной валюте или без валют выбора нет data-mapping: I11
PC Независимый выбор валюты вкладки F3: локальный выбор; пропавшая валюта → первая в списке Hub
PC Топ-5 и строка «Прочее» F3: до 6 элементов — все строки; от 7 — пять и «Прочее» с числом остальных data-mapping: I7
PC Раскрытие строки «Прочее» F3: остаток уже входит в ответ; нового запроса нет Hub
PC Порядок элементов с равной суммой F3: название без регистра: цифры, латиница, кириллица, затем порядок в Portfolio data-mapping: I8
PC Расчёт долей F3: знаменатель — сумма учитываемых позиций разреза data-mapping: I5, I9
PC Показ долей F3: формат карточек позиций, «< 0,1 %» data-mapping
PC Суммарная доля топ-5 F3: метрика только при ≥6 элементах data-mapping: I7
PC Группы «Сектор не указан» и «Эмитент не указан» F2 → F3: null образует равноправный элемент data-mapping: I6; failure-model F06
PC Подписи секторов F3: известный код → подпись, иначе код как получен data-mapping
PC Русские подписи известных секторов F3: таблица подписей data-mapping
PC Диаграмма распределения разреза F3: сегменты совпадают со списком; ≤6 элементов — по сегменту, ≥7 — пять и «Прочее» data-mapping: I10
PC Центр диаграммы F3: сумма разреза и подпись «Топ-5 · N %» при показе метрики data-mapping: I10
PC Строки без переходов F3: строки без переходов; в «Эмитентах» без логотипов; logoName остаётся в API Hub
PC Доступность диаграммы без цвета F3: текстовый эквивалент и сопоставление сегмента со строкой Hub; ux-design.md
PC Пустое состояние разреза F3: нет учтённых элементов — пустое состояние без доли и диаграммы data-mapping: I14
PC Предупреждение о неполных данных F2 → F3: meta обозначает неполноту — «Данные неполные» только на вкладке над разрезом; страница его не дублирует; позиции без оценки и отсутствие sector/issuer предупреждения не вызывают failure-model F14; заметка для design ниже
PC Состояния Portfolio на вкладке «Концентрация» F2 → F3: состояния как на «Позициях»; отсутствие sector/issuer не скрывает вкладку и не меняет успешность и свежесть failure-model F12, F14
PVΔ Нормализованный состав Portfolio (MODIFIED) F1 → F2: аддитивные sector, issuer; значения только у STOCK/BOND/FUND, включая issuer фонда; обрезка пробелов; остальные типы null; UID → FIGI; исключение — отказ token Hub: контракт; data-mapping; failure-model
PVΔ Свежесть и fallback полного Portfolio Snapshot (MODIFIED) F1, F2: два исключения — сектор и бренд хранятся как последнее известное значение (GET читает хранимое, T-Bank не вызывает); отказ token при получении обрабатывается как при обходе Portfolio Hub; failure-model F08, F11
PVΔ Обновление сектора и эмитента (ADDED) F1: обновление при первом обходе, начавшемся не ранее чем через 24 ч после последнего успешного получения; пока значение не получено — при каждом обходе failure-model: «Таймауты и повторы»
PVΔ Результат получения сектора и эмитента (ADDED) F1: четыре исхода определяют поле и отсчёт 24 ч; неуспешное получение не мешает обновлению Portfolio data-mapping; failure-model F02–F05

Системный контекст и границы

Участники: T-Bank Invest API → backend часовой синхронизации → сохранённый Portfolio Snapshot → backend HTTP API → авторизованный frontend. T-Bank владеет исходной классификацией и брендами, WealthLedger — нормализацией и представлением. Подтверждено docs/architecture/context.md:9-38, docs/architecture/containers.md:9-33, docs/integrations/tbank.md:3-21.

Сектор и бренд получает сервер в часовом обходе, не браузер и не открытие вкладки. Обычный GET и его повтор не обращаются к T-Bank (specs/openspec/specs/tbank/tbank-data-sync/spec.md:9-14; PVΔ «Свежесть и fallback полного Portfolio Snapshot», сценарий «Сектор и бренд читаются из хранимого значения»). MOEX, НКР и CDN логотипов не являются источниками sector/issuer.

Владелец расчёта разрезов — frontend над полным ответом Portfolio. Подтверждено: Change Profile — «вкладка считается по уже загруженному Portfolio» (specs/openspec/changes/account-top-positions/process-record.md:16), impact в proposal.md:60. Specs закрепляют клиентский расчёт: имя эмитента выбирается по позиции с наибольшим currentValue в выбранной валюте (PC «Название эмитента при разных названиях бренда»), а валюта и учитываемость зависят от выбора пользователя (PC «Позиции, учитываемые в разрезе», PC «Одна валюта за раз»). Серверный агрегат такой выбор не воспроизвёл бы без параметров запроса, которых контракт не вводит. Backend-агрегаты, endpoint топ-5 и обращение браузера к каталогу не требуются.

As-Is / To-Be

As-Is: фактический путь

  1. Часовой планировщик независимо от экрана обновляет membership и Portfolio счетов (backend/src/modules/investments/tbank-sync/tbank-hourly.scheduler.ts:176-209). Интервал и отсутствие перекрытий — specs/openspec/specs/tbank/hourly-investment-sync/spec.md:8-21.
  2. Для счёта параллельно запрашиваются GetPortfolio и GetPositions; после нормализации полный Snapshot публикуется, и только затем запрашивается обновление metadata позиций (backend/src/modules/investments/portfolio/application/portfolio.service.ts:263-315). Регистрация metadata-запроса не ждёт внешнего lookup (backend/src/integrations/tbank/instrument-metadata.service.ts:63-105).
  3. Snapshot хранится одним JSON payload; публикация транзакционна и ограждена connection revision, attempt и доступностью счёта (backend/prisma/schema.prisma:60-70; backend/src/modules/investments/portfolio/infrastructure/portfolio.repository.ts:116-147).
  4. Mapper считает currentValue из quantity × currentPrice и заполняет logoName из metadata (backend/src/modules/investments/portfolio/infrastructure/tbank-portfolio.mapper.ts:22-31,63-99). Это прецедент необязательного обогащения.
  5. GET читает сохранённый Snapshot и дополняет позиции сохранённой metadata без обращения к T-Bank (backend/src/modules/investments/portfolio/application/portfolio.service.ts:55-105,122-164); время финансового Snapshot при этом не меняется.
  6. Общая metadata — GetInstrumentBy по UID, затем по FIGI. Instrument содержит asset_uid, но не sector; его brand — BrandData (логотип и цвета), а не Brand с uid/name (backend/src/integrations/tbank/proto/contracts/instruments.proto:939-998; backend/src/integrations/tbank/proto/contracts/common.proto:120-124). Локальный TbankInstrument не объявляет assetUid и sector (backend/src/integrations/tbank/tbank.client.ts:91-99).
  7. Каталог акций и облигаций получает ShareBy/BondBy и переносит sector/assetUid; это отдельный источник, а не готовое обогащение Portfolio (backend/src/modules/investments/instruments/application/catalog-enrichment.service.ts:335-351; backend/src/modules/investments/instruments/application/public-instrument.ts:6-23; backend/src/integrations/tbank/tbank-market.types.ts:8-23).
  8. Расхождения AS-IS с PVΔ «Обновление сектора и эмитента» и PVΔ «Результат получения сектора и эмитента», которые должна закрыть реализация. (а) Общая metadata считается свежей по факту завершённого lookup, без возраста (backend/src/integrations/tbank/instrument-metadata.repository.ts:314-323); норма требует срок от последнего успешного получения и четыре исхода. (б) Клиент превращает NOT_FOUND в NotFoundException только для shareBy и getInstrumentBy, остальные методы дают Unavailable (backend/src/integrations/tbank/tbank.client.ts:577-583); норма относит «не найдено» к исходу «значения нет». Это требования к реализации, а не выбор между вариантами.
  9. Frontend берёт Portfolio из generated paths существующего GET (frontend/src/entities/portfolio/api/usePortfolio.ts:1-28). Текущие DTO и опубликованный snapshot новых полей не содержат (backend/src/modules/investments/portfolio/presentation/portfolio.dto.ts:7-55; frontend/src/shared/api/spec/openapi.json:6426-6519; frontend/src/shared/api/generated/schema.d.ts:1059-1085).
  10. Общий справочник инструментов в AS-IS задокументирован как онлайн, без долговременного хранения (docs/architecture/cross-cutting/data-freshness.md:9-12, ADR 019); PVΔ «Свежесть и fallback полного Portfolio Snapshot» вводит исключение для сектора и бренда.

To-Be: системные обязательства

  • Каждая позиция содержит sector и issuer; значения только у STOCK, BOND, FUND, у остальных типов null (PVΔ «Нормализованный состав Portfolio»).
  • Получение — в часовом обходе: при первом обходе, начавшемся не ранее чем через 24 часа после последнего успешного получения; пока значение не получено — при каждом обходе (PVΔ «Обновление сектора и эмитента»). Поле и отсчёт 24 часов после каждого получения определяет таблица исходов (PVΔ «Результат получения сектора и эмитента»); здесь она не пересказывается.
  • Сектор и бренд хранятся как последнее известное значение; GET читает хранимое (PVΔ «Свежесть и fallback полного Portfolio Snapshot»).
  • Отказ token при получении обрабатывается как отказ token в обходе Portfolio (PVΔ «Свежесть и fallback полного Portfolio Snapshot»); иные ошибки на обновление Portfolio не влияют (PVΔ «Результат получения сектора и эмитента»).
  • Frontend получает полный список позиций и сам вычисляет разрезы; Portfolio не сортируется и не объединяется (PVΔ «Нормализованный состав Portfolio»).

Способ получения (типизированный запрос или ранее сохранённые данные), форма хранения времени успешного получения и порядок вызовов относительно публикации — design; нормы Specs от них не зависят, кроме того, что после отказа token подключение недействительно.

Анализ влияния

Область Изменение / обязательство Не меняется
T-Bank → backend Типизированный sector и asset → brand только для STOCK/BOND/FUND; источники-кандидаты в data-mapping GetPortfolio/GetPositions, права подключения
Часовой обход Дополнительные чтения по инструментам и активам по сроку PVΔ «Обновление сектора и эмитента» Интервал 60 минут, запрет перекрытия
Сохранённый Snapshot и состояние получения Новые nullable поля позиций; хранение последнего известного значения и времени последнего успешного получения (PVΔ «Свежесть и fallback полного Portfolio Snapshot», PVΔ «Обновление сектора и эмитента») Количество, деньги, порядок, fetchedAt финансового наблюдения
Backend → frontend Аддитивные поля PortfolioPositionDto в /api/v1 Envelope, параметры, прежние статусы
Подключение Отказ token при получении сектора/бренда делает подключение недействительным как при обходе Portfolio Модель доступа
Frontend Четыре вычисляемых разреза над полным Portfolio; единственное сообщение о неполноте на вкладке (PC «Предупреждение о неполных данных») Сводка, остальные вкладки
Режим «Все счета» Общая DTO получает те же поля; вкладки и расчёта нет Агрегирование счетов
API artifacts backend OpenAPI → переданный snapshot → generated types Автономность репозиториев
Docs Темы Portfolio и T-Bank, глоссарий, исключение из онлайн-справочника в docs/architecture/cross-cutting/data-freshness.md и ADR 019 — по docs-impact В этой задаче docs не редактируются

Общая DTO для двух GET подтверждена backend/src/modules/investments/portfolio/presentation/portfolio.controller.ts:19-31. Подробности — data-mapping и failure-model.

Заметка для design: дублирование предупреждения о неполноте

PC «Предупреждение о неполных данных» требует одно сообщение о неполноте: «Данные неполные» на вкладке, страница его не дублирует. В AS-IS страница уже показывает собственный Alert при неполноте:

  • frontend/src/pages/account/ui/AccountPage/components/AccountPageLoaded.view.tsx:77-79 — <Alert role="status">{t("investment.partial")}</Alert> при props.partial; признак вычисляется как portfolio.meta?.completeness === "incomplete" (frontend/src/pages/account/ui/AccountPage/AccountPage.vm.ts:124,130);
  • Alert выводится над <Tabs> (AccountPageLoaded.view.tsx:108-112, неконтролируемый defaultValue="positions"), поэтому виден при любой вкладке, включая «Концентрация»;
  • текст Alert — «Период загружен не полностью» (frontend/src/shared/i18n/locales/ru.ts:423), не «Данные неполные».

Следствие: при открытой вкладке «Концентрация» и неполном Portfolio страничный Alert не должен показываться (иначе на странице два сообщения). Содержание других вкладок не меняется (PC «Вкладка «Концентрация» страницы счёта»). Состояние активной вкладки сейчас внутри Tabs и странице недоступно; как это обеспечить — design.

Системы и ответственность

  • T-Bank: инструмент, его сектор, связь с активом, идентичность и название бренда; допустимость token.
  • Backend sync: полный финансовый результат; получение sector/brand по PVΔ «Обновление сектора и эмитента» и PVΔ «Результат получения сектора и эмитента»; хранение последнего известного значения; обработка отказа token.
  • Backend HTTP: проверка доступа, выдача Portfolio с новым shape, явные null для старых Snapshot.
  • Frontend: вычисление разрезов, единый набор сумм для списка и диаграммы, выбор имени эмитента по PC «Название эмитента при разных названиях бренда», единственное предупреждение о неполноте.
  • Change Owner: принимает остаточные факты данных (Q-D1, Q-D2, Q-F3) как результат проверки при реализации; решений по ним не требуется.

Владение данными

Данные Источник истины Пишут Читают
quantity, price, cash T-Bank финансовые ответы Backend публикует Snapshot GET, frontend
sector (STOCK/BOND/FUND) sector Share/Bond/Etf в T-Bank, обрезанный по краям Backend; хранимое последнее известное значение Frontend: группирует по точному коду
issuer (STOCK/BOND/FUND) AssetFull.brand.uid/name в T-Bank, обрезанные по краям Backend; пара целиком либо null Frontend: группирует по id, имя по PC «Название эмитента при разных названиях бренда»
Время последнего успешного получения sector/brand Backend Backend Backend: условие PVΔ «Обновление сектора и эмитента»
lastSuccessfulAt, isStale, meta Подтверждённое финансовое наблюдение и состояние ресурса Backend sync / local read Frontend
Разрезы, суммы, доли, топ-5, имя эмитента Производные от одного ответа Portfolio Frontend, только вычисляет Список и диаграмма
Русские подписи секторов Таблица PC «Русские подписи известных секторов» Frontend Пользователь

Потоки взаимодействий

F1 — часовой обмен. Backend проверяет подключение и доступные счета → GetPortfolio + GetPositions → полный финансовый Snapshot. Для позиций STOCK/BOND/FUND, у которых значение не получено либо наступил срок PVΔ «Обновление сектора и эмитента», запрашиваются сектор и бренд актива; результат применяется по PVΔ «Результат получения сектора и эмитента»; отказ token делает подключение недействительным (PVΔ «Свежесть и fallback полного Portfolio Snapshot»). Прочие сбои получения на финансовый результат не влияют.

F2 — локальная выдача. Авторизованный GET проверяет membership и connection → читает Snapshot и хранимые значения → {data, meta}. Для старого JSON без новых ключей возвращаются явные null; GET не обращается к T-Bank (PVΔ «Свежесть и fallback полного Portfolio Snapshot»). data: null — отсутствие полного снимка, а не пустая концентрация (docs/domains/portfolio/flows/portfolio-loading.md:10-21).

F3 — клиентская проекция. Из полного Portfolio frontend определяет список валют, выбирает разрез, отбирает позиции, агрегирует, ранжирует, выбирает имя эмитента и рассчитывает доли. Переключение разрезов и раскрытие «Прочее» новых запросов не требуют.

Диаграммы в отдельных файлах не создаются: работа ограничена тремя Markdown-файлами; три потока выше передают границы без внутреннего устройства.

Контракты

Контракт Producer → Consumer Версия / artifact Совместимость Опубликованный источник
GET /api/v1/brokerage-accounts/{accountId}/portfolio, data.positions[] Backend → frontend API v1; PortfolioPositionDto + delta ниже additive frontend/src/shared/api/spec/openapi.json:6426-6519 — предоставленная версия
GET /api/v1/brokerage-accounts/all/portfolio, общий shape позиции Backend → существующие потребители Тот же DTO; вкладка не применяется additive backend/src/modules/investments/portfolio/presentation/portfolio.controller.ts:19-31
Instrument / Asset lookup T-Bank → backend tinkoff.public.invest.api.contract.v1, локальный instruments.proto Внешний контракт не меняется; расширяется используемая часть Источники-кандидаты в data-mapping

Семантическая delta PortfolioPositionDto

Поле Присутствие Тип / ограничение Значение
sector Обязательно в каждой позиции string или null Код T-Bank без перекодирования, с обрезанными краями; только у STOCK/BOND/FUND; иначе null
issuer Обязательно в каждой позиции object или null {id, name} только у STOCK/BOND/FUND, включая FUND; иначе null
issuer.id Внутри непустого issuer Непустая строка после обрезки: brand.uid Не asset_uid и не UID инструмента
issuer.name Внутри непустого issuer Непустая строка после обрезки: brand.name Не brand.company, не название актива

Пример позиции с данными: {"sector":"financial","issuer":{"id":"brand-uid-example","name":"Сбер"}}; идентификатор условный. Без данных: {"sector":null,"issuer":null}. Поля независимы. Значение из одних пробелов считается отсутствующим (PVΔ «Нормализованный состав Portfolio»).

Изменение добавляет только response-поля: запросы, Money, маршруты, статусы и версия API остаются. Текущий snapshot — OpenAPI 3.0.0 (frontend/src/shared/api/spec/openapi.json:2); синтаксис 3.1 молча не вводится. Таблица — семантическая delta, не полный машиночитаемый target OpenAPI. Протокол требует target-контракт в analysis/contracts/ до реализации (specs/openspec/schemas/wealth-ledger-sdd-lab/schema.yaml:383-393); он не создан, так как работа ограничена тремя файлами. Для G2 нужен отдельный разрешённый шаг публикации и проверки target-контракта. После реализации backend-generated OpenAPI должен семантически совпасть с ним до G4.

Публикация и получение API artifact

Backend генерирует и проверяет OpenAPI; потребителю явно передаётся новый artifact. Frontend обновляет versioned src/shared/api/spec/openapi.json, локально генерирует src/shared/api/generated/schema.d.ts и проверяет соответствие. Generated types вручную не правятся; frontend не читает backend checkout, runtime не требует Swagger. Основания: specs/openspec/specs/backend-platform/api-contract-generation/spec.md:10-35; docs/architecture/http-api.md:5-22; frontend/.ai/conventions/data.md:15-34.

Семантика ошибок

Новых бизнес-ошибок HTTP из-за sector/issuer нет, кроме отказа token. Результат получения определяет PVΔ «Результат получения сектора и эмитента»; 200 с группами «не указан» не означает сбой Snapshot (PVΔ «Нормализованный состав Portfolio»; PC «Группы «Сектор не указан» и «Эмитент не указан»», PC «Состояния Portfolio на вкладке «Концентрация»»).

Отказ token при получении сектора или бренда обрабатывается как отказ token в обходе Portfolio: 400 INVALID_TBANK_TOKEN без fallback Snapshot (PVΔ «Свежесть и fallback полного Portfolio Snapshot», сценарий «Отказ token при получении бренда»; specs/openspec/specs/portfolio/portfolio-view/spec.md:113-115). Это соответствует текущему клиенту, сводящему PERMISSION_DENIED и UNAUTHENTICATED к InvalidToken (backend/src/integrations/tbank/tbank.client.ts:571-575).

Прочие ошибки доступа: нет подключения — 409 TBANK_NOT_CONNECTED, недоступный счёт — 404 (docs/domains/portfolio/flows/portfolio-loading.md:24-35).

Совместимость и миграция

  1. Старый потребитель → новый backend: аддитивные JSON-поля не меняют существующий shape; известный потребитель — generated paths (frontend/src/entities/portfolio/api/usePortfolio.ts:7-16).
  2. Новый backend → старый JSON Snapshot: отсутствующие ключи выдаются как null; Snapshot не пересоздаётся, lastSuccessfulAt не меняется. Значения появляются после обхода, получившего их по PVΔ «Обновление сектора и эмитента». Текущий spread payload этого сам не делает (backend/src/modules/investments/portfolio/application/portfolio.service.ts:88-95); механизм — design.
  3. Новый frontend → старый backend или Client Cached Snapshot: отсутствие ключей трактуется как неизвестные значения. Использование новых полей возможно после получения provider-first artifact.
  4. Свежесть: в обходах раньше срока значение не меняется (PVΔ «Обновление сектора и эмитента»); sector/brand не влияют на isStale (PVΔ «Нормализованный состав Portfolio»).
  5. /all: общий DTO проверяется, расчёта концентрации нет. Ломающих изменений для существующих потребителей нет.

Подробные модули

  • data-mapping.md: источники полей, типы позиций, нормализация, инварианты, риски классификации.
  • failure-model.md: сценарии отказов со ссылками на нормы, лимиты, повторы, восстановление.
  • Отдельные nfr и observability не выбраны: нагрузка и частичное обогащение рассматриваются в failure-model без выдуманных SLA (process-record.md:16-17).
  • ux-design.md — представление вкладки; в этом комплекте не дублируется.

Открытые вопросы

Закрыто решениями владельца

Вопрос Решение Где в Specs
issuer у фондов Заполняется у STOCK/BOND/FUND; разрез «Эмитенты» фонды отбрасывает (3081) PVΔ «Нормализованный состав Portfolio»; PC «Состав разрезов»
Имя при разных названиях одного issuer.id Название позиции с наибольшим currentValue; при равных — по алфавиту (3081, 3082) PC «Название эмитента при разных названиях бренда»
Пробелы Края обрезаются; значение из одних пробелов отсутствует (3081) PVΔ «Нормализованный состав Portfolio»
Срок и поведение при ошибке Раз в сутки от последнего успешного получения; исходы по таблице (3081, 3082) PVΔ «Обновление сектора и эмитента», PVΔ «Результат получения сектора и эмитента»
Отказ token Как отказ token в обходе Portfolio; прочие ошибки не мешают обновлению Portfolio (3081, 3082) PVΔ «Свежесть и fallback полного Portfolio Snapshot», PVΔ «Результат получения сектора и эмитента»
Хранение сектора и бренда вопреки «Свежесть и fallback» Исключение для сектора и бренда (3082) PVΔ «Свежесть и fallback полного Portfolio Snapshot»
«Не найдено» от T-Bank Как «значения нет» (3082) PVΔ «Результат получения сектора и эмитента»
Предупреждение о неполноте Только на вкладке (3082) PC «Предупреждение о неполных данных»

Остаётся неизвестным

Это факты данных T-Bank; они проверяются при реализации и решения владельца не требуют.

ID Что неизвестно Чем проверяется
Q-D1 Реальное покрытие STOCK/BOND/FUND брендом актива; совпадает ли brand.uid у акций, префов и облигаций одной компании См. data-mapping: однократный read-only прогон на подключении владельца с агрегированной сводкой
Q-D2 Какие значения sector фактически отдаются для фондов и государственных облигаций См. data-mapping: тот же прогон, список различных значений со счётчиками
Q-F3 Фактические квоты методов T-Bank, число различных инструментов и активов, вид ответа «не найдено» См. failure-model: официальные лимиты Invest API, измерение числа вызовов в обходе, запрос с несуществующим asset_uid