Files
specs/openspec/changes/persist-tbank-data/tasks.md
T
ksv741 2f5814abdd
Conventional commits / commits (pull_request) Successful in 12s
Specs security / security (pull_request) Successful in 7s
Specs verify / verify (pull_request) Successful in 11s
Specs security / security (push) Successful in 7s
Specs verify / verify (push) Successful in 9s
spec: complete persist-tbank-data implementation
Record the approved proposal, delta specifications, design and 27 verified
implementation tasks. Keep the change active; archiving and main-spec synchronization
are deferred.
2026-09-26 21:29:24 +03:00

120 KiB
Raw Blame History

Выполнены implementation-owned задачи 1.1–7.5 (27/27). Archive не выполнялся. Текущее evidence — в checkpoint ниже. Входы: Design revision 1, включая полностью inline UI/UX package, и delta specs. Перед работой в каждом repo прочитать его AGENTS и применимый routing; перед Node — местный nvm use --silent. Ни одна задача не требует изменения root или чтения соседнего checkout в CI.

1. Основание и сохраняемая модель

  • 1.1 [backend] Применить Solution Assessment: использовать текущие Prisma/SQLite/TbankClient, зафиксировать baseline HTTP/RPC и подготовить изолированные исходные данные профиля Design без новой очереди или scheduler.

    • Covers: N/A — техническое основание storage/concurrency решения и сопоставимых измерений из Design; самостоятельного пользовательского поведения не добавляет.
    • Verification: сохранить версии runtime, hardware, объём/распределение fixture и числа RPC/latency исходного navigation trace; проверить, что тесты не используют рабочую SQLite и реальные token; проверить существующие owners и отсутствие добавленной инфраструктуры.
  • 1.2 [backend] После 1.1 добавить additive Prisma migration для connection revision, membership, private datasets и последних полных прогнозов, общих инструментальных источников, coverage/work/staging с описанными unique keys и индексами.

    • Covers: tbank-data-sync — Все экраны читают сохранённые данные без ожидания T-Bank; tbank-data-sync — Общие данные инструментов отделены от личных.
    • Verification: npx prisma validate, generate/typecheck и migration на пустой и заполненной временной SQLite; автоматическая проверка integrity/FK, сохранности User/Session/TbankConnection/manual cards и исходных зашифрованных token; decimal round-trip без float; подтверждение ключей/индексов и невозможности дублирующей операции.
  • 1.3 [backend] После 1.2 реализовать локальный membership owner и атомарную границу PUT/DELETE подключения, включая использование списка успешной проверки token и publication fence по revision/attempt.

    • Covers: tbank-data-sync — Локальная проверка доступа сохраняет границу подключения; brokerage-accounts — Состояния недоступности списка счетов.
    • Verification: реальные SQLite/HTTP проверки двух пользователей, unknown/empty/stale membership, closed/unsupported/removed account, invalid token, failed replacement и late completion после replace/delete; на warm access path spy фиксирует 0 GetAccounts до HTTP-ответа; данные/coverage/errors старой revision не публикуются.

2. Интервалы и выполнение запрошенной работы

  • 2.1 [backend] После 1.2–1.3 реализовать операции staging → atomic reconciliation → coverage/dataRevision с обязательным исходным ID и локальной фильтрацией границ.

    • Covers: tbank-data-sync — Сверка операций сохраняет идентичность и прежний результат; tbank-data-sync — Полнота подтверждается успешным покрытием интервалов; brokerage-account-ledger — Ledger entries preserve broker operation meaning.
    • Verification: SQLite integration на нескольких страницах: одинаковый ID, изменённые amount/date/state, исчезнувшая операция, identical duplicate, conflicting duplicate, missing ID/cursor и сбой средней страницы; полная старая выборка/сумма/время не меняются до commit, удаление ограничено account/interval/predicate, частичный income-filter не подтверждает весь счёт. Refresh полного квартала/all с ошибкой второго месяца сохраняет весь прежний результат до атомарного commit publication group.
  • 2.2 [backend] После 2.1 реализовать durable intent и in-process выполнение с coalescing, priority, ограниченной подачей RPC и request-only recovery по processRunId/attemptId.

    • Covers: tbank-data-sync — Прогресс переживает перезапуск и одновременные запросы; tbank-data-sync — Обновление запускается только запросом с учётом свежести.
    • Verification: автоматические гонки 20 одинаковых запросов, пересечения диапазонов и stale attempt; kill/restart между страницами и между stage/publish; без нового запроса 0 запусков, следующий запрос начинает незавершённое окно с первой страницы без дублей; после terminal failure нет retry loop; existing limiter/retry bounds сохраняются.
  • 2.3 [backend] После 2.2 реализовать planner экранных зависимостей, TTL и первичной догрузки истории с учётом календарей и unknown lower bound.

    • Covers: tbank-data-sync — Первая загрузка приоритизирует экран и продолжает историю; tbank-data-sync — Полнота подтверждается успешным покрытием интервалов; tbank-data-sync — Ручное обновление ограничено текущим экраном.
    • Verification: controlled-clock сценарии 59/60, 299/300 и 86399/86400 секунд; повтор current to=now через секунду не создаёт RPC и сохраняет asOf; selected/previous/yearAgo выполняются до старой истории; новый видимый пропуск обгоняет pending backfill; Moscow/UTC boundary, конец месяца/года/февраля и незагруженный хвост; openedOn отсутствует — coverage явно ограничена, вся история не объявлена полной. Зафиксировать проверенные source boundary semantics без выдуманного default from.

3. Локальные владельцы данных и производные результаты

  • 3.1 [backend] После раздела 2 перевести accounts, portfolio и все consumers личных позиций на общий persistent portfolio/membership owner.

    • Covers: brokerage-accounts — Список активных брокерских счетов; portfolio-view — Получение Portfolio выбранного Brokerage Account; portfolio-view — Свежесть и fallback полного Portfolio Snapshot; tbank-data-sync — Все экраны читают сохранённые данные без ожидания T-Bank.
    • Verification: configured HTTP/SQLite сценарии warm/cold/empty/stale portfolio, independent summary failure, all-account membership revision, отсутствующий metadata fallback и known access error; прежние Money/order/unsupported account правила сохранены; portfolio старше пяти минут остаётся доступен при допустимом доступе без блокирующих RPC.
  • 3.2 [backend] После 2.1–2.3 перевести ledger и instrument personal history на локальные фильтры, детерминированную пагинацию и revision-bound cursor; убрать обязательный RAM-page TTL read path.

    • Covers: brokerage-account-ledger — User can retrieve an account ledger; brokerage-account-ledger — User can browse a filtered ledger; brokerage-account-ledger — Кэш страниц журнала ограничивает локальные ресурсы.
    • Verification: HTTP/DB cursor tests на равных timestamps, нескольких счетах, эквивалентных filters, connection/membership/rowset change, invalid cursor и hasNext=false при неполном coverage; categories/UID/page limit не создают полноту; повторная старая страница не вызывает RPC; personal instrument force удаляет только записи своего predicate.
  • 3.3 [backend] После 3.2 перевести income/summary на сохранённые операции и раздельную готовность selected/previous/yearAgo, сохранив точные денежные правила.

    • Covers: brokerage-account-income-analytics — Realized income analytics is account-scoped and period-bound; brokerage-account-income-analytics — Period comparisons preserve calendar and currency meaning; brokerage-account-income-analytics — Realized analytics never presents an incomplete result as complete; brokerage-account-income-analytics — Income payments remain traceable to exact Ledger Entries.
    • Verification: денежные integration tests с несколькими валютами, отрицательной корректировкой, одинаковыми ID одного/разных счетов, empty complete и missing periods; selected complete/previous loading не даёт нулевую базу; all aggregation требует каждого счёта; обновлённая запись пересчитывается один раз; новый period не возвращает старый под новой подписью.
  • 3.4 [backend] После 2.2–2.3 разделить shared catalog/metadata/company/quotes и личные projections; сохранить existing UID/FIGI/ticker lookup и источники bond metrics.

    • Covers: tbank-data-sync — Общие данные инструментов отделены от личных; tbank-data-sync — Все экраны читают сохранённые данные без ожидания T-Bank; tbank-data-sync — Обновление запускается только запросом с учётом свежести.
    • Verification: два пользователя используют сохранённый общий источник без повторного RPC и без передачи private fields/errors; каталог без enrichment не выдаёт ложный пустой поиск; свежий query SBER не подтверждает unknown GAZP, повтор того же query использует сохранённый discovery; company/fundamentals included; minute/day TTL независимы; stale initiating connection не публикует даже общий результат; bond quote percent/nominal/ACI и optional MOEX failures сохраняют прежний смысл.
  • 3.5 [backend] После 3.4 реализовать durable candle coverage, mutable tail и portfolio-instrument prefetch через тот же planner.

    • Covers: tbank-data-sync — Завершённость свечей подтверждается источником; tbank-data-sync — Первая загрузка приоритизирует экран и продолжает историю.
    • Verification: автоматические window tests: 365-day seams/dedupe, complete candle без RPC после restart, old incomplete candle после полуночи, утреннее пустое окно → новая свеча, закрытое пустое окно, missing historyFrom, ошибка ручной перечитки; prefetch только бумаг текущего portfolio, открытие другого инструмента запускает его историю.
  • 3.6 [backend] После 3.1 и 3.4 перевести instrument payouts и account upcoming events на общие сохранённые календари и локальные personal estimates, устранив отдельный synchronous portfolio fetch.

    • Covers: brokerage-account-upcoming-events — User can retrieve upcoming events for an account; brokerage-account-upcoming-events — Forecasts preserve event meaning and uncertainty; brokerage-account-upcoming-events — Upcoming events use complete source results; tbank-data-sync — Общие данные инструментов отделены от личных.
    • Verification: полные/неполные/пустые календари, cancelled dividends, offer без суммы, MOEX missing block, stock/bond source identity, holdings-dependent estimate и отсутствие private values в shared tables; новый portfolio с новой бумагой + ошибка её календаря + restart возвращает прежний полный прогноз/estimate того же scope с исходным временем; новый period/membership не получает чужой snapshot. Events refresh сохраняет применённые from/to.

4. Публичный API и передача контракта

  • 4.1 [backend] После раздела 3 оформить envelope/meta/dependency coverage всех существующих data GET, observe mode, screen-scoped POST sync и авторизованный GET status в DTO/controllers/Swagger.

    • Covers: tbank-data-sync — Ручное обновление ограничено текущим экраном; tbank-data-sync — Интерфейс различает свежесть полноту и состояние работы; tbank-data-sync — Локальная проверка доступа сохраняет границу подключения.
    • Verification: configured HTTP contract tests для каждого route family, включая accounts/search arrays, stock company, quotes/candles/payouts и all scope; 202 не означает завершение, malformed descriptor отклонён, чужой job 404; sync=observe/status не создают RPC при stale/missing/failed; generation отсутствует в API/errors/logs и декодируемых cursors; Problem Details и nullable previous/yearComparison/summary dependency states соответствуют Design. Empty coverage completion меняет stateVersion без изменения pagination revision.
  • 4.2 [backend] После 4.1 опубликовать сгенерированный OpenAPI artifact для frontend и проверить runtime parity, не превращая specs в editable HTTP-контракт.

    • Covers: N/A — передача изменённого публичного контракта из Contract Gate Decision, без самостоятельной бизнес-возможности.
    • Verification: npm run test:openapi-contract и сформированный backend-owned artifact; новые DTO/status/errors представлены, secret examples отсутствуют; artifact передаваем явно, backend CI не читает соседний frontend.
  • 4.3 [frontend] После 4.2 принять предоставленный snapshot, выполнить локальную генерацию и адаптировать entity query owners, включая observe reads и connection/session fences.

    • Covers: frontend-data-resilience — Client Cached Snapshot остаётся доступным при обновлении Accounts и Portfolio; tbank-data-sync — Локальная проверка доступа сохраняет границу подключения.
    • Verification: npm run openapi:generate, npm run openapi:check; typecheck всех consumers, включая breadcrumbs, document title и scope switch; MSW/RTL доказывает одну canonical cache identity для ordinary/observe, поздние data/status ответы старой connection/session игнорируются, all financial caches очищаются успешной mutation и сохраняются после неуспешной.

5. Экранные состояния и ручное обновление

  • 5.1 [frontend] После 4.3 добавить page-owned screen descriptor и observer запрошенной работы по inline UI/UX package revision 1; разделить transport и source lifecycle.

    • Covers: tbank-data-sync — Интерфейс различает свежесть полноту и состояние работы; tbank-data-sync — Ручное обновление ограничено текущим экраном; frontend-data-resilience — Client Cached Snapshot остаётся доступным при обновлении Accounts и Portfolio.
    • Verification: MSW/RTL controlled-clock checks: manual refresh обходит TTL только текущего scope; status poll + observe не создаёт новую работу даже после истечения минуты; observer прекращается при terminal/уходе/logout, active duplicate button недоступна; empty coverage completion отображается до завершения дальней истории; reverse-order observe ответы не откатывают данные/доступ; old data/timestamp остаются при transient failure, failed force до TTL сохраняет fresh, known access error очищает personal view.
  • 5.2 [frontend] После 5.1 адаптировать accounts/account/all screens и независимые overview sections к server completeness/freshness и scoped refresh.

    • Covers: brokerage-accounts — Экран списка брокерских счетов; brokerage-accounts — Клиентские состояния ошибки списка счетов; portfolio-view — Состояния и ошибки Portfolio на клиенте; brokerage-account-ledger — Account overview includes recent ledger events; brokerage-account-income-analytics — Account overview has an independent current-month income summary; brokerage-account-upcoming-events — Account overview includes upcoming events.
    • Verification: RTL scenarios unknown/complete-empty accounts, independent summary staleness, portfolio + recent ops + income + events partial states, сохранённые суммы при failed refresh, 404/invalid token, новая membership в all; кнопка обновляет dependencies overview, не только portfolio.
  • 5.3 [frontend] После 5.1 адаптировать operations/income/events pages: отдельная полнота периодов и comparisons, cursor recovery и сохранение applied filters.

    • Covers: brokerage-account-ledger — User can browse a filtered ledger; brokerage-account-income-analytics — Realized analytics never presents an incomplete result as complete; brokerage-account-income-analytics — Period comparisons preserve calendar and currency meaning; brokerage-account-income-analytics — Income payments remain traceable to exact Ledger Entries; brokerage-account-upcoming-events — Account page presents an upcoming events list.
    • Verification: RTL/MSW: partial empty не показывает «операций/доходов нет», selected готов до comparison без нулевой базы, отрицательная корректировка/одна карточка на identity, INVALID_OPERATIONS_CURSOR возвращает первую страницу с сохранением фильтров, смена периода не переименовывает старые суммы; полный старый events result виден с ошибкой обновления.
  • 5.4 [frontend] После 5.1 адаптировать stock/bond search и detail sections: quote, company/metrics, candles, position, payouts и personal history к общим статусам и текущему screen scope.

    • Covers: tbank-data-sync — Все экраны читают сохранённые данные без ожидания T-Bank; tbank-data-sync — Завершённость свечей подтверждается источником; frontend-data-resilience — Client Cached Snapshot остаётся доступным при обновлении Accounts и Portfolio.
    • Verification: section-adapter и page integration tests различают missing/partial/complete-empty/stale/failed, неполные свечи и личные estimates; refresh сохраняет выбранный график/UID и обновляет показанную personal history, не весь каталог; metadata completion не меняет личную cache boundary.

6. Доказательства корректности и быстродействия

  • 6.1 [backend] После раздела 4 выполнить интегрированный crash/durability/rollback прогон на заполненной изолированной SQLite, расширив существующий подход сохранности данными T-Bank.

    • Covers: tbank-data-sync — Прогресс переживает перезапуск и одновременные запросы; tbank-data-sync — Сверка операций сохраняет идентичность и прежний результат; tbank-data-sync — Локальная проверка доступа сохраняет границу подключения.
    • Verification: сохранить runnable DB/HTTP tests для kill-before/after-publish, concurrent readers, membership change, replace/delete и shared result fence; подтвердить Rollback Contract без потери ручных карт и новых данных; unit mocks не заменяют реальные транзакции и reopen DB.
  • 6.2 [backend] После 6.1 измерить HTTP budget и RPC reduction на профиле Design с задержанным/отказывающим upstream и одинаковым baseline trace из 1.1.

    • Covers: tbank-data-sync — Быстродействие и сокращение запросов проверяются измерениями; tbank-data-sync — Все экраны читают сохранённые данные без ожидания T-Bank; tbank-data-sync — Обновление запускается только запросом с учётом свежести.
    • Verification: ≥100 запросов каждой указанной группы, 10 concurrent clients, p50/p95/p99/max/размеры ответов/hardware; цель p95 ≤500 мс, отдельно первый read после restart; fresh RPC=0, старые полные intervals RPC=0, 20 одинаковых stale requests=1 логический проход/dependency, завершённая работа без нового запроса RPC=0. Показать old/new counts и снижение; провал бюджета не объявлять успехом и не менять порог без явного решения.
  • 6.3 [frontend] После раздела 5 проверить inline UI/UX package revision 1 в браузере и сохранить уместные состояния в существующих stories на вымышленных данных.

    • Covers: tbank-data-sync — Интерфейс различает свежесть полноту и состояние работы; brokerage-accounts — Экран списка брокерских счетов; portfolio-view — Состояния и ошибки Portfolio на клиенте; brokerage-account-upcoming-events — Account page presents an upcoming events list.
    • Verification: journey accounts → account/all → ledger → income/comparison → events → stock/bond: cold, complete, partial, stale, failure, force refresh, leave/reopen, connection replacement; 320/375 px и широкий экран, длинные суммы, keyboard/focus, polite announcements, busy/skeleton/reduced motion. Browser evidence дополняет tests; Storybook build не доказывает состояния.

7. Документация и итоговые gates

  • 7.1 [docs] После подтверждённой реализации обновить as-built storage/access/freshness, инвестиционные flows, public API handoff и термин полноты, сохранив ADR как историю принятого решения.

    • Covers: N/A — delivery объяснений поставленной архитектуры из Design, без параллельного источника требований.
    • Verification: сверить architecture/containers, cross-cutting data-freshness/ui-resilience, http-api, integrations/tbank, domains accounts/operations/portfolio/income/instruments и glossary со всеми delivered flows; обновить отметку отсутствующей реализации ADR 017 только по факту поставки, сохранить исторические решения и чужие изменения. Пути README → тема → термин/API существуют.
  • 7.2 [backend] После 6.1–6.2 выполнить canonical gate для итогового backend и передать финальный OpenAPI artifact при отличиях от 4.2.

    • Covers: N/A — canonical backend verification из Delivery Map и Contract Gate Decision; не отдельное поведение.
    • Verification: npm ci, npm run verify, npm run test:openapi-contract; результаты обязательных DB/HTTP/latency checks относятся к тому же итоговому состоянию. Type/lint/build не объявляются доказательством migration/concurrency или latency.
  • 7.3 [frontend] После 6.3 и финального artifact backend выполнить canonical frontend gate для итоговых types/queries/UI/stories.

    • Covers: N/A — canonical frontend verification изменённого API/UI package из Delivery Map, без самостоятельной бизнес-возможности.
    • Verification: npm ci, npm run verify, включая локальный OpenAPI drift; браузерные и boundary checks должны относиться к итоговому коду. Frontend CI использует свой snapshot, а не checkout backend.
  • 7.4 [docs] После 7.1 выполнить canonical docs gate и смысловую проверку изменённых маршрутов чтения.

    • Covers: N/A — проверка связности as-built documentation из Delivery Map, без новых требований.
    • Verification: npm run verify, проверка новых/изменённых ссылок и терминов; если изменена диаграмма, проверить её renderer либо явно назвать ограничение. Не выдавать Markdown lint за семантическое подтверждение.
  • 7.5 [specs] После implementation-owned задач сверить выполненный результат с каждой delta requirement и обновить этот Tasks по наблюдённым результатам без преждевременного archive/main-spec sync.

    • Covers: N/A — поддержание существующего SDD change и traceability реализации из Delivery Map; новых behaviors или отдельного журнала доказательств не создаёт.
    • Verification: все 35 delta requirement headings, включая REMOVED, имеют выполненные задачи и подходящее evidence; npm run verify, openspec schema validate wealth-ledger-sdd --verbose, openspec validate persist-tbank-data --type change --strict --store wealth-ledger-specs, openspec validate --specs --strict --store wealth-ledger-specs; проверить новые файлы, ссылки и diff. Structural success не означает реализации или approval.

Независимое review и последующее завершение lifecycle не маскируются задачами, которые implementation agent может закрыть самостоятельно. Эта подготовка не разрешает менять приложение, применять миграцию к рабочей БД или архивировать change; текущий результат — комплект для начала реализации.

Implementation checkpoint — 2026-09-24

Пользователь разрешил Apply утверждённых артефактов, включая изменения приложения, публичного API и документации. Архивирование не входит в текущую работу.

  • Completed: 0/27. Задача 1.1 выполнена частично; checkbox не установлен.
  • Backend: ветка codex/persist-tbank-data от полученного origin/develop 0862d56c4e4d9dd554556c3992cc073193020ff1. Production source/schema не изменены. Добавлены test/tbank-read-baseline.e2e-spec.ts и test/fixtures/tbank-read-baseline.json с исходным HTTP trace и результатами.
  • Наблюдённый baseline: временная SQLite со штатными migrations, синтетическое подключение, 3 счёта × 100 000 доступных upstream операций, 200 инструментов; 7 групп × 100 чтений, 10 клиентов. Node v24.21.0, Apple M1 Pro, 10 CPU, 32 GiB. Счётчики считают вызовы TbankClient, а не реальные transport RPC. p95 client end-to-end: accounts 33.05 мс, portfolio 15.21 мс, all portfolio 30.39 мс, ledger 13.17 мс, all ledger 16.20 мс, income 2345.84 мс, all income 7128.47 мс. Полные percentile/size/counters сохранены в JSON; это исходная реализация и не доказательство новой модели.
  • Наблюдённые проверки: backend npm run build, npm run typecheck:test, targeted ESLint, npm run verify (35 suites, 257 tests) — success; node test/sqlite.cjs tbank-read-baseline.e2e-spec.ts — success (1 test). HTTP runner потребовал разрешённый loopback listener вне sandbox. Рабочая пользовательская БД и реальные credentials не использовались.
  • Specs: npm run verify, native schema validation, strict change validation с --store wealth-ledger-specs и strict validation всех 25 main specs — success. Повтор npm ci с сетевым доступом завершился HTTP 502 настроенного Nexus для undici-types-8.9.0.tgz; dependencies/lockfile не менялись.
  • Backend npm ci после проверок также завершился HTTP 502 Nexus для zeptomatch-2.1.0.tgz. Установка могла оставить неполный node_modules; успешный verify выше относится к прежнему установленному окружению. Воспроизводимая установка и canonical gate текущей поставки не закрыты.
  • Remaining: задачи 1.1–7.5. Baseline пока не включает market/candles/payouts, delayed/failing transport, профиль 4 CPU / 8 GiB или заполненные новые таблицы. Миграция, новая модель чтения, frontend/API handoff и as-built docs не реализованы.
  • Next implementation outcome: закончить 1.1 полным воспроизводимым trace профиля Design и подготовкой fixtures, затем переходить к additive migration 1.2.

Продолжение установки

Повторные установки через Nexus снова получили HTTP 502. Выполнен успешный npm ci --registry=https://registry.npmjs.org --replace-registry-host=never в backend (1065 packages) и specs (239 packages), с прежними lockfile/integrity. Manifest, lockfile и постоянная registry configuration не менялись. Это восстанавливает локальное окружение, но не исправляет доступность Nexus.

Checkpoint после продолжения Apply

  • Completed: 1.1, 1.2 (2/27); remaining: 1.3–7.5. Предыдущий checkpoint описывает предыдущий прогон, а не текущее состояние реализации.
  • 1.1: расширенный baseline успешно измерил 23 группы × 100 чтений, 10 concurrent clients, включая stock/bond detail, quote, company/metrics, year/all candles, payouts/search и account/all events. Fixture предоставляет 3 × 100 000 операций и 200 × 5000 свечей; все внешние providers синтетические. Полный trace/percentiles/bytes/счётчики вызовов внешних clients сохранены в backend test/fixtures/tbank-read-baseline.json. Это измерение исходной модели на фактическом host, не доказательство budget новой модели 6.2; transport limiter/retries исключены из этих счётчиков.
  • 1.2: добавлены Prisma models и migration 20260924170000_persist_tbank_data. Revision присваивается существующим подключениям без изменения ciphertext; SQLite rebuild подключения и новые таблицы выполняются одной транзакцией. Private membership/portfolio/operations/coverage/forecasts/work/staging связаны FK с revision; shared metadata/lookups/catalog/sources/candles/coverage хранятся отдельно. Decimal payload и candle close остаются строками.
  • Наблюдённые проверки 1.2: Prisma validate/generate, app/test typechecks, node test/sqlite.cjs tbank-migration.e2e-spec.ts (2 passed). Проверены пустая/заполненная SQLite, reopen, integrity/FK, сохранность старых User/Session/connection/manual-card records, unique operation identity, одинаковые ID разных счетов, decimal round-trip, индекс чтения, отказ позднего staging attempt, cascade private rows и сохранение shared candle.
  • 1.3 частично: PUT повторно использует accounts из validateToken, атомарно заменяет connection/private rows и публикует membership. Local access method не расшифровывает token и не делает RPC; различает unknown/empty/stale и известный invalid token. node test/sqlite.cjs tbank-connection.e2e-spec.ts (3 passed) проверяет HTTP auth, two users, failed replacement, DB rollback, revision rotation и поздние private writes после replace/delete. Известный invalid token блокирует и существующий HTTP accounts read до RPC; финальный повтор HTTP suite (постоянный loopback listener) и verify прошёл. Data GET ещё используют прежние owners; общий publication fence и discovery через coordinator ещё не реализованы. Checkbox 1.3 не установлен.
  • Итоговый backend npm run verify: 34 suites / 253 tests passed. npm run test:durability -- /tmp/wealthledger-tbank-rollback.PuzfjF passed на отдельной предыдущей сборке из 0862d56 и временной SQLite: manual data, restart, rollback/return и backup/restore сохранены. Этот прогон не закрывает задачу 6.1 о новых datasets и worker crash; результатов для неё пока нет.
  • Frontend, docs, публичный envelope и OpenAPI handoff не изменены. Рабочая пользовательская БД не использовалась. Change не архивирован.
  • Next implementation outcome: завершить 1.3 — membership discovery/publication с transaction fence текущей revision/attempt, затем staging/reconciliation 2.1.

Checkpoint — membership publication и операции staging

  • Completed остаётся 2/27. В 1.3 добавлена транзакционная публикация membership через существующий access owner: revision/attempt fence, сохранение datasets неизменных accounts, cascade удалённых accounts, отказ устаревшему invalid-token результату. Отдельный coordinator ещё не подключён; checkbox не изменён.
  • Начата persistence boundary 2.1: concrete operations repository сохраняет страницы и continuation progress в SQLite staging, требует исходный ID, проверяет pagination и противоречащие payload, локально фильтрует [from,to). Publication group обновляет операции/coverage всех accounts и intervals одной транзакцией; instrument predicate ограничивает удаления и coverage. operationsRevision изменяется только вместе с rowset, один раз на account.
  • Наблюдённые проверки: node test/sqlite.cjs tbank-connection.e2e-spec.ts — 4 passed; node test/sqlite.cjs tbank-operations-persistence.e2e-spec.ts — 4 passed. Проверены rollback неполной группы, отрицательная корректировка, одинаковый ID разных accounts, repeated/missing cursor, отсутствие ID, exact upper boundary, конфликт версий между intervals, predicate isolation, прежняя attempt, concurrent read отдельным SQLite connection и reopen. Использованы только изолированные временные SQLite.
  • Backend npm run verify прошёл (34 suites / 253 tests, lint, typechecks, build). Это проверка текущего промежуточного состояния, не финальный gate задачи 7.2.
  • Оставшиеся ограничения: HTTP owners ещё не читают новые datasets; worker/coalescing/recovery и interval planner не реализованы. Repository publication пока использует построчные Prisma operations; производительность на 300 000 строк и budget 500 мс не подтверждены. Проверка kill процесса, shared publication fence и полный Rollback Contract остаются в 6.1–6.2. Frontend/docs и публичный API не изменены, OpenAPI handoff не выполнялся.

Checkpoint — request-driven operations worker

  • Реализован следующий backend этап 2.1–2.2: operations worker получает token только для действующей revision/attempt, сохраняет intent и staging progress, загружает EXECUTED pages через прежний TbankClient и публикует coverage вместе с завершением работы. Уже полное покрытие автоматически требует атомарной повторной сверки всей группы, даже при запросе инкрементального режима.
  • Нормализуются пересекающиеся targets одного account/predicate; RPC windows ограничены UTC-месяцем, с защитной секундой по краям и точным storage filter. Двадцать одинаковых запросов присоединяются к одной попытке. Частичное пересечение расширяет pending target только непокрытым остатком. Запрос, соединяющий несколько активных групп, fenced supersedes их producers и перезапускает объединённый staging новой попыткой; старые handles наблюдают successor без запуска работы. Этот случай может повторно загрузить ранее staged страницы и должен учитываться в итоговых измерениях.
  • Coordinator подаёт одну страницу за turn и выбирает screen перед history; сетевой RPC не удерживает reservation/publication lock. Retry policy остаётся в TbankClient. После terminal failure нет автоматического повторения. При новой runId следующий request очищает unfinished staging/cursor; ранее опубликованные интервалы первичной загрузки сохраняются. Observation и создание нового service не запускают импорт.
  • Evidence: node test/sqlite.cjs tbank-operations-sync.e2e-spec.ts tbank-operations-persistence.e2e-spec.ts — 12 + 4 passed. Sync suite включает настоящий дочерний process и SIGKILL между страницами, перед publish и сразу после publish; child использует текущую сборку из npm run build и только SQLite штатного isolated runner. После kill наблюдение не вызывает RPC, запрос запускает unfinished window с первой страницы; committed result и terminal state переживают kill-after-publish.
  • Проверены полный квартал двух accounts, failure второго месяца и сохранность всех прежних rows/coverage/timestamps, последующий atomic commit, 20-way coalescing, overlap remainder, bridge handles, page priority, known invalid token и отказ чужому account до RPC. Backend npm run verify — 35 suites / 255 tests, lint, app/test typechecks и build passed.
  • Completed остаётся 2/27: 1.3 пока не подтверждена на новом локальном HTTP read path; 2.1–2.2 имеют проверенное operations execution ядро, но ещё не подключены к экранным owners/public sync API. Общий discovery/shared-source scheduling, source TTL/coverage planner 2.3, HTTP envelopes и frontend остаются впереди. Это не итоговое доказательство 6.1, 6.2 или gate 7.2. Бюджет 500 мс и полный RPC navigation trace пока не измерялись.

Checkpoint — operations coverage/freshness planner, 2026-09-25

  • Продолжена 2.3: pure planner разделяет availability, freshness и asOf; полнота вычисляется по union интервалов, независимо от pagination. Account coverage обслуживает instrument subset, обратное не допускается. Current moving end сохраняет наблюдённый asOf и не создаёт RPC на новый хвост внутри TTL; в 300 секунд назначается сверка текущего UTC-месяца. Исторические полные интервалы автоматически не перечитываются, реальные holes не скрываются, после смены месяца незавершённый хвост прошлого месяца остаётся missing.
  • Operations sync service получил readPlan: читает durable coverage, проверяет account membership, возвращает plan и при необходимости запускает existing request-driven worker. Observe всегда read-only; force перечитывает показанные targets. Автоматическая сверка не добавляет RPC для уже полных прошлых месяцев. Верхняя граница новой попытки ограничена временем запроса: будущее не публикуется как подтверждённое coverage.
  • Verification: backend npm run verify — 35 suites / 261 tests passed. Pure calendar/planner suite — 8 tests: 299/300 секунд, current moving end, explicit end, реальные gaps, instrument predicate, rollover и force. node test/sqlite.cjs tbank-operations-sync.e2e-spec.ts tbank-operations-persistence.e2e-spec.ts — 14 + 4 passed на итоговой сборке; сохранены SIGKILL/race/atomic-quarter проверки. Новые SQLite сценарии подтверждают 0 RPC свежего readPlan и stale observe, RPC обычного stale request/force и отсутствие будущего coverage.
  • Completed по-прежнему 2/27: это operations-часть planner, а не весь 2.3. Source TTL 60/86400, discovery и shared sources, screen dependency plans, comparisons/backfill/unknown lower bound, локальные HTTP owners и API envelope ещё не поставлены. Новые функции пока не вызываются существующими HTTP GET. Frontend/docs не изменялись; OpenAPI artifact не изменён. Budget 500 мс и полный navigation RPC trace пока не измерены; change не архивирован.

Checkpoint — local accounts/portfolio HTTP, 2026-09-25

  • Закрыта 1.3: локальный membership/access owner, атомарная замена и удаление подключения, discovery только по запросу, coalescing и revision/attempt fence. SQLite/HTTP evidence: tbank-connection.e2e-spec.ts (4 tests) и tbank-local-reads.e2e-spec.ts (6 tests). Проверены unknown/empty/stale, два пользователя, unsupported/removed membership (закрытый счёт отсутствует в GetAccounts с ACCOUNT_STATUS_OPEN), failed replacement, invalid token, late publication после replace/delete и сохранение retained account data.
  • Accounts и portfolio HTTP теперь читают локальные snapshots и возвращают envelope; missing snapshot даёт null, observe не запускает работу. Полный portfolio сохраняется без временного предела при неудачном обновлении. Warm GET не вызывает GetAccounts, decrypt или metadata RPC. Exact total 21.100000002 сохраняется. Двадцать одновременных reads объединяют discovery; abandoned attempt восстанавливается только следующим обычным запросом.
  • Исправлена freshness составного metadata: худшее обязательное состояние и самый ранний успешный timestamp источников. Пустой aggregate использует TTL membership (300 секунд); непустой portfolio — TTL snapshot (60 секунд). Unit regression проверяет разные TTL и неизменность source timestamps.
  • Verification: npm run verify — 36 suites / 255 tests passed; npm run openapi:generate выполнен; runtime OpenAPI parity — 1 passed; SQLite operations persistence/sync — 4 + 14 passed на актуальной сборке, включая SIGKILL/recovery и атомарный refresh полного квартала/all.
  • Completed 3/27. 3.1 не закрыта: legacy consumers личных позиций ещё используют прежний путь. 2.3 и остальные source owners/API endpoints остаются в работе. Backend OpenAPI сгенерирован; передача frontend snapshot и адаптация consumer остаются задачами 4.2–4.3. Frontend/docs на этом этапе не изменялись. Финальный gate 7.2, полный durability/rollback и профиль 500 мс/RPC reduction не подтверждены. Change не архивирован.

Checkpoint — batch 2.1–2.3, 3.1–3.2, 2026-09-25

  • Закрыты 2.1, 2.2, 2.3, 3.1, 3.2; completed 8/27, remaining 19.
  • 2.1: staging проверяет исходные ID, курсоры и конфликтующие версии, включая смену state. Reconciliation обновляет дату/сумму, удаляет исчезнувшие и отменённые операции только в перечитанном account/interval/predicate. Полный квартал/all публикуется атомарно; ошибка средней страницы/месяца сохраняет прежние строки, суммы, coverage и время. SQLite persistence — 5 passed, включая отдельного читателя, reopen и instrument predicate.
  • 2.2: coalescing пересечений включает whole-account/instrument scope; новый экранный интервал обгоняет pending history, после публикации экранной части остаток получает background priority. Force показанного периода не ждёт несвязанный backfill: внутри durable intent хранится отдельная atomic publication group. Её результат сохраняется при последующей ошибке истории. SQLite sync — 17 passed: 20 одинаковых requests, overlaps/bridge, stale attempt, priority, failure без retry loop и реальные SIGKILL между страницами, до/после publish; recovery запускается только новым запросом. TbankClient остаётся единственным владельцем RPC limiter/retries.
  • 2.3: screen dependency planner описывает membership/portfolio, applied operations, selected/previous/yearAgo через существующий income planner, shared metadata/catalog/quote/company/metrics/calendars/candles. Force исключает архив; ordinary ledger request после экранных интервалов ставит недостающее account history с низким приоритетом. Оконные RPC идут последовательно, без предварительной массовой подачи в limiter. Unknown opening использует явный requested floor 1970, сохраняет unknown boundary и не объявляет полную историю. TTL policy проверена на 59/60, 299/300, 86399/86400 секундах; calendar tests покрывают Moscow/UTC, февраль, смену месяца/года, moving end и missing tail. Proto не обещает default-from/inclusivity: используются явные bounds, защитная секунда и точный локальный [from,to), без нового допущения о нижней границе источника. План shared зависимостей готов; их persistent owners/execution и candle prefetch поставляются задачами 3.4–3.6, public screen dispatch — 4.1.
  • 3.1: старые RAM portfolio snapshots удалены; accounts, stock/bond personal positions и upcoming-events используют общий persistent owner. Отдельный upstream portfolio fetch событий удалён. Missing member скрывает aggregate/position, не превращается в ноль; summary другого счёта остаётся доступной. Проверены metadata fallback, source timestamp, indefinitely stale portfolio, known access failure и reopen. Local reads — 7 passed; portfolio structure HTTP теперь использует настоящую SQLite — 4 passed (точные валюты, отрицательные остатки и неизвестные valuations).
  • 3.2: ledger/person-instrument history читают SQLite transaction со стабильным порядком occurredAt/accountId/brokerOperationId. HMAC cursor связан с user/connection, all membership, нормализованным filter/limit и account row revisions, без connection identifier в payload. Изменение coverage/time не ломает cursor; изменение rows/owner/connection — ломает. Read-only observe не ставит work; partial coverage не становится complete из-за hasNext=false, category/UID или размера страницы. HTTP SQLite — 5 passed, включая reopen, равные даты/ID, equivalent categories и отсутствие RPC старых полных страниц. RAM page TTL read path удалён. Legacy RPC collector сохранён только для ещё не переведённого income (3.3).
  • Gates: npm run verify — 38 suites / 235 tests passed, lint, app/test typecheck и build успешны. npm run openapi:generate выполнен; openapi-contract.e2e-spec.ts — 1 passed. Дополнительно сохранены connection SQLite/HTTP — 4 passed. Всего relevant SQLite/HTTP — 43 passed (1 + 4 + 5 + 17 + 7 + 5 + 4), рабочая БД не использовалась. git diff --check успешен; native validation и specs gate выполнены.
  • Frontend/docs в этом batch не изменялись. Generated backend openapi.json содержит новые envelopes; явная передача consumer snapshot остаётся 4.2. Профиль 500 мс/RPC reduction, итоговый durability/rollback и gates 7.2–7.5 не закрыты; change не архивирован и не объявляется завершённым.
  • Следующий Implementation outcome: 3.3 — income/summary из согласованного локального набора операций с отдельной готовностью selected/previous/yearAgo и сохранением прежнего полного результата при неудачной сверке.

Checkpoint — local income/summary, 2026-09-25

  • Закрыта 3.3, completed 9/27, remaining 18. Income/summary читают операции, coverage и membership одной SQLite read transaction. Удалён последний synchronous operations collector; income больше не получает cursor pages или metadata до HTTP-ответа.
  • Selected, previous и yearAgo имеют отдельные coverage/status; неполный selected возвращает data:null, незагруженное сравнение — null без нулевой базы. Невозможное календарное/историческое сравнение имеет unavailableReason. Moscow inclusive dates преобразуются в half-open UTC; historical period не расширяется до now, current month сохраняет подтверждённый asOf. Расчёты используют прежние decimal helpers и source timestamps.
  • Наблюдённые проверки: npm run verify — 36 suites / 232 tests passed, lint, app/test typecheck и build; npm run openapi:generate выполнен. node test/sqlite.cjs tbank-income-local.e2e-spec.ts tbank-ledger-local.e2e-spec.ts tbank-operations-persistence.e2e-spec.ts tbank-operations-sync.e2e-spec.ts openapi-contract.e2e-spec.ts — 7 + 5 + 5 + 17 + 1 passed. Только временные изолированные SQLite. Income HTTP проверяет exact signed multi-currency sums, одинаковые ID разных accounts, correction без повторного учёта, partial all/complete empty, раздельные comparisons, другой period, source time/asOf, reopen, observe, blocked upstream, access/period validation и невидимость unfinished staging с сохранением старого финансового результата после failure.
  • Старые mock-only suites синхронного collector заменены SQLite income проверками; pure финансовые проверки сохранены. Backend OpenAPI содержит income envelopes и nullable previous. Передача consumer snapshot остаётся задачей 4.2; frontend/docs на этом этапе не изменялись.
  • В запрошенном batch 3.4–3.6 и 4.1 ещё не выполнены. Общие источники, свечи, durable forecasts и public sync API требуют дальнейшей реализации. Измерения профиля 500 мс/RPC reduction и финальные gates не закрыты. Change не архивирован и implementation complete не заявлен.
  • Следующий Implementation outcome: 3.4 — общие сохранённые catalog, metadata, quotes, company/metrics с раздельной freshness и revision fence.

Checkpoint — shared UID/FIGI metadata, 2026-09-25

  • Продолжена 3.4; checkbox остаётся открытым, completed 9/27, remaining 18. Existing InstrumentMetadataService теперь использует сохранённые Instrument/InstrumentLookup и private SyncWork вместо RAM TTL. Успешное отсутствие отделено от failed lookup; UID/FIGI fallback и aliases сохраняются, FIGI не превращается в выдуманный provider UID.
  • Успешная metadata переиспользуется между пользователями и после reopen. Для одинакового UID/FIGI descriptor requests объединяются в producer, наблюдатели получают собственные handles. Publication и ошибки fenced по текущей connection revision/attempt; удалённый/заменённый инициатор не изменяет даже общий timestamp. Ошибка его credentials не становится общим отрицательным lookup и не передаётся другому пользователю.
  • Worker запускается только запросом, читает credentials только для актуальной attempt и подаёт последовательные вызовы через прежний TbankClient. Observe и создание нового service не восстанавливают unfinished intent; новый обычный запрос меняет attempt. Нет startup scan, timer или retry loop. Внутренний force обходит TTL, присоединяется к активной работе и сохраняет ещё свежий источник/время при ошибке. Public screen sync остаётся в 4.1.
  • Portfolio normalization и ledger читают metadata из SQLite. Обычные запросы планируют отсутствующую/устаревшую metadata показанных позиций/операций; observe этого не делает. Изменение metadata журнала меняет stateVersion, сохраняя pagination binding и действующий cursor. Batch 1000 identities проверен реально: обнаруженный SQLite/Prisma parameter limit устранён ограниченными IN queries в одной read transaction.
  • Evidence: npm run verify — 35 suites / 216 tests passed, lint, app/test typecheck и build. Старые RAM-only metadata mocks заменены реальной SQLite suite. node test/sqlite.cjs tbank-metadata-persistence.e2e-spec.ts tbank-local-reads.e2e-spec.ts tbank-ledger-local.e2e-spec.ts portfolio-structure.e2e-spec.ts tbank-income-local.e2e-spec.ts openapi-contract.e2e-spec.ts — 15 + 7 + 6 + 4 + 7 + 1 passed. Проверены 20-way coalescing, два пользователя, UID/FIGI/negative/sparse outcomes, transient fallback, 86399/86400 seconds, failed force, late completion после replace/delete, superseded attempt, reopen/request-only recovery, сохранность финансовых read paths и runtime OpenAPI parity. Использованы только временные изолированные SQLite; git diff --check passed.
  • Не закрыты catalog discovery/enrichment, stock/bond company/metrics/quotes и оставшиеся shared projections 3.4; candles 3.5, forecasts 3.6 и API 4.1 также впереди. Полный профиль 500 мс/RPC reduction не измерен; новые RPC assertions относятся к указанным controlled-source tests. Frontend/docs не изменены, consumer artifact не передавался, change не архивирован.
  • Следующий Implementation outcome: продолжить 3.4 — persistent catalog discovery с отдельными enrichment/quote sources и локальные stock/bond reads, сохранив query identity, ticker ambiguity и MOEX/NCR semantics.

Checkpoint — persistent catalog discovery owner, 2026-09-25

  • Продолжена 3.4, checkbox открыт: completed 9/27, remaining 18. Добавлен concrete CatalogDiscoveryRepository/Service в instruments module. Успешный discovery сохраняет упорядоченные UID по нормализованному query/type отдельно от минимальных public catalog identities в InstrumentSource. Отсутствующий query возвращает null; подтверждённый пустой — []. Сохранённый SBER не подтверждает GAZP или bond query. Enrichment не требуется для чтения найденных identities и не считается подтверждённым этим discovery.
  • Existing stock/bond selection вынесен в один используемый обоими owners helper: trade availability, exact ticker, preferred class, UID ordering, ISIN dedup и отдельные missing-ISIN UID сохранены. Discovery сохраняет прежний предел 30 после dedup. Минимальный catalog payload явно выбирает public поля и не перезаписывает уже имеющуюся полную Instrument metadata или её timestamp; InstrumentLookup completeness не создаётся автоматически.
  • Read/request/observe API нового owner использует local access, durable private work handles, дневной TTL и existing TbankClient. Одинаковые query/type двух пользователей объединяются; credentials берутся только у актуального producer. Shared writes и final states защищены connection/attempt fence. Recovery запускается только обычным запросом; observe и создание service работу не возобновляют. Failed force сохраняет прежний набор и timestamp.
  • Evidence: backend npm run verify — 35 suites / 216 tests passed, lint, оба typecheck и build. node test/sqlite.cjs tbank-catalog-discovery.e2e-spec.ts tbank-metadata-persistence.e2e-spec.ts — 10 + 15 passed на disposable SQLite со штатными migrations. Проверены normalized/different queries/types, successful empty/unknown, reopen, 20-way coalescing, private handles, whitelist shared fields, независимость полной metadata, late replace/delete, invalid-token isolation, superseded attempt, request-only recovery, failed force и 86399/86400-second boundary.
  • Ограничение этапа: новый discovery owner зарегистрирован в DI, но HTTP search/detail ещё использует legacy orchestration. Его переключение вместе с отдельными persistent enrichment/quote sources остаётся в 3.4; заявлять локальный HTTP-поиск или отсутствие его broker wait пока нельзя. Company, bond metrics/MOEX/NCR, candles, forecasts и public sync API также остаются. Wire contract не менялся; frontend/docs и consumer snapshot не затронуты. Профиль 500 мс/RPC navigation trace не измерялся; change не архивирован.
  • Specs npm run verify и native strict validation persist-tbank-data с явным --store wealth-ledger-specs успешны; backend/specs diff whitespace checks успешны, включая новые source/test files.

Checkpoint — local stock/bond search and persistent enrichment, 2026-09-25

  • Продолжена 3.4, completed 9/27, remaining 18. HTTP GET /stocks и /bonds теперь читают сохранённые discovery/detail/last-price sources, возвращают {data, meta} и поддерживают sync=observe. Неизвестный query даёт null, подтверждённый пустой — []; найденные identities доступны при незавершённых/отказавших enrichment sources. Метаданные описывают отдельные зависимости, их availability/freshness/private work handles; resourceKey стабилен между missing и последующим результатом.
  • CatalogEnrichmentService сохраняет типизированные детали по UID и prices раздельно. TTL деталей — сутки, prices — минута; повторный query использует уже сохранённые sources независимо от пользователя. Cold discovery запускает запрошенные enrichment dependencies самостоятельно, поэтому observe не обязан инициировать следующий этап. UID работ объединяются между query/users; до 30 цен одного producer идут одним existing getLastPrices RPC, подробности запрашиваются последовательно через existing TbankClient. Новых dependencies, migration, scheduler или внешней очереди нет.
  • Публикация каждого source проверяет current connection/revision/attempt; batch дополнительно проверяет initiating attempt. Удаление/замена подключения или superseded initiating attempt не позволяют опубликовать остальные цены batch. Failed force оставляет прежние данные и timestamps. Shared payload явно выбирает public fields. Успешные полезные детали также обновляют canonical Instrument и UID/FIGI aliases внутри той же transaction: generic metadata owner переиспользует результат без повторного RPC. Successful typed miss не становится отрицательным generic UID lookup.
  • Сохранены decimal price mapping, bond pricePercent отдельно от Money, nominal/ACI, UID matching пакетных цен, selection/dedup/limit. Legacy mock tests синхронного search заменены реальными SQLite/HTTP сценариями; прежние ticker/market/company финансовые tests продолжают проходить.
  • Evidence на итоговом коде: backend npm run verify — 35 suites / 209 tests, lint, оба typecheck и build passed. npm run openapi:generate выполнен. node test/sqlite.cjs tbank-catalog-local.e2e-spec.ts tbank-catalog-discovery.e2e-spec.ts tbank-metadata-persistence.e2e-spec.ts tbank-ledger-local.e2e-spec.ts stocks.e2e-spec.ts bonds.e2e-spec.ts openapi-contract.e2e-spec.ts — 15 + 10 + 15 + 6 + 16 + 18 + 1 = 81 passed. HTTP sandbox EPERM повторён с разрешённым локальным loopback; итоговый прогон успешен. Только disposable SQLite, рабочая БД не использовалась.
  • Проверены blocked discovery/enrichment без ожидания HTTP, partial/empty/unknown, shared reuse после reopen без decrypt/GetAccounts/RPC, одна price batch на 30 бумаг, межпользовательские/private handles, failed force, независимые minute/ day TTL, wrong detail UID, late replace/delete и superseded batch origin, request-only recovery, финансовые строковые значения и configured access/DTO validation. Эти RPC assertions не заменяют полный профиль измерений 6.2: 500 мс и navigation RPC reduction пока не подтверждены.
  • Остаток 3.4: локальные UID/ticker detail endpoints, company/fundamentals, полноценные quote/metrics owners и MOEX/NCR semantics; legacy synchronous read paths этих sections пока сохранены. Candles/forecasts/public sync API остаются 3.5/3.6/4.1. Backend OpenAPI обновлён, явная передача consumer snapshot остаётся 4.2; frontend/docs в этом этапе не менялись. Change не архивирован, задача 3.4 и общий implementation complete не объявлены.

Checkpoint — local instrument sections, 2026-09-25

  • Завершена 3.4, completed 10/27, remaining 17. UID/ticker, company/fundamentals, quotes и bond metrics читают SQLite и поддерживают observe; missing не превращается в пустой финансовый результат. Exact ticker проверяется до listing selection/ISIN dedup; неоднозначность сохраняется, optional alias не подменяет запрошенный UID другой площадкой.
  • Details/company/ratings и minute quote sources сохраняются раздельно. MOEX yield и NCR rating сохраняют source identity, точные значения и прежние timestamps при failed force. Shared sources не содержат private projections; два пользователя используют общий результат с private handles. Сохранённая metadata обновляет названия/логотипы portfolio без изменения финансовых сумм и времени portfolio snapshot.
  • Исправлена гонка присоединения наблюдателя во время SQLite publication: producer остаётся зарегистрированным до обработки всех присоединений. Реальный DB test доказывает один RPC и два завершённых private handles.
  • Evidence: npm run verify — 35 suites / 196 unit tests, lint, app/test typecheck, build passed; npm run openapi:generate passed. SQLite/HTTP suites catalog-local/discovery/metadata/local-reads/portfolio/ledger/stocks/bonds/ openapi-contract: 22+10+15+7+4+6+16+18+1 passed; после финальных additions local-reads 8 passed, catalog-local 24 passed. Runtime OpenAPI parity passed; HTTP fixtures используют постоянный loopback listener. Только disposable SQLite и synthetic credentials; git diff --check passed.
  • Tasks 3.5, 3.6, 4.1, 4.2 запрошенного batch ещё не завершены. Свечи, payouts/events пока сохраняют legacy orchestration. Передача OpenAPI consumer snapshot ещё не выполнена; frontend/docs не изменены. Полный профиль latency/ RPC 6.2 не измерен; implementation complete и archive не заявлены.
  • Следующий Implementation outcome: 3.5 — durable candle coverage с source-confirmed closed ranges, mutable tail и request-only recovery.

Checkpoint — persistent candle reads and atomic reconciliation, 2026-09-25

  • Продолжена 3.5, checkbox открыт; completed 10/27, remaining 17. Stock/bond candles HTTP теперь возвращает локальный {data, meta} с observe. Durable CandleRepository использует существующие Candle/Coverage/SyncWork/ SyncStage; новых schema, dependencies, scheduler или startup scan нет.
  • Диапазоны до 365 суток собираются в staging и публикуются общей transaction. Повторная сверка удаляет исчезнувшие свечи только своего диапазона, сохраняет coverage вне него и при ошибке следующего окна оставляет предыдущие данные и timestamps целиком. Late/superseded/deleted attempts не публикуют данные.
  • Closed empty coverage переиспользуется после reopen; source isComplete и точные decimal strings сохраняются, bond close остаётся процентом. Текущий UTC-день, включая пустой, изменяемый с minute TTL; смена дня сама не закрывает старое empty/incomplete окно. Полнота ответа отделена от TTL: истечение минуты сохраняет полный результат с stale freshness. Unknown historyFrom для all сохраняет STOCK/BOND_HISTORY_START_UNAVAILABLE.
  • 20 одновременных запросов объединяются, typed metadata ожидается только внутри worker через существующего source owner. Observe не возобновляет abandoned intent; следующий обычный запрос меняет attempt и запускает работу. Worker последовательно подаёт RPC через existing TbankClient.
  • Evidence итогового кода: npm run verify — 36 suites / 197 unit tests, lint, оба typecheck и build passed; дополнительный npm run typecheck:test после последнего SQLite scenario passed. OpenAPI generated; последовательный runtime parity passed. node test/sqlite.cjs tbank-candles-persistence.e2e-spec.ts tbank-catalog-local.e2e-spec.ts tbank-local-reads.e2e-spec.ts stocks.e2e-spec.ts bonds.e2e-spec.ts openapi-contract.e2e-spec.ts — 8+26+8+16+18+1 = 77 passed. Первый parity run пересёкся с build и увидел прежний dist; итоговый прогон выполнен после завершения build/generation. Только disposable SQLite; git diff --check passed.
  • Остаток 3.5: portfolio-only prefetch через screen planner, продолжение дальней истории после показанного периода и интеграция quote comparison с общей candle coverage. Нужна итоговая проверка очередности/предзагрузки и полного crash/restart поведения после этой интеграции. Поэтому 3.5 не отмечена выполненной. Tasks 3.6, 4.1, 4.2 также не завершены; весь batch из пяти задач не выполнен. Frontend/docs и consumer snapshot не изменялись. Профиль p95 500 мс/RPC reduction не измерялся; archive не выполнялся.
  • Следующий Implementation outcome: завершить 3.5 — подключить planner предзагрузки только сохранённых portfolio instruments к тому же candle owner без циклических DI dependencies и подтвердить remaining Verification.

Checkpoint — portfolio candle prefetch and screen priority, 2026-09-25

  • Завершена 3.5, completed 11/27, remaining 16. Existing shared instrument providers собраны в InstrumentSourcesModule без дублирования DI instances и forwardRef; PortfolioModule использует публичный CandleService.
  • Предзагрузка отбирает только сохранённые STOCK/BOND positions с UID, удаляет дубликаты и применяет existing screen planner. На warm portfolio read её DB планирование не блокирует HTTP; одинаковые активные prefetch объединяются. Открытый не входящий в portfolio инструмент получает собственную историю.
  • После показанного периода очередь продолжает all-history с меньшим приоритетом. Каждый RPC-window уступает место экранным dependencies; automatic windows публикуются постепенно, force остаётся атомарным для всего показанного периода. Coverage повторно проверяется между окнами. Quote comparison сохраняет и переиспользует тот же durable candle coverage.
  • Evidence: backend npm run verify — 36 suites / 197 tests, lint, оба typecheck, build passed. OpenAPI generated. SQLite candles/catalog/local reads/ portfolio/OpenAPI suites — 9+26+8+4+1 = 48 passed, включая ordering между окнами, portfolio-only scope, opening another instrument, request-only recovery, midnight/empty coverage, failed force, exact bond percentage и comparison reuse. Использована только disposable SQLite; latency/RPC profile 6.2 не измерялся.
  • Следующий Implementation outcome: 3.6 — shared payout calendars и private last-complete forecast fallback с исходными timestamps и membership/range fence.

Checkpoint — durable payout calendars and forecasts, 2026-09-25

  • Завершена 3.6, completed 12/27, remaining 15. Instrument dividends, coupons и account/all events читают saved calendars + persistent portfolio, возвращают envelope и поддерживают observe. Stock/bond legacy RAM callbacks и отдельные synchronous calendar/portfolio fetch удалены. Общие источники сохраняют raw events без quantities/estimates; account bond events остаются MOEX, instrument coupons — T-Bank; missing MOEX block не становится [].
  • ForecastService/Repository принадлежат existing private portfolio owner и используют TbankForecast. Publication проверяет current connection/membership, portfolio versions и shared source versions/timestamps в SQLite transaction. Старый полный snapshot сохраняется при missing новой зависимости, ошибке календаря и reopen; другой applied range/membership не получает его данные. Successful одинаковые dependencies не меняют calculatedAt/исходные timestamps. Public payout rows при missing personal snapshot не получают неподтверждённые estimates; private calculations не возвращаются мимо publication fence.
  • Сохранены exact signed/fractional money, валюты, registry dates, cancelled dividends, offer без суммы, redemption отдельно от income totals, future unfixed payout entitlement и optional metadata fallback к portfolio ticker.
  • Evidence: npm run verify — 36 suites / 188 unit tests, lint, оба typecheck, build passed; старые synchronous-cache orchestration tests заменены SQLite tests, pure financial checks сохранены. OpenAPI generated. SQLite/HTTP upcoming-events/catalog/candles/local reads/stocks/bonds/OpenAPI — 15+26+9+8+16+18+1 = 93 passed, включая реальную optimistic-publication race, two-user reuse/private values, new holding failure + reopen, membership/range isolation, cancelled/empty/unknown calendars, MOEX failure, late connection deletion, default/inclusive dates и observer without RPC. Только disposable DB.
  • Consumer snapshot ещё не передан; frontend/docs не изменены. Профиль 500 мс/ RPC reduction остаётся 6.2, archive не выполнялся.
  • Следующий Implementation outcome: 4.1 — validated screen-scoped force dispatch и observational authorized status с DTO/OpenAPI и resource states.

Checkpoint — sync contract preparation, 2026-09-25

  • Запрошенная пятёрка 3.5, 3.6, 4.1, 4.2, 4.3: первые две завершены; 4.1 остаётся открытой, общий счёт 12/27. Добавлены DTO и подготовка durable screen intent, нормализация разрешённых screen fields и scope; это пока не подключённые публичные POST/status endpoints.
  • Dependency DTO теперь описывает фактически возвращаемые dataRevision и stateVersion. Общий mapper учитывает running/queued/failed dependencies, сохраняя availability и successful timestamps прежнего результата. Candle meta явно возвращает requested/complete/missing coverage независимо от freshness; stale current tail не превращается в missing interval.
  • Проверки: backend npm run verify — 37 suites / 192 tests passed, lint, оба typecheck и build; npm run openapi:generate passed. node test/sqlite.cjs tbank-candles-persistence.e2e-spec.ts tbank-catalog-local.e2e-spec.ts tbank-local-reads.e2e-spec.ts upcoming-events.e2e-spec.ts openapi-contract.e2e-spec.ts — 9+26+8+15+1 = 59 passed. Только disposable SQLite и synthetic credentials. Исправлена устаревшая неполная metadata fixture candle-тестов; unit income изолирует Prisma import после расширения operations public provider exports.
  • Frontend snapshot не передан, frontend не изменён; existing docs edits сохранены. Полный профиль 500 мс/RPC 6.2 не измерялся; archive не выполнялся.
  • Следующий Implementation outcome: завершить 4.1: подключить scoped dispatcher к existing owners и observational status с текущими resource stateVersion, проверить configured HTTP authorization/validation/observe и coalescing на SQLite. Затем последовательно выполнить 4.2 и 4.3.

Checkpoint — public sync/status and explicit OpenAPI handoff, 2026-09-25

  • Завершены 4.1–4.2, итог 14/27. POST tbank-sync строго валидирует screen scope, нормализует поля, резервирует private handle и возвращает 202 до broker completion. Concrete coordinator раскрывает dependency graph через existing membership/portfolio/operations/catalog/calendar/candle owners. Force не запускает full-history prefetch и сохраняет атомарность показанного периода operations. Новая инфраструктура/dependencies не добавлены.
  • Status авторизует current connection/account, использует только observe reads, возвращает текущие resource stateVersion и terminal outcome. Поддержаны handles обычных GET; abandoned work не запускается. Screen progress фиксирует child attempts, superseded результат не приписывается прежнему запросу.
  • Evidence: backend npm run verify — 37 suites / 192 tests, lint, app/test typecheck и build passed. SQLite/HTTP run screen-sync/all/local-reads/ledger/ income/catalog/candles/events/stocks/bonds — 10+18+8+6+7+26+9+15+16+18. Финальный screen-sync — 11 passed, включая empty coverage stateVersion без изменения dataRevision; runtime OpenAPI parity — 1 passed. 20-way POST coalescing, 202 при заблокированном upstream, malformed/foreign scope, private handles, failure без retry, old-process cancellation и old-connection 404 проверены на disposable SQLite. All route tests обновлены с legacy synchronous mock на настоящую локальную DB boundary.
  • Backend openapi.json явно скопирован в frontend src/shared/api/spec/openapi.json; frontend npm ci, локальные openapi:generate и openapi:check успешны. Frontend CI не читает backend. 4.3 остаётся открытой до итоговых frontend lifecycle tests/gates.
  • Профиль latency/RPC 6.2 не измерялся; archive не выполнялся. Следующий Implementation outcome: завершить entity query envelope/observe owners и доказать session/connection/access/latest-response fences во frontend.

Checkpoint — frontend resource owners and response fences, 2026-09-25

  • Завершена 4.3, итог 15/27, remaining 12. Все investment entity query owners используют backend envelope. Canonical generated query identity хранит envelope, owners возвращают payload и meta существующим consumers. Missing null не становится []/нулевым финансовым успехом. Types derived from snapshot, включая nullable periods, проходят проверку всех consumers; account VM использует accounts owner вместо прежнего raw-array cache cast.
  • Observe использует тот же generated key с отдельным transport mode. При несовпадении ожидаемого stateVersion stale response не публикуется; повторяется только observational read. Transport объединяет identity ordinary/ observe для latest-request fencing. In-flight records с ограниченным временем жизни очищаются после завершения; новая инфраструктура или зависимости не добавлены.
  • Успешная connection mutation отменяет publication прежних data/status/mutation responses и сбрасывает финансовые GET caches, включая sync status. Failed mutation сохраняет caches/boundary. Session generation и unmount защищают ответы от прежней session. Confirmed private access loss очищает snapshots, отменяет связанные запросы и повышает access epoch; поздний success не восстанавливает скрытые данные. Обычный 503 сохраняет cached snapshot.
  • Sync mutation/status hooks готовы в existing tbank-connection feature; автоматический page observer и действия refresh остаются 5.1, не включены в эти hooks. Existing frontend fixtures обновлены до нового wire envelope; generic transport tests проверяют envelope, presentation tests — payload.
  • Evidence: frontend npm ci, openapi:generate, openapi:check; полный npm run verify успешен: typecheck, Biome, 51 suites / 287 tests с coverage, Knip, dependency/FSD и Storybook dependency gates, production build и Storybook build. После усиления status-publication assertions targeted sync tests 2 passed, финальный typecheck passed. Полный gate ранее также прошёл на итоговом production code. MSW/RTL проверяют canonical observe cache, rejection старой версии, late ordinary/observe ordering, missing/failed null, access loss + late sibling response, connection/session status и mutation. Subscription на query cache подтверждает отсутствие публикации old status.
  • Backend финальный npm run verify — 192 tests, lint/type/build; итоговые screen-sync 11 passed и runtime OpenAPI parity 1 passed. Nested descriptor errors содержат field pointers. Backend artifact и явно переданный frontend snapshot побайтово совпадают (cmp). Все DB проверки использовали disposable SQLite. Diff whitespace checks успешны.
  • Docs и root не менялись этим batch; прежние docs edits сохранены. Frontend production/Storybook builds сообщают предупреждения о крупных chunks; gates завершаются успешно. Browser proof/новые UI states остаются 6.3, latency/RPC profile 6.2 не измерялся. Archive не выполнялся.
  • Следующий Implementation outcome: 5.1 — page-owned descriptor и passive observer известной работы по inline UI/UX revision 1, с отдельными transport и source lifecycle, остановкой observation после ухода или terminal outcome.

Checkpoint — scoped screen refresh and populated rollback proof, 2026-09-25

  • Завершены 5.1–5.4 и 6.1, итог 20/27, remaining 7. Descriptors принадлежат page VMs; existing tbank-connection feature наблюдает только полученные handles. Status polling и canonical observe reads не инициируют новые imports; terminal/leave/logout останавливают polling. Dependency-only completion также перечитывает projection. Повторный POST текущего scope защищён; поздний acceptance другого scope не заменяет текущий handle.
  • Entity owner отдельно отдаёт transport status/error, сохраняя source metadata. Known access failures очищают private snapshots с существующим epoch fence; NOT_FOUND самого work handle не трактуется как потеря доступа ко всем счетам. Transient transport failure и failed source work показываются раздельно; прежние суммы, source timestamps и fresh до TTL сохраняются.
  • Accounts различает unknown и complete-empty; карточки показывают timestamps и freshness отдельных portfolio summaries. Account/all refresh охватывает membership, portfolio, operations, income и events. Частичный portfolio не показывает окончательные totals/structure; подтверждённые позиции и operations/events остаются видимыми с сообщением о неполноте. Overview sections сохраняют независимые partial/error/stale состояния.
  • Operations/income/events используют applied scope и source completeness. Partial empty не получает финансовый empty message; selected income не ждёт year comparison и не получает вымышленную нулевую базу. Cursor recovery возвращает первую страницу с прежними dates/categories. Смена периода не переименовывает прежний snapshot; сохранённый forecast виден с исходным временем при failed source refresh.
  • Stock/bond search и detail используют те же source states. Ручной refresh передаёт текущие UID, candle period и personal-history categories/limit, не сбрасывает график и не запрашивает весь каталог. Общий section adapter учитывает missing/partial/stale/failed и source timestamps; незавершённые свечи и неподтверждённые personal estimates не превращаются в нули.
  • Frontend evidence: итоговый npm run verify — 53 suites / 306 tests, OpenAPI check, typecheck, Biome, coverage, Knip, FSD/dependency и Storybook dependency checks, production и Storybook builds passed. MSW/RTL проверяют duplicate POST, terminal/leave/logout, переход времени за TTL без ordinary GET, empty completion при ещё running history, dependency completion, access loss, fresh snapshot при failed force, scope stock/bond, independent overview/summary freshness, полный overview observe и invalid cursor recovery. Ранее созданные race/negative-correction/period-boundary проверки также входят в этот итоговый gate. Browser/reduced-motion/viewport proof остаётся 6.3, успешная Storybook build его не заменяет.
  • Backend evidence: npm run verify — 37 suites / 192 tests, lint, оба typecheck и build passed. Исправлены unsafe Jest asymmetric matcher values в screen-sync test, runtime assertions field pointers сохранены. Через node test/sqlite.cjs прошли operations-sync/migration/connection/catalog/ candles/events — 17+2+4+26+9+15, затем operations-persistence/ledger-local/ screen-sync — 5+6+11; всего 95 SQLite/HTTP checks. Включены SIGKILL между страницами и до/после publish, отдельный concurrent SQLite reader, reopen/request-only recovery, membership replace/delete и shared fences.
  • Existing test/bank-cards-durability.cjs расширен populated T-Bank datasets, coverage, forecasts, shared sources, staging/progress и migration state. npm run test:durability -- /tmp/wealthledger-tbank-rollback.PuzfjF passed: equality после restart, rollback/return и restore в другую SQLite; integrity и FK checks; User/Session/connection/manual cards, refunds/tombstones и новые datasets сохранены. Evidence result: /var/folders/j_/h2ft23gd3qq35ps3v5bcftfm0000gn/T/wealthledger-bank-durability-7MLwhL/result.json.
  • Rollback pair проверена явно: JSON OpenAPI, сгенерированный прежним backend 0862d56c4e4d9dd554556c3992cc073193020ff1, равен consumer snapshot frontend a209d715892862bb6d48084df0c84a10b8d56bf1 (db184c8^). Более новый frontend HEAD содержит другой validation/conflict contract и не объявлен подходящей парой этого rollback build. Deploy/rollback реального приложения не выполнялись. Текущие backend OpenAPI и явно переданный frontend snapshot побайтово совпадают (cmp); новых public DTO изменений в этом batch нет.
  • Только disposable SQLite/synthetic credentials; рабочая БД не использовалась. Root/docs не менялись, прежние docs edits сохранены. git diff --check passed. Builds сохраняют предупреждения о крупных chunks. Профиль 500 мс/RPC reduction 6.2 ещё не измерен; implementation complete не объявлена. Remaining: 6.2, 6.3, 7.1–7.5. Archive/main-spec sync не выполнялись.
  • Следующий Implementation outcome: 6.2 — измерить HTTP/RPC по согласованному профилю и baseline trace; затем 6.3 — browser verification inline UI revision 1.

Checkpoint — measured reads, browser proof and application gates, 2026-09-25

  • Завершены 6.2, 6.3, 7.1, 7.2, 7.3, итог 25/27, remaining 2. Backend сохраняет existing owners: batch reads coverage/source work заменяют загрузку свечей и N+1 queries при prefetch/projection; Intl formatter reused. Проверка source versions прогноза разбита на batches внутри одной transaction, чтобы 200 инструментов не превышали SQLite parameter limit. Financial publication fences и fallback сохранены; новой инфраструктуры нет.
  • Performance runner: node test/sqlite.cjs tbank-read-baseline.e2e-spec.ts. Evidence: backend test/fixtures/tbank-read-persistent.json. Изолированный Docker, network none, без volumes; cgroup 4 CPU / 8 GiB (VM доступно 7.65 GiB), Apple M1 Pro SSD host, Node 24.21.0. SQLite 619343872 bytes: 300000 операций, 1000000 свечей, 3 счёта / 200 инструментов. Dependency entries image lock совпадают с текущим lock; отличается только version корневого package.
  • 2300 warmed reads: 23 группы × 100, concurrency 10. Server ingress → response finish p95 7.3–382.6 ms, все группы ≤500 ms. p50/p99/max/bytes сохранены. Первый DB-only read после Nest/provider restart: 71.2 ms client (HTTP logger 16 ms). Это не OS-process restart; отдельный process crash/reopen проверен durability suite. Fresh mutable timestamps обновлялись перед каждой группой, чтобы измерять именно fresh path; полный прошлый coverage сохранён.
  • Baseline navigation trace: 42913 → 0 synthetic TbankClient calls (100% reduction), включая первые reads; baseline repeated-only часть — 41821. Реальный внешний broker network не измерялся; baseline host latency не сравнивается с container latency. 20 stale requests: один portfolio и один positions pass, retries 0; все ответы за 1717 ms при upstream delay 2000 ms. Cold import ответ 18.3 ms; завершённая работа без новых запросов RPC не делает. Client p95 достигает 3556.4 ms: server budget не означает end-to-end browser latency ≤500 ms; client timings сохранены отдельно.
  • Frontend: existing stories independent summary freshness/source failure; фоновые warnings используют polite status announcements. Chrome/Playwright 56 app checks, 9 Storybook viewport checks: 320/375/1440, длинные суммы, account/all, ledger, income, events, stock/bond, complete/partial/stale/failed/ missing, refresh, leave/reopen, connection replacement, keyboard/focus, skeleton/busy и reduced motion; JS errors 0. Synthetic API fixtures, без реальных credentials. Проверка resize ждёт завершения responsive chart layout; первоначальный transient overflow воспроизводился до перерасчёта, после него отсутствует. CSS workaround не добавлялся. Evidence текущего запуска: /tmp/wealthledger-browser-evidence.json, /tmp/wealthledger-ui-final3.log, /tmp/wealthledger-stories-check.log, screenshots /tmp/wl-*.png.
  • Backend: npm ci, npm run verify (37 suites / 192 tests), npm run test:openapi-contract, npm run openapi:generate passed. SQLite/HTTP candles/catalog/discovery/events/income/local reads/screen-sync: 86 checks passed; durability/rollback повторно passed на disposable DB, result wealthledger-bank-durability-kWQOEX. Рабочая БД не использовалась. Финальный backend OpenAPI побайтово равен явно переданному frontend snapshot.
  • Frontend: npm ci, npm run verify (53 suites / 306 tests), включая local OpenAPI drift, type/lint/coverage/Knip/dependencies, production и Storybook builds passed. Крупные chunks остаются build warnings.
  • Docs обновляет storage/access/freshness, flows accounts/operations/portfolio/ income/instruments, HTTP handoff и glossary; ADR 017 сохраняет историческое решение и отмечает проверенную реализацию в рабочих ветках, не production deployment. README routes к темам/терминам/API сохранены. Полный отдельный semantic/diagram gate 7.4 остаётся открытым.
  • Specs npm ci успешно повторён без изменения dependencies после прежнего registry 502. Diff/owner/callers review выполнен; чужие active changes и staged/unstaged изменения сохранены. Итоговая requirement-by-requirement сверка 7.5 остаётся открытой. Реализация целиком завершённой не объявляется; archive/main-spec sync и deployment не выполнялись.
  • Финальные npm run verify docs (46 Markdown files, 0 issues) и specs passed; strict native validation change с explicit store passed. Native apply подтверждает 25 completed / 2 remaining. Эти проверки не заменяют 7.4/7.5.
  • Следующий Implementation outcome: 7.4 — финальная semantic/link/diagram проверка docs, затем 7.5 — все 35 delta requirements и native final gates.

Checkpoint — final semantic and requirement verification, 2026-09-26

  • Завершены 7.4–7.5, итог 27/27 implementation-owned tasks. Сверены все 35 delta requirement headings, включая REMOVED; таблица ниже связывает каждый heading с задачами и наблюдаемыми проверками.
  • Semantic review обнаружил и устранил пропуски frontend: список счетов и его skeleton теперь одноколоночные согласно delta requirement; аналитика показывает previous comparison через существующий компонент отдельно от yearAgo. Для каждого сравнения различаются incomplete, source failure и недоступность годового сравнения по календарю/истории; null не становится нулевой базой. Financial Money приходит с сервера, новые calculations/API поля не добавлялись.
  • Frontend npm ci, targeted income (41 tests) и npm run verify (53 suites / 307 tests) passed: local OpenAPI drift, type/lint/coverage, Knip/dependency checks, production и Storybook builds. Финальный browser run: 56 app cases, 9 Storybook viewport checks, затем 14 focused income checks, включая видимость обоих сравнений на 320/375/1440 px; JS errors 0. Storybook проверяет расположение второй account card ниже первой на каждой ширине. Evidence: /tmp/wealthledger-frontend-verify27.log, /tmp/wealthledger-ui27.log, /tmp/wealthledger-stories27.log, /tmp/wealthledger-income-browser27.log, screenshots /tmp/wl-previous-*.png.
  • Docs: пройдены маршруты README → architecture/flows → glossary/HTTP API. Убраны оставшиеся утверждения о временном portfolio, потере snapshots после restart, отсутствии force action и совместимости старого клиента с envelope. Уточнены local filtering, private portfolio/shared calendars, предыдущий период дохода и уже согласованный applied period событий. Исторические ADR сохранены; отдельные прежние ограничения CURRENCY-card и налогового смысла dividend_net не скрыты и не объявлены исправленными этим change.
  • Уточнение evidence MOEX: успешный отсутствующий block даёт [] по существующему MoexClient и его unit test treats a successful response without the requested block as no events. Название старого e2e case про missing block моделирует rejected adapter promise, то есть source failure; оно не доказывает отказ реального adapter при отсутствующем block. Поведение adapter не менялось и соответствует delta scenario; повреждённый block/transport error — иной случай.
  • Docs npm run verify: 46 Markdown files, 0 issues, relative links/anchors и diff passed. Изменённый label в существующей Mermaid sequence проверен по PUT transaction flow и синтаксису; доступного локального Mermaid renderer нет, отрисовка диаграммы не проверена. Это явно допустимое ограничение 7.4; Markdown gate не выдаётся за render proof. Нового renderer/dependency нет.
  • Backend production/tests не менялись в этом checkpoint; результаты 7.2, SQLite/crash/durability/rollback и versioned performance fixture актуальны. Backend OpenAPI и frontend snapshot по-прежнему побайтово равны. Серверный максимум p95 382.6 ms в профиле Design, client p95 до 3556.4 ms; synthetic RPC boundary 42913 → 0. Реальный broker network/production rollout этим не измерены. Рабочая пользовательская БД не использовалась.
  • Native gates: openspec schema validate wealth-ledger-sdd --verbose, openspec validate persist-tbank-data --type change --strict --store wealth-ledger-specs, openspec validate --specs --strict --store wealth-ledger-specs passed (25 main specs / 0 failed); npm run verify specs и final diff checks passed. Long requirement INFO не является validation failure. Проверены staged, unstaged и новые файлы; root/dependencies/main specs/чужие changes сохранены.
  • Implementation-owned work завершена. Independent review перед archive, archive/main-spec sync, commits/push и deployment этим checkpoint не выполняются.

Requirement evidence index

Здесь B — backend, F — frontend; пути служат адресами evidence, не входами CI соседнего repo. Результаты запусков приведены в checkpoint соответствующих задач.

  • B-access: test/tbank-connection.e2e-spec.ts, test/tbank-local-reads.e2e-spec.ts.
  • B-ops: test/tbank-operations-persistence.e2e-spec.ts, test/tbank-operations-sync.e2e-spec.ts (включая SIGKILL и concurrent reader).
  • B-ledger: test/tbank-ledger-local.e2e-spec.ts.
  • B-income: test/tbank-income-local.e2e-spec.ts, income period/analytics unit tests.
  • B-catalog: test/tbank-catalog-local.e2e-spec.ts, test/tbank-catalog-discovery.e2e-spec.ts.
  • B-candles: test/tbank-candles-persistence.e2e-spec.ts, candle coverage unit tests.
  • B-events: test/upcoming-events.e2e-spec.ts, src/integrations/moex/moex.client.spec.ts.
  • B-sync: test/tbank-screen-sync.e2e-spec.ts.
  • B-perf: test/tbank-read-baseline.e2e-spec.ts, test/fixtures/tbank-read-persistent.json.
  • F-accounts: AccountsPage.test.tsx, BrokerageAccountList.test.tsx и viewport stories.
  • F-overview: AccountPage.test.tsx, AccountPage.vm.test.tsx, AllAccounts.test.tsx.
  • F-ledger: AccountOperationsPage.test.tsx, filters tests и instrument page tests.
  • F-income: AccountIncomePage.test.tsx, filters tests; browser comparisons.
  • F-events: AccountEventsPage.test.tsx, filters tests, BrokerageEventsPreview consumers.
  • F-boundary: src/shared/api/client.test.ts, authenticated query tests, src/features/tbank-connection/model/screen-sync.test.tsx, sync.test.tsx.
  • UI: browser/reduced-motion/keyboard/state checks 6.3 и final checkpoint выше.
Capability / requirement Tasks Evidence
brokerage-account-income-analytics — Realized income analytics is account-scoped and period-bound 3.3, 5.3 B-income, F-income
brokerage-account-income-analytics — Period comparisons preserve calendar and currency meaning 3.3, 5.3 B-income, F-income; independent previous/year states
brokerage-account-income-analytics — Realized analytics never presents an incomplete result as complete 2.1, 3.3, 5.3 B-ops, B-income, F-income
brokerage-account-income-analytics — Account overview has an independent current-month income summary 3.3, 5.2 B-income, F-overview
brokerage-account-income-analytics — Income payments remain traceable to exact Ledger Entries 2.1, 3.3, 5.3 B-ops, B-income, F-income; exact signed entries
brokerage-account-ledger — User can retrieve an account ledger 3.2, 5.3 B-access, B-ledger, F-ledger
brokerage-account-ledger — User can browse a filtered ledger 3.2, 5.3 B-ledger; revision-bound cursor and recovery
brokerage-account-ledger — Ledger entries preserve broker operation meaning 2.1, 3.2 B-ops, B-ledger; exact money and identity
brokerage-account-ledger — Account overview includes recent ledger events 3.2, 5.2 B-ledger, F-overview
brokerage-account-ledger — Кэш страниц журнала ограничивает локальные ресурсы 2.1, 3.2 REMOVED: B-ledger reopen/no RPC; persistent row cursor replaces RAM page TTL
brokerage-account-upcoming-events — User can retrieve upcoming events for an account 3.6, 5.3 B-events, F-events
brokerage-account-upcoming-events — Forecasts preserve event meaning and uncertainty 3.6 B-events; decimal, cancelled, registry, null offer
brokerage-account-upcoming-events — Upcoming events use complete source results 3.6 B-events; fallback/reopen/new dependency failure, MOEX adapter semantics
brokerage-account-upcoming-events — Account page presents an upcoming events list 5.3, 6.3 F-events, UI
brokerage-account-upcoming-events — Account overview includes upcoming events 5.2 F-overview, B-events
brokerage-accounts — Список активных брокерских счетов 1.3, 3.1 B-access; order/empty/independent summaries
brokerage-accounts — Состояния недоступности списка счетов 1.3, 3.1 B-access; known invalid/failed replacement/observe
brokerage-accounts — Экран списка брокерских счетов 5.2, 6.3 F-accounts, UI; final single-column geometry
brokerage-accounts — Клиентские состояния ошибки списка счетов 4.3, 5.2 F-accounts, F-boundary
frontend-data-resilience — Client Cached Snapshot остаётся доступным при обновлении Accounts и Portfolio 4.3, 5.1–5.4, 6.3 F-boundary, F-accounts, F-overview, F-income, F-events, UI
portfolio-view — Получение Portfolio выбранного Brokerage Account 3.1 B-access; blocked upstream/reopen/local membership
portfolio-view — Свежесть и fallback полного Portfolio Snapshot 3.1 B-access; stale >5min/metadata overlay/late revision fence
portfolio-view — Состояния и ошибки Portfolio на клиенте 5.1–5.2, 6.3 F-overview, F-boundary, UI
tbank-data-sync — Все экраны читают сохранённые данные без ожидания T-Bank 1.2, 3.1–3.6, 6.2 B-access, B-ledger, B-income, B-catalog, B-candles, B-events, B-perf
tbank-data-sync — Обновление запускается только запросом с учётом свежести 2.2–2.3, 3.1–3.6 B-ops, B-access, B-catalog, B-candles; TTL/observe/no startup work
tbank-data-sync — Ручное обновление ограничено текущим экраном 4.1, 5.1–5.4 B-sync, F-boundary, F-ledger, F-income, UI
tbank-data-sync — Первая загрузка приоритизирует экран и продолжает историю 2.3, 3.5 B-ops priority/replay/unknown floor; B-candles prefetch
tbank-data-sync — Полнота подтверждается успешным покрытием интервалов 2.1–2.3, 3.2–3.3 B-ops, B-ledger, B-income; pages ≠ completeness
tbank-data-sync — Сверка операций сохраняет идентичность и прежний результат 2.1, 6.1 B-ops; atomic quarter/all publish and separate reader
tbank-data-sync — Прогресс переживает перезапуск и одновременные запросы 2.2, 6.1 B-ops, B-candles, B-catalog; SIGKILL/reopen/coalescing/fences
tbank-data-sync — Общие данные инструментов отделены от личных 1.2, 3.4–3.6 B-catalog, B-events; two users/shared sources/private forecasts
tbank-data-sync — Локальная проверка доступа сохраняет границу подключения 1.3, 4.3 B-access, B-sync, F-boundary
tbank-data-sync — Завершённость свечей подтверждается источником 3.5 B-candles; incomplete prior day/current empty/closed gaps/failed force
tbank-data-sync — Интерфейс различает свежесть полноту и состояние работы 4.1–4.3, 5.1–5.4, 6.3 B-sync, F-boundary, F-income, UI
tbank-data-sync — Быстродействие и сокращение запросов проверяются измерениями 6.2 B-perf; 23×100, 10 clients, server p95, 20-way stale coalescing

Checkpoint — feature commit verification, 2026-09-26

  • Implementation-owned status remains 27/27; archive/main-spec synchronization and release preparation remain deferred by the Change Owner.
  • Fixed journal regressions after implementation: a current-day or paginated moving period preserves confirmed completeness; the moving requested end no longer changes stateVersion between unchanged status/observe reads. Actual coverage changes still change the version. Disposable SQLite regressions prove these outcomes without additional operations RPC.
  • Fresh npm ci completed in all four affected repositories. Docs required a retry with network access after the configured Nexus host returned ENOTFOUND; dependencies and lockfiles were not changed.
  • Backend npm run verify passed: 37 suites / 193 unit tests, lint, both typechecks and build. Frontend npm run verify passed: 53 suites / 307 tests, OpenAPI/type/lint/dependency gates, production and Storybook builds. Generated backend OpenAPI remains byte-identical to the explicitly supplied frontend snapshot. Docs verify: 46 files / 0 issues. Native schema/change/main-spec validation passed; apply reports 27 complete / 0 remaining.
  • Full backend npm run test:e2e passed in disposable Linux Docker: 21 suites / 226 tests, including runtime OpenAPI, migrations, financial integrity, crash/restart, concurrency and the persisted read budget. Current tracked source was copied into the existing development image; dependency lock contents match exactly after excluding only root package version. Node 24.21.0, 4 CPU / 8 GiB, no network, no host data volumes.
  • This repeat of the Design profile measured 2300 warm reads, maximum server p95 215.7 ms, synthetic RPC 42913 → 0. The original versioned measurement remains in test/fixtures/tbank-read-persistent.json; the repeat is recorded in /tmp/wealthledger-feature-linux-e2e-final.log and /tmp/wealthledger-feature-budget.json. This is not a real-broker or production latency measurement and does not establish a 500 ms browser response budget.
  • Host macOS full HTTP verification is not green: two attempts aborted in the native better-sqlite3 statement cleanup with Node RemoveEnvironmentCleanupHook. The same authentication suite and the complete HTTP gate passed in Linux; no dependency workaround or application change was introduced for the host failure. Earlier rollback/durability and browser evidence remains applicable; Mermaid rendering remains unverified as recorded in the preceding checkpoint.
  • Staged secret scans and whitespace checks passed. Three known public income/yearAgo resource identifiers have narrowly scoped Gitleaks comments; a false positive in the Design delivery-map terminology was reworded without changing its meaning. No credentials, working database, local backups or unrelated active changes enter the feature commits.