Files
worldmonitor/todos/153-complete-p1-polling-no-statusresp-ok-check.md
Elie Habib 60e727679c feat(supply-chain): Sprint E — scenario visual completion + service parity (#2910)
* feat(supply-chain): Sprint E — scenario visual completion + service parity

- E1: fetchSectorDependency exported from supply-chain service index
- E2: PRO gate + all-renderer dispatch in MapContainer.activateScenario
- E3: scenario summary banner in SupplyChainPanel (dismiss wired)
- E4: "Simulate Closure" trigger button in expanded chokepoint cards
- E5: affectedIso2s heat layer in DeckGLMap (GeoJsonLayer, red tint)
- E6: SVG renderer setScenarioState (best-effort iso2 fill)
- E7: Globe renderer scenario polygons via flushPolygons
- E8: integration tests for scenario run/status endpoints

* fix(supply-chain): address PR #2910 review findings (P1 + P2 + P3)

- Wire setOnScenarioActivate + setOnDismissScenario in panel-layout.ts (todo #155)
- Rename shadow variable t→tmpl in SCENARIO_TEMPLATES.find (todo #152)
- Add statusResp.ok guard in scenario polling loop (todo #153)
- Replace status.result! non-null assertion with shape guard (todo #154)
- Add AbortController to prevent concurrent polling races (todo #162)
- Add polygonStrokeColor scenario branch (transparent) in GlobeMap (todo #156)
- Re-export SCENARIO_TEMPLATES via src/config/scenario-templates.ts (todo #157)
- Cache affectedIso2Set in DeckGLMap.setScenarioState (todo #158)
- Add scenario paths to PREMIUM_RPC_PATHS for auth injection (todo #160)
- Show template name in scenario banner instead of raw ID (todo #163)

* fix(supply-chain): address PR #2910 review findings

- Add auth headers to scenario fetch calls in SupplyChainPanel
- Reset button state on scenario dismiss
- Poll status immediately on first iteration (no 2s delay)
- Pre-compute scenario polygons in GlobeMap.setScenarioState
- Use scenarioId for DeckGL updateTriggers precision

* fix(supply-chain): wire panel instance to MapContainer, stop button click propagation

- Call setSupplyChainPanel() in panel-layout.ts so scenario banner renders
- Add stopPropagation() to Simulate Closure button to prevent card collapse
2026-04-10 21:31:26 +04:00

57 lines
2.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
status: complete
priority: p1
issue_id: "153"
tags: [code-review, quality, supply-chain, reliability]
dependencies: []
---
# Missing `statusResp.ok` Guard in Scenario Polling Loop
## Problem Statement
In `SupplyChainPanel.ts:677`, the polling loop calls `statusResp.json()` without first checking `statusResp.ok`. A 429, 500, or network error causes `.json()` to throw or produce garbage, silently burning through all 30 iterations. The button ends up stuck on "Computing…" for 60 seconds before showing "Error — retry" with no useful signal.
## Findings
- **File:** `src/components/SupplyChainPanel.ts`, line 677
- **Code:**
```ts
const statusResp = await fetch(`/api/scenario/v1/status?jobId=${encodeURIComponent(jobId)}`);
const status = await statusResp.json() as { status: string; result?: ScenarioResult };
```
- No check on `statusResp.ok` before consuming body
- 30 × 2s = 60s of silent failure with no feedback to the user
## Proposed Solutions
### Option A: Guard before `.json()` (Recommended)
```ts
const statusResp = await fetch(`/api/scenario/v1/status?jobId=${encodeURIComponent(jobId)}`);
if (!statusResp.ok) throw new Error(`Status poll failed: ${statusResp.status}`);
const status = await statusResp.json() as { status: string; result?: ScenarioResult };
```
**Pros:** Fails fast on server error, exits loop immediately
**Cons:** None
**Effort:** Small | **Risk:** None
### Option B: Retry on non-fatal errors, throw on fatal
Skip 429/503, throw on 4xx. More complex, adds ~10 lines, probably not worth it for this use case.
**Effort:** Medium | **Risk:** Low
## Recommended Action
_Apply Option A — guard before `.json()`. One line._
## Technical Details
- **Affected files:** `src/components/SupplyChainPanel.ts`
- **Line:** 677
## Acceptance Criteria
- [ ] `statusResp.ok` checked before calling `.json()`
- [ ] Loop exits immediately (throws) on non-OK response
- [ ] Button shows "Error — retry" within one polling cycle on server error
## Work Log
- 2026-04-10: Identified by kieran-typescript-reviewer during PR #2910 review
## Resources
- PR: #2910