feat: Scenario Simulation / What-If Planning (MVP) — new scenarios slice (#221)#222
Conversation
There was a problem hiding this comment.
Sorry @w7-mgfcode, your pull request is larger than the review limit of 150000 diff characters
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Promotes the MVP of
docs/optional-features/03-scenario-simulation-what-if-planning.md(PRP-26) into code: a newapp/features/scenarios/vertical slice plus aVisualize → What-If Plannerpage. Turns ForecastLabAI from "predict the future" into "plan possible futures" — it loads an already-trained baseline model, runs its forecast, applies deterministic, transparent uplift/drag factors for future assumptions (price, promotion, holiday, inventory, lifecycle), and returns a baseline-vs-scenario comparison. Comparisons save as namedscenario_planrows.Closes #221.
What's in it
Backend —
scenariossliceadjustments.py— pure, dependency-free deterministic factor engine (never raises on junk input)schemas.py/models.py(ScenarioPlan) /service.py/routes.py43e35957a248_create_scenario_plan_table.py(down_revision= verified head378c112e4b32)POST /scenarios/simulate,POST /scenarios,GET /scenarios,GET /scenarios/{id},DELETE /scenarios/{id}Frontend — What-If Planner
pages/visualize/planner.tsx,hooks/use-scenarios.ts, purelib/scenario-utils.ts(+ vitest),Scenario*types, route + nav entryproduct-vision.md§ "When Ideas Don't Align")Xargument, so a what-if cannot be answered by re-prediction. The MVP applies a deterministic post-forecast multiplier; every result carriesmethod = "heuristic"and a fixeddisclaimer, and the page shows a prominent disclaimer banner (a NIST-AI-RMF transparency control). The "Full Version" (exogenous-regressor models, future-feature-frame generator, agent-generated scenarios) is out of scope.service.py. It imports only the stable lower-level building blockload_model_bundlefromforecasting/persistence.pyand replicates the ~30-lineForecastPoint-construction block — callingForecastingServicewould violate the no-cross-slice-service-import rule (AGENTS.md§ Architecture). Read-only ORM imports ofdata_platform.modelsare allowed.Product-vision Litmus test
scenariosvertical slice —app/features/scenarios/{models,schemas,adjustments,service,routes,tests}.py.PRPs/PRP-26-scenario-simulation-what-if-planning.md.app/features/scenarios/tests/test_leakage.pyis a load-bearing spec asserting it.43e35957a248, upgrades and downgrades cleanly on a fresh DB.docker compose up? Yes — no new dependency, no managed-cloud SDK, no WebSocket.Validation
ruff+mypy --strict+pyright --strict— cleanpytest -m "not integration"— 1195 passed (incl. the leakage spec and the strict-mode-policy linter, which now covers the scenario request models)pytest -m integration— 9 passed (real Postgres)alembic upgrade head → downgrade -1 → upgrade head— cleantsc --noEmit+lint+test— clean, 94 tests pass/visualize/plannerin a real browser — disclaimer banner, KPI tiles, baseline-vs-scenario chart, per-day delta table, save/reload/delete — 0 console errors🤖 Generated with Claude Code