koala73 / koala73/worldmonitor

feat(forecast): adopt the 202 async-job contract on trigger-simulation (conditional 202/200)

Open
#4,811 1 comment 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
TypeScript
Stars
86.6k
Forks
13.1k
Avg merge
8h 4m
Merged PRs (30d)
825

Description

Follow-up to #4810, which restored the 202 Accepted + Location async-job pattern on `scenario/run-scenario` (orank Access `async-job-pattern` now satisfied by that op).

`forecast/trigger-simulation` mirrors the same enqueue pattern (server-derived runId, Railway worker, poll `get-simulation-outcome`) but was deliberately left at 200-always in #4810 because it has non-enqueue success outcomes that make an unconditional 202 dishonest:

- `queued=true` → a fresh enqueue: **202 Accepted** + `Location: /api/forecast/v1/get-simulation-outcome?runId=` would be correct (use `setSuccessStatusOverride` from `server/_shared/response-headers.ts`, POST-200-only semantics already handled by the gateway).
- `reason='no_package'` → nothing enqueued (no package pointer): 202 would be wrong; keep 200.
- `reason='already-handled'` → idempotency hit: debatable (the work IS accepted/complete); pick one and document it.

Work needed beyond the handler one-liner:
1. Conditional status = the OpenAPI must document BOTH a 202 (queued) and a 200 (not-queued) success with the same `TriggerSimulationResponse` schema — extend `scripts/openapi-inject-async-jobs.mjs` with a dual-success mode, and give each response a **curated per-outcome example** (`queued:true` on the 202, `queued:false, reason:'no_package'` on the 200). The examples injector stamps ONE example on every 2xx (`successResponses` matches all `2\d\d`), so it would currently show `queued:true` on the 200 — a doc lie; needs an override hook.
2. `trigger_simulation.proto` response NOTE says 'All paths that return this message represent HTTP 200' — rewrite + `make generate` regen.
3. `tests/openapi-idempotency-contract.test.mjs` now asserts **exactly one** 2xx success per POST (generalized in #4810) — the dual-success op needs that assertion relaxed for ops documented as async-enqueue.
4. Extend `tests/openapi-async-jobs-contract.test.mjs` + the runtime tests for the conditional branch.

No orank points depend on this (run-scenario already satisfies the check) — this is REST-purity/honesty work.

Contributor guide

Open the contributing guide

Research direction

Start with the trigger-simulation handler and compare its enqueue behavior with scenario/run-scenario from #4810. Then read scripts/openapi-inject-async-jobs.mjs, trigger_simulation.proto, and the named OpenAPI and runtime contract tests; run make generate and those tests. Done means conditional 202/200 behavior, per-outcome examples, regenerated notes, and updated contract coverage, including the already-handled outcome decision.

Written by the indexing model from the issue text.

Assessment

Tech stack
openapi, typescript
Domain
api, testing
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.