Skip to content

feat: Scenario Simulation / What-If Planning (MVP) — new scenarios slice (#221)#222

Merged
w7-mgfcode merged 5 commits into
devfrom
feat/scenarios-what-if-planning
May 19, 2026
Merged

feat: Scenario Simulation / What-If Planning (MVP) — new scenarios slice (#221)#222
w7-mgfcode merged 5 commits into
devfrom
feat/scenarios-what-if-planning

Conversation

@w7-mgfcode
Copy link
Copy Markdown
Owner

Summary

Promotes the MVP of docs/optional-features/03-scenario-simulation-what-if-planning.md (PRP-26) into code: a new app/features/scenarios/ vertical slice plus a Visualize → What-If Planner page. 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 named scenario_plan rows.

Closes #221.

What's in it

Backend — scenarios slice

  • adjustments.py — pure, dependency-free deterministic factor engine (never raises on junk input)
  • schemas.py / models.py (ScenarioPlan) / service.py / routes.py
  • Alembic migration 43e35957a248_create_scenario_plan_table.py (down_revision = verified head 378c112e4b32)
  • 5 endpoints: 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, pure lib/scenario-utils.ts (+ vitest), Scenario* types, route + nav entry

⚠️ Design decisions to flag (per product-vision.md § "When Ideas Don't Align")

  1. Results are heuristic, deliberately labelled — not model-causal. The baseline forecasters ignore the exogenous X argument, so a what-if cannot be answered by re-prediction. The MVP applies a deterministic post-forecast multiplier; every result carries method = "heuristic" and a fixed disclaimer, 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.
  2. The scenario service does NOT import a sibling slice's service.py. It imports only the stable lower-level building block load_model_bundle from forecasting/persistence.py and replicates the ~30-line ForecastPoint-construction block — calling ForecastingService would violate the no-cross-slice-service-import rule (AGENTS.md § Architecture). Read-only ORM imports of data_platform.models are allowed.

Product-vision Litmus test

  1. Which slice? A new scenarios vertical slice — app/features/scenarios/{models,schemas,adjustments,service,routes,tests}.py.
  2. PRP? Yes — PRPs/PRP-26-scenario-simulation-what-if-planning.md.
  3. Time-safety preserved? Yes — the adjustment touches only horizon (future) points; app/features/scenarios/tests/test_leakage.py is a load-bearing spec asserting it.
  4. Migration shipped? Yes — 43e35957a248, upgrades and downgrades cleanly on a fresh DB.
  5. Works on a laptop via docker compose up? Yes — no new dependency, no managed-cloud SDK, no WebSocket.
  6. Passes the gates? Yes — see below.

Validation

  • ruff + mypy --strict + pyright --strict — clean
  • pytest -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 — clean
  • Frontend tsc --noEmit + lint + test — clean, 94 tests pass
  • Dogfooded /visualize/planner in 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

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @w7-mgfcode, your pull request is larger than the review limit of 150000 diff characters

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2fdcceed-4c05-46d4-bc13-3e317050a998

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/scenarios-what-if-planning

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@w7-mgfcode w7-mgfcode merged commit 9a5f8c1 into dev May 19, 2026
10 checks passed
@w7-mgfcode w7-mgfcode deleted the feat/scenarios-what-if-planning branch May 20, 2026 03:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant