Repository navigation
Conversation
…iling)
The Public API's client of the simulation service gains rerun_report,
which posts {"force": …} to POST /reports/{report_id}/runs and reads
each answer the service's re-run route gives.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SimulationServiceReportClient.rerun_report posts {"force": …} to the
simulation service's POST /reports/{report_id}/runs. Its answers are read
in the new policyengine_api.libs.simulation_report_reruns: a started run
naming the report is accepted; a 409 (a run in progress, or a report the
service does not run again) is SimulationServiceConflictError, which the
report routes answer 409; refusals, unavailability and failures follow
the create's rules, with messages that ask the caller to read the report
before running it again. The status and code sets both clients use move
into simulation_service_answers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GET /v2/reports/{report_id}/runs lists an economy report's runs, newest
first, each with its package versions, beside the versions the Public
API runs. POST /v2/reports/{report_id}/runs checks the report's country
and policies, has the simulation service start its new run, with or
without force, and answers the report with that run; a run in progress
answers 409.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
POST /v2/reports/{report_id}/runs?country_id= reads the economy report in
its country, checks the country and the policies its simulations name as
a new report is checked, has the simulation service create and start the
report's new run (body {"force": …}), and answers 201 with the report
and that run read back from the tables. A run in progress, or a report
the service does not run again, answers 409 naming the run; a report that
cannot be read back once its new run started answers 502 with its ID.
GET /v2/reports/{report_id}/runs?country_id= lists the report's runs,
newest first, each with its country package and PolicyEngine.py
versions, beside the versions the Public API runs. Household reports and
budget windows answer 422 on both routes until their own PRs add them.
The migration contract documents gain the two requests, and the
cross-database integration workflow runs the new PostgreSQL tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ns (failing) Review round 1's quality findings: the run routes refuse household reports and budget windows with their own message, rather than the read route's, so the read route's check can change on its own. New tests cover what was untested: no report session is open while the simulation service is asked, the simulation service's refusal is answered as its own, and a report that cannot be read, or an unconfigured service, asks the simulation service nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The run routes refuse household reports and budget windows through their own check, require_economy_report_runs, saying their runs are not started or listed here yet, so the read routes' kind check can change without changing them. - The 409 mapping for SimulationServiceConflictError is removed: the re-run route answers it itself, with run_id. - The re-run's 503 description lists every answer that gives a 503, and its description says why the newest run read back is the new one. - Docstrings that described only creation, or said re-runs should call the policy check, now describe the re-run, and the unavailable error lists a re-run's unreadable 409. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- require_economy_report_runs refuses every kind but the ones the run routes take (RUN_ROUTE_KINDS, economy for now), so a kind added later is refused by default; REPORT_KIND_NAMES names each kind for the message. The behavior is unchanged, so the existing tests cover it. - The database test now stores a household report as well as a budget window, and checks that neither run route lists or starts its runs, answering 422 without asking the simulation service; round 2 found the household refusal tested only through the validator. It passes before the change, since the behavior exists. - Docstrings no longer describe the run routes' kind refusal as the read route's, ReportKindUnsupportedError covers both kinds of route, the client protocol lists a re-run's unreadable 409, and the report service says a re-run also needs the simulation service. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RUN_ROUTE_KINDS is typed as a set of report kinds, so mypy refuses a misspelled one, and a test checks that REPORT_KIND_NAMES names every report kind, so a kind added later is refused with its name (422) rather than failing on a missing key (500). The test passes as is: every kind is named today. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #4298 +/- ##
==========================================
+ Coverage 93.22% 93.35% +0.13%
==========================================
Files 357 363 +6
Lines 20526 21114 +588
Branches 3338 3418 +80
==========================================
+ Hits 19136 19712 +576
- Misses 818 823 +5
- Partials 572 579 +7
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
# Conflicts: # .github/workflows/v2-integration-check.yml # policyengine_api/fastapi_routes/resource_service_protocols.py # policyengine_api/libs/simulation_reports.py # policyengine_api/services/v2/simulation_service/services.py # policyengine_api/services/v2/simulation_service/types.py # policyengine_api/services/v2/stored_reports/services.py # policyengine_api/services/v2/stored_reports/types.py # policyengine_api/services/v2/stored_reports/validators.py # tests/unit/test_alembic_workflows.py
With #4290 merged, the run routes take budget windows too. GET /v2/reports/{report_id}/runs lists a window's budget-window runs, newest first, each with its years, as kind budget_window; POST answers the window with its new run. Only household reports are refused now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With #4290 merged, the run routes take budget windows. require_run_route_kind returns the report's kind and refuses only household reports now. GET /v2/reports/{report_id}/runs answers a budget window's budget-window runs, newest first, each with its years (BudgetWindowRunListResult, kind budget_window); ReportRunListResponse's result is told apart by kind. POST runs a budget window again through the same simulation service route and answers the window with its new run. reads.read_budget_window_years is now public, for the run list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- require_run_route_kind returns RunRouteKind (economy or budget_window), and list_report_runs matches on it with a case for each, so a kind the run routes take later fails mypy (a missing return) until its list is added, rather than being listed as an economy report. - A test lists a window run with no year: no years and no versions. It passes as is, since the behavior exists. - The unit window re-run's years carry the current versions, as a window run's first year always does. - ReportRunsRead and the reads module say what they now hold. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The accepted-kind test now runs for every kind in RunRouteKind, from a table of the columns that make each kind, so the validator and the type can't drift apart unseen; the window re-run in the unit stand-in has simulation runs of its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4294
Summary
Runs a stored economy report or budget window again and lists a report's runs in
/v2/reports, with each run's package versions beside the current ones.POST /v2/reports/{report_id}/runs?country_id=, body{"force": false}(a JSON boolean;{}is the default, unknown fields refused, 16 KiB limit):SimulationSubmissionService.rerun_report, the same checks as a new report, including Refuse /v2/reports and /v2/simulations submissions whose policies set missing parameters #4286's 422missing_parameters;POST /reports/{report_id}/runswith{"force": …}), with the database session closed while it is asked;GET /v2/reports/{report_id}/runs?country_id=answers{report_id, kind, items, current_versions}, newest first (created last, ties by the larger ID):kind: economy): its report runs, each with its status, trigger,country_package_version,policyengine_version, simulation run IDs, error and times;kind: budget_window): its budget-window runs, each withrecalculate, its versions and its years, asGET /v2/reports/{id}answers a window's newest run.current_versionsare the versions the Public API runs, asGET /v2/reports/{id}already answers, so v3 can mark a report whose newest run used an older .py version as out of date and offer a re-run.How the simulation service's re-run answers are read (
policyengine_api/libs/simulation_report_reruns.py):run_in_progresswithrun_id, orrerun_not_supported): 409 with the service's code and reason andrun_id. The service answers 409 only before writing, so one that can't be read is 503.unknown_region,unknown_datasetorunknown_dynamicfor a row the stored report names: 422 with code and reason. Any other 400: 503.report_id.The status and code sets the create client and the re-run client share move from
simulation_reportsintosimulation_service_answers.The migration contract documents gain the two requests, and
v2-integration-check.ymlruns the new PostgreSQL tests.Waits for other PRs
POST /reports/{report_id}/runsis built against the shapes of draft Re-run a stored economy or budget-window report, or a simulation, on the current .py version policyengine-sim-api#1059, with test doubles for its answers. Until a release with that route deploys, re-runs answer 503 (the service's 404 for a route it doesn't have). Once it merges, this PR is checked against what shipped.report_id, which is all the re-run client reads; the window is then answered as read back.masterand adds them: a household report's re-run checks the household country, as its create does, rather than the economy flag, and its run list is its report runs.post_report_rerunis the only code that sends the re-run, and its docstring names the generated operation.Known limit:
current_versionsare the versions the Public API runs, asGET /v2/reports/{id}already answers, while a re-run records the simulation service's default worker's versions. During a release, while the two differ, a report run again a moment ago can still compare as out of date until both deploy the same .py version.Environment variables and secrets
No new ones. The re-run uses the create's client and configuration:
SIMULATION_ENTRYPOINT_URL: GitHub environment secret (staging, production) →push.ymljobenv:→deploy_cloud_run_candidate.sh→ Cloud Run. Unverified: that it names a simulation service revision with the re-run route (not yet released).GATEWAY_AUTH_ISSUER,GATEWAY_AUTH_AUDIENCE,GATEWAY_AUTH_CLIENT_ID,GATEWAY_AUTH_CLIENT_SECRET_RESOURCE: organization secrets → the deploy step'senv:→ the deploy script → Cloud Run, the secret read from Secret Manager at runtime. Unverified: the Auth0 client'ssimulation:submitpermission on the new route (the same permission asPOST /reports).V2_RUNTIME_DATABASE_URL_SECRET_RESOURCE: existing wiring; the runtime role already hasSELECTonreportsandreport_runs.v2-integration-check.yml, which uses the job's literal throwaway database values.Testing
Red-green throughout: each change's tests were committed first and seen failing for the expected reason.
New tests, each run by node ID (58 node IDs, 113 cases, all passing):
tests/unit/libs/test_simulation_report_reruns.py);tests/unit/v2/test_report_rerun_submissions.py);tests/unit/v2/test_report_run_routes.py);tests/unit/v2/test_report_rerun_service.py);tests/integration/test_v2_report_runs.py): run lists newest first with versions, other reports' runs left out, another country's report or an unknown one (404), household reports and budget windows (422), a re-run with and withoutforceanswered with its new run, no report session open while the simulation service is asked, the service's 409 and 503 answered as its own, and a report that can't be read back (502).Modified tests: the OpenAPI path list, the contract request count (99), the integration workflow's file list and the contract registry check.
Checks:
alembic -c alembic-v2.ini checkon a fresh PostgreSQL 17 database (no operations),lint-imports,python -m scripts.rules validate,python scripts/run_quality_guards.py, ruff, ruff format, mypy, and mypy on the changedlibsmodules. The migration contract documents are regenerated.Review: three adversarial review rounds on the economy routes, one on the budget-window extension after Serve budget windows through /v2/reports #4290 merged, and one on its fixes; none found a bug. Their quality findings are fixed:
Left as they are, with reasons:
All of these are revisited after Serve budget windows through /v2/reports #4290 and Serve household reports through /v2/reports #4293 merge.
🤖 Generated with Claude Code