gendesign/backend
Light1YT 8206a0b067
All checks were successful
Deploy / changes (push) Successful in 6s
Deploy / build-backend (push) Successful in 1m49s
Deploy / build-frontend (push) Has been skipped
Deploy / build-worker (push) Successful in 2m45s
Deploy / deploy (push) Successful in 1m10s
perf(forecast): per-request memoization cache for §22 cold build (#1129)
Cold §22 forecast measured ~215-233s on prod: §9.x layers re-execute the same
horizon/segment-invariant DB loads with identical args hundreds of times per
report (profiled: get_competitors x69, market_metrics x124, get_monthly_macro
x290). Add a per-report ContextVar cache (forecast_cache(), opened once in the
orchestrator) + @cached(key_builder) on the expensive §9.x loaders so each
unique load runs ONCE and reuses the same frozen, read-only instance.

Output is byte-identical (memoized producers are frozen dataclasses / read-only
Pydantic, callers never mutate; cache is per-report, discarded on exit; no-op
outside the report build). No concurrency, no signature changes.

- forecast_request_cache.py: ContextVar cache + cached() decorator (no-op
  outside context, reentrant, _MISS sentinel for cached None)
- @cached on competitors/future_supply/market_metrics/macro_series/
  sales_series/macro_coefficient/demand_normalization/regression loaders
- orchestrator: wrap build_site_finder_report in forecast_cache()
- 58 tests: key discrimination (call-counting regression guard), no-op-outside,
  per-report isolation, reentrancy, frozen-producer canary, amplification proof
  (real get_monthly_macro xN->1)

code-reviewer APPROVE (keys correct, mutation-safe, output identical). 1265
forecast/cache tests green. No new deps. Refs #1129.
2026-06-08 05:26:27 +00:00
..
alembic ops: alembic baseline, pre-commit, TIGER cleanup, pg_dump scripts 2026-04-26 13:08:51 +03:00
app perf(forecast): per-request memoization cache for §22 cold build (#1129) 2026-06-08 05:26:27 +00:00
db/init ops: alembic baseline, pre-commit, TIGER cleanup, pg_dump scripts 2026-04-26 13:08:51 +03:00
output feat(geo): NSPD bulk-fetcher без Playwright + resume-friendly UI 2026-05-11 08:53:28 +03:00
scripts fix(backtest): add binomial significance gate to §9.6 verdict 2026-06-04 16:42:45 +05:00
tests perf(forecast): per-request memoization cache for §22 cold build (#1129) 2026-06-08 05:26:27 +00:00
.dockerignore fix(scraper): диагностируем «кнопка не работает» — Redis lock + task_received log 2026-04-28 23:17:42 +03:00
.env.example refactor(security): убрать X-Admin-Token (Caddy basic_auth достаточен) (#437) 2026-05-23 10:41:22 +00:00
.env.runtime.example sprint1: nspd scraper industrialization, per-bucket elasticity, cadastre cross-check, sentry releases 2026-04-30 21:51:19 +03:00
alembic.ini ops: alembic baseline, pre-commit, TIGER cleanup, pg_dump scripts 2026-04-26 13:08:51 +03:00
debug.log feat(geo): NSPD bulk-fetcher без Playwright + resume-friendly UI 2026-05-11 08:53:28 +03:00
Dockerfile feat(sf): OCR-пайплайн изъятия ЕКБ (Tesseract rus) → land_reservation (#1062) 2026-06-07 18:07:06 +03:00
pyproject.toml feat(sf): OCR-пайплайн изъятия ЕКБ (Tesseract rus) → land_reservation (#1062) 2026-06-07 18:07:06 +03:00
uv.lock feat(sf): OCR-пайплайн изъятия ЕКБ (Tesseract rus) → land_reservation (#1062) 2026-06-07 18:07:06 +03:00