Skip to content

feat(api,db): add forecast champion selector backend (#353)#354

Merged
w7-mgfcode merged 3 commits into
devfrom
feat/forecast-champion-selector-backend
Jun 1, 2026
Merged

feat(api,db): add forecast champion selector backend (#353)#354
w7-mgfcode merged 3 commits into
devfrom
feat/forecast-champion-selector-backend

Conversation

@w7-mgfcode
Copy link
Copy Markdown
Owner

Summary

Backend-only Forecast Champion Selector — a new model_selection vertical slice (issue #353) that, for one (store, product) pair, validates data availability, runs comparable backtests for a set of candidate models, deterministically ranks them, selects a champion with a recommendation confidence, persists an auditable run, and optionally trains/predicts with the winner. Creates the stable backend contract a future UI PRP will consume. No UI, no agent surface, no cloud SDK (by design).

Endpoints (all under /model-selection)

  • GET /availability — coverage, demand, promotion days, recommended split config, ready|limited|unusable
  • POST /run — availability gate → candidate backtests → ranking → optional train/predict → persisted run (200)
  • GET /{selection_id} — fetch a persisted run
  • GET /{selection_id}/ranking — just the ranking block
  • POST /{selection_id}/train-winner — train the champion
  • POST /{selection_id}/predict — forecast with the trained champion

Implementation notes

  • New model_selection_run table (JSONB audit snapshots + 6 indexes); migration b667d321603c chains to head c1d2e3f40512, downgrade drops indexes then table, alembic check shows no drift.
  • Calls the direct BacktestingService / ForecastingService (full ModelConfig union + fold-level chart data); sibling services imported lazily, data-platform ORM read at module scope (OpsService precedent).
  • Pure, unit-tested ranking.py (deterministic (wape, smape, abs(bias), mae, model_type) tie-break) + explanations.py (deterministic business summary — no LLM).
  • All 7 LOCKED decisions implemented: 200 sync, unusable→400 fail-fast, all-fail→persist failed+200, include_baselines=False+store_fold_details=True, horizon match, deterministic ranking, auto_predict⇒auto_train_winner.
  • Two JSONB columns added beyond the original blueprint (candidate_results, chart_data) so GET rebuilds the same fold-level chart_data that /run returns.

Validation

  • ✅ ruff check + format clean; mypy/pyright 0 errors in new code (pre-existing lightgbm/xgboost import noise only; CI installs the extras)
  • test_strict_mode_policy.py green
  • ✅ 44 unit tests + 7 integration tests (real Postgres) pass; migration upgrade/downgrade round-trips
  • ✅ full repo unit suite: 1743 passed

Closes #353

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 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: d58f79bd-adb7-44ce-a812-a4874e42725c

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/forecast-champion-selector-backend

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.

Copy link
Copy Markdown
Contributor

@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, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@w7-mgfcode w7-mgfcode merged commit 6c3f8d4 into dev Jun 1, 2026
8 of 9 checks passed
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