[Bug] Ограничить Income/Ledger GET разрешённой локальной read boundary #57

Closed
opened 2026-10-11 21:43:36 +03:00 by codex-bot · 2 comments
Owner

Problem

Обычный collectRanges запускает membership и readPlan(history=true). Ledger также добавляет missing lifetime history вне target. Date→screen planner→interval round-trip скрывает уже вычисленный range. Это конкурирующий initiator, не проблема отсутствующих слоёв.

Expected Behavior

Income GET читает local operations; Ledger впервые получает только missing requested intervals. Неполная история не выдаётся за zero/full Income.

Evidence

Audit date: 2026-10-11. 01, 02, 07. IDs: ARCH-002, CPLX-002, CPLX-006, BE-004, FLOW-001, TA-F06. Revision: 0ad84ff4f0b4712abc7e69dc299856f14af6eadd; Confidence High; Verification status static.
Affected code: brokerage-operations.service.ts:120–151, :391–435; brokerage-operations-sync.service.ts:46–126; income-analytics.controller.ts:24–79.

Scope

In scope

Оба production readPlan callers, cold historical Income decision, existing operationIntervals reuse.

Out of scope

Удаление coverage/staging/cursor/auth fences, hourly mutable-tail refresh, новый IncomeSyncService или скрытый full-history replacement.

Proposed Approach

Убрать membership/scheduling из ordinary Income; shared read planner не расширяет targets на accountHistory. Использовать уже вычисленный [from,to) и existing normalizer. Перед удалением cold-load пути явно согласовать recovery/UX: разрешённый Ledger owner либо approved narrow exception, без собственной догадки.

Acceptance Criteria

  • Default Income GET без observe не создаёт membership/operations work и RPC.
  • Complete January + missing December не вызывает December import из January Ledger; missing January импортирует только gaps January.
  • Inclusive HTTP end/subsecond cursor/all/unknown membership дают прежние bounded unfiltered source intervals.
  • Selected/previous/year Income completeness честна; unknown не превращается в ноль.
  • Cold-history decision записано в existing owner requirement, если меняется контракт; общий planner не удалён целиком.

Verification

Existing tbank-ledger-local/tbank-income-local SQLite HTTP suites; assertions actual requested intervals, default GET, cursor prevalidation и confirmed local reuse. Backend verify конечного diff.

Dependencies

Нет обязательных Issues; cold-history решение — named blocker внутри задачи. P1 fixes могут выполняться параллельно.

Traceability

Campaign WealthLedger/main#23 . Findings: ARCH-002, CPLX-002, CPLX-006, BE-004, FLOW-001, TA-F06. Repository WealthLedger/backend; T05.

<!-- wealthledger-audit:2026-10-11:income-ledger-ownership --> ## Problem Обычный collectRanges запускает membership и readPlan(history=true). Ledger также добавляет missing lifetime history вне target. Date→screen planner→interval round-trip скрывает уже вычисленный range. Это конкурирующий initiator, не проблема отсутствующих слоёв. ## Expected Behavior Income GET читает local operations; Ledger впервые получает только missing requested intervals. Неполная история не выдаётся за zero/full Income. ## Evidence Audit date: `2026-10-11`. [01](https://git.personal.ksv741.ru/WealthLedger/main/src/commit/d07fbfabb1295780952a554185989d2d5b5c8349/audits/2026-10-11/reports/01-architecture-and-module-boundaries-report.md), [02](https://git.personal.ksv741.ru/WealthLedger/main/src/commit/d07fbfabb1295780952a554185989d2d5b5c8349/audits/2026-10-11/reports/02-complexity-and-overengineering-report.md), [07](https://git.personal.ksv741.ru/WealthLedger/main/src/commit/d07fbfabb1295780952a554185989d2d5b5c8349/audits/2026-10-11/reports/07-api-and-data-flow-efficiency-report.md). IDs: ARCH-002, CPLX-002, CPLX-006, BE-004, FLOW-001, TA-F06. Revision: `0ad84ff4f0b4712abc7e69dc299856f14af6eadd`; Confidence High; Verification status static. Affected code: [brokerage-operations.service.ts:120–151](https://git.personal.ksv741.ru/WealthLedger/backend/src/commit/0ad84ff4f0b4712abc7e69dc299856f14af6eadd/src/modules/investments/operations/application/brokerage-operations.service.ts#L120-L151), :391–435; brokerage-operations-sync.service.ts:46–126; income-analytics.controller.ts:24–79. ## Scope ### In scope Оба production readPlan callers, cold historical Income decision, existing operationIntervals reuse. ### Out of scope Удаление coverage/staging/cursor/auth fences, hourly mutable-tail refresh, новый IncomeSyncService или скрытый full-history replacement. ## Proposed Approach Убрать membership/scheduling из ordinary Income; shared read planner не расширяет targets на accountHistory. Использовать уже вычисленный [from,to) и existing normalizer. Перед удалением cold-load пути явно согласовать recovery/UX: разрешённый Ledger owner либо approved narrow exception, без собственной догадки. ## Acceptance Criteria - [ ] Default Income GET без observe не создаёт membership/operations work и RPC. - [ ] Complete January + missing December не вызывает December import из January Ledger; missing January импортирует только gaps January. - [ ] Inclusive HTTP end/subsecond cursor/all/unknown membership дают прежние bounded unfiltered source intervals. - [ ] Selected/previous/year Income completeness честна; unknown не превращается в ноль. - [ ] Cold-history decision записано в existing owner requirement, если меняется контракт; общий planner не удалён целиком. ## Verification Existing tbank-ledger-local/tbank-income-local SQLite HTTP suites; assertions actual requested intervals, default GET, cursor prevalidation и confirmed local reuse. Backend verify конечного diff. ## Dependencies Нет обязательных Issues; cold-history решение — named blocker внутри задачи. P1 fixes могут выполняться параллельно. ## Traceability Campaign https://git.personal.ksv741.ru/WealthLedger/main/issues/23 . Findings: ARCH-002, CPLX-002, CPLX-006, BE-004, FLOW-001, TA-F06. Repository WealthLedger/backend; T05.
codex-bot added this to the Technical Audit Remediation — 2026-10-11 milestone 2026-10-11 21:43:36 +03:00
codex-bot added the Kind/Bug
Priority
Medium
3
audit/2026-10-11
labels 2026-10-11 21:43:36 +03:00
codex-bot was assigned by hermes-agent 2026-10-12 00:04:25 +03:00
hermes-agent added this to the WealthLedger — Delivery Board project 2026-10-12 00:04:25 +03:00
Author
Owner

Решение владельца по cold historical Income: узкое исключение — Income может импортировать только недостающий запрошенный интервал (без membership и без lifetime history аккаунта). Публичный контракт API не меняется.

Решение владельца по cold historical Income: узкое исключение — Income может импортировать только недостающий запрошенный интервал (без membership и без lifetime history аккаунта). Публичный контракт API не меняется.
Author
Owner

Сделано в #147 (squash в develop).

По AC:

  • Income без observe не создаёт membership и lifetime/history work. Для локально покрытого периода нет и RPC. Исключение — холодный период: по решению владельца (комментарий выше) импортируется только недостающий запрошенный интервал. Первый ответ при этом data: null / incomplete, а не ноль.
  • Ledger грузит только недостающие интервалы внутри target; история вне target не запрашивается (было 82 RPC → только target). from >= to → 200 без RPC.
  • Контракт HTTP/OpenAPI не менялся, поэтому отдельная запись в owner requirement не нужна. Общий planner сохранён (accountHistory, ledgerRange), удалён только неиспользуемый planInvestmentScreen.
  • Побочный эффект: historyState у большинства аккаунтов остаётся partial. Плашка UI исправлена в WealthLedger/frontend#124 (PR frontend#125, слит первым).
Сделано в #147 (squash в develop). По AC: - Income без observe не создаёт membership и lifetime/history work. Для локально покрытого периода нет и RPC. Исключение — холодный период: по решению владельца (комментарий выше) импортируется только недостающий запрошенный интервал. Первый ответ при этом `data: null` / `incomplete`, а не ноль. - Ledger грузит только недостающие интервалы внутри target; история вне target не запрашивается (было 82 RPC → только target). `from >= to` → 200 без RPC. - Контракт HTTP/OpenAPI не менялся, поэтому отдельная запись в owner requirement не нужна. Общий planner сохранён (`accountHistory`, `ledgerRange`), удалён только неиспользуемый `planInvestmentScreen`. - Побочный эффект: `historyState` у большинства аккаунтов остаётся `partial`. Плашка UI исправлена в WealthLedger/frontend#124 (PR frontend#125, слит первым).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: WealthLedger/backend#57