Slice 1 of the #1157 build. The FE creates a Scenario and passes only
its id to the pipeline; the Modelling stage reads it back here.
- domain/modelling/scenario.py: thin `Scenario(id, goal, goal_value,
budget, is_default)` — the slice the stage uses today (goal/budget for
the Optimiser later; is_default drives plan.is_default). No phases
(ADR-0005); legacy file-path/aggregate columns not modelled.
- infrastructure/postgres/scenario_table.py: `ScenarioRow` SQLModel
mirror of the live `scenario` table (ADR-0017), declaring only the
read columns; goal mapped as its string value.
- ScenarioPostgresRepository.get_many(scenario_ids) -> list[Scenario]:
bulk read, input-order-preserving, raises on a missing id.
The method shape lives on the concrete repo for now; it is promoted to
an @abstractmethod on the port when the real orchestrator is wired and
the bare-stub instantiations retire (keeps the stubbed Modelling wiring
composing meanwhile). 2 tests, pyright strict clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>