Hourly pass перечитывает сохранённые календари выплат (dividends, bond-events) один раз за проход. Остальные источники и обычный GET не затронуты.
Linked Issue
Refs WealthLedger/backend#53 (audit 2026-10-11: BE-003, BE-014). Зависит от #55 (смержен, 169bee1).
Changes
sourcePolicy: kinds dividends и bond-events получили policy calendar (раньше stable).
CatalogEnrichmentService.readMany/requestMany принимают необязательный refreshBefore. Календарь перечитывается, только если fetchedAt < refreshBefore. Без параметра поведение прежнее (GET, bond/stock income и т.д.).
UpcomingEventsService.refresh принимает walkStartedAt; TbankHourlyScheduler.dispatchEvents передаёт метку начала обхода (как уже делает portfolio). Второй счёт с тем же UID видит свежий fetchedAt и не грузит календарь повторно.
Detail/metadata/quotes/history не форсируются. Failed refresh не перезаписывает строку, поэтому предыдущий полный календарь и forecast сохраняются (граница из #55).
MOEX: по решению владельца missing/malformed/cursor остаются MOEX_UNAVAILABLE (conservative failure). moex.client.ts и его spec не менялись.
Нет миграции, схема БД не менялась, новых слоёв нет.
Verification
test/upcoming-events.e2e-spec.ts (SQLite HTTP, реальный путь refresh→readMany→requestMany, без stub планировщика): 4 новых теста падали на старом коде, 30/30 проходят после фикса. Проверяют: изменённая и отменённая выплата того же окна обновляют dataRevision/события; failed refresh сохраняет строку, lastSuccessfulAt, forecast и виден как failure; два счёта с одним UID дают одну загрузку за проход; GET и обычный refresh без метки RPC не делают, detail не перечитывается; bond-календарь с постоянным ключом перечитывается только в проходе.
npm run verify: 42 suites / 310 tests, lint, typecheck, build — OK.
npm run test:e2e (все SQLite-suites): exit 0. npm run openapi:check: OK.
Не проверено: реальные T-Bank/MOEX (live запрещены), PostgreSQL, нагрузка одного часового прохода на MOEX. Конкретное поведение MOEX на missing-блок не проверялось.
Breaking Changes (если есть)
Нет. Публичный API/OpenAPI не менялся.
## Summary
Hourly pass перечитывает сохранённые календари выплат (`dividends`, `bond-events`) один раз за проход. Остальные источники и обычный GET не затронуты.
## Linked Issue
Refs WealthLedger/backend#53 (audit 2026-10-11: BE-003, BE-014). Зависит от #55 (смержен, `169bee1`).
## Changes
- `sourcePolicy`: kinds `dividends` и `bond-events` получили policy `calendar` (раньше `stable`).
- `CatalogEnrichmentService.readMany/requestMany` принимают необязательный `refreshBefore`. Календарь перечитывается, только если `fetchedAt < refreshBefore`. Без параметра поведение прежнее (GET, bond/stock income и т.д.).
- `UpcomingEventsService.refresh` принимает `walkStartedAt`; `TbankHourlyScheduler.dispatchEvents` передаёт метку начала обхода (как уже делает portfolio). Второй счёт с тем же UID видит свежий `fetchedAt` и не грузит календарь повторно.
- Detail/metadata/quotes/history не форсируются. Failed refresh не перезаписывает строку, поэтому предыдущий полный календарь и forecast сохраняются (граница из #55).
- MOEX: по решению владельца missing/malformed/cursor остаются `MOEX_UNAVAILABLE` (conservative failure). `moex.client.ts` и его spec не менялись.
- Нет миграции, схема БД не менялась, новых слоёв нет.
## Verification
- `test/upcoming-events.e2e-spec.ts` (SQLite HTTP, реальный путь refresh→readMany→requestMany, без stub планировщика): 4 новых теста падали на старом коде, 30/30 проходят после фикса. Проверяют: изменённая и отменённая выплата того же окна обновляют `dataRevision`/события; failed refresh сохраняет строку, `lastSuccessfulAt`, forecast и виден как failure; два счёта с одним UID дают одну загрузку за проход; GET и обычный refresh без метки RPC не делают, detail не перечитывается; bond-календарь с постоянным ключом перечитывается только в проходе.
- `npm run verify`: 42 suites / 310 tests, lint, typecheck, build — OK.
- `npm run test:e2e` (все SQLite-suites): exit 0. `npm run openapi:check`: OK.
- Не проверено: реальные T-Bank/MOEX (live запрещены), PostgreSQL, нагрузка одного часового прохода на MOEX. Конкретное поведение MOEX на missing-блок не проверялось.
## Breaking Changes (если есть)
Нет. Публичный API/OpenAPI не менялся.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Hourly pass перечитывает сохранённые календари выплат (
dividends,bond-events) один раз за проход. Остальные источники и обычный GET не затронуты.Linked Issue
Refs WealthLedger/backend#53 (audit 2026-10-11: BE-003, BE-014). Зависит от #55 (смержен,
169bee1).Changes
sourcePolicy: kindsdividendsиbond-eventsполучили policycalendar(раньшеstable).CatalogEnrichmentService.readMany/requestManyпринимают необязательныйrefreshBefore. Календарь перечитывается, только еслиfetchedAt < refreshBefore. Без параметра поведение прежнее (GET, bond/stock income и т.д.).UpcomingEventsService.refreshпринимаетwalkStartedAt;TbankHourlyScheduler.dispatchEventsпередаёт метку начала обхода (как уже делает portfolio). Второй счёт с тем же UID видит свежийfetchedAtи не грузит календарь повторно.MOEX_UNAVAILABLE(conservative failure).moex.client.tsи его spec не менялись.Verification
test/upcoming-events.e2e-spec.ts(SQLite HTTP, реальный путь refresh→readMany→requestMany, без stub планировщика): 4 новых теста падали на старом коде, 30/30 проходят после фикса. Проверяют: изменённая и отменённая выплата того же окна обновляютdataRevision/события; failed refresh сохраняет строку,lastSuccessfulAt, forecast и виден как failure; два счёта с одним UID дают одну загрузку за проход; GET и обычный refresh без метки RPC не делают, detail не перечитывается; bond-календарь с постоянным ключом перечитывается только в проходе.npm run verify: 42 suites / 310 tests, lint, typecheck, build — OK.npm run test:e2e(все SQLite-suites): exit 0.npm run openapi:check: OK.Breaking Changes (если есть)
Нет. Публичный API/OpenAPI не менялся.