mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
docs(mintlify): add Route Explorer + Scenario Engine workflow pages (#3211)
* docs(mintlify): add Route Explorer + Scenario Engine workflow pages Checkpoint for review on the IA refresh (per plan docs/plans/2026-04-19-001-feat-docs-user-facing-ia-refresh-plan.md). - docs/docs.json: link Country Resilience Index methodology under Intelligence & Analysis so the flagship 222-country feature is reachable from the main nav (previously orphaned). Add a new Workflows group containing route-explorer and scenario-engine. - docs/route-explorer.mdx: standalone workflow page. Who it is for, Cmd+K entry, four tabs (Current / Alternatives / Land / Impact), inputs, keyboard bindings, map-state integration, PRO gating with free-tier blur + public-route highlight, data sources. - docs/scenario-engine.mdx: standalone workflow page. Template categories (conflict / weather / sanctions / tariff_shock / infrastructure / pandemic), how a scenario activates on the map, PRO gating, pointers to the async job API. Deferred to follow-up commits in the same PR: - documentation.mdx landing rewrite - features.mdx refresh - maritime-intelligence.mdx link-out to Route Explorer - Panels nav group (waits for PR 2 content) All content grounded in live source files cited inline. * docs(mintlify): fix Route Explorer + Scenario Engine review findings Reviewer caught 4 cases where I described behavior I hadn't read carefully. All fixes cross-checked against source. - route-explorer (free-tier): the workflow does NOT blur a numeric payload behind a public demo route. On free tier, fetchLane() short-circuits to renderFreeGate() which blurs the left rail, replaces the tab area with an Upgrade-to-PRO card, and applies a generic public-route highlight on the map. No lane data is rendered in any tab. See src/components/RouteExplorer/ RouteExplorer.ts:212 + :342. - route-explorer (keyboard): Tab / Shift+Tab moves focus between the panel and the map. Direct field jumps are F (From), T (To), P (Product/HS2), not Tab-cycling. Also added the full KeyboardHelp binding list (S swap, ↑/↓ list nav, Enter commit, Cmd+, copy URL, Esc close, ? help, 1-4 tabs). See src/components/RouteExplorer/ KeyboardHelp.ts:9 and RouteExplorer.ts:623. - scenario-engine: the SCENARIO_TEMPLATES array only ships templates of 4 types today (conflict, weather, sanctions, tariff_shock). The ScenarioType union includes infrastructure and pandemic but no templates of those types ship. Dropped them from the shipped table and noted the type union leaves room for future additions. - scenario-engine + api-scenarios: the worker writes status: 'done' (not 'completed') on success, 'failed' on error; pending is synthesised by the status endpoint when no worker record exists. Fixed both the new workflow page and the merged api-scenarios.mdx completed-response example + polling language. See scripts/scenario-worker.mjs:421 and src/components/SupplyChainPanel.ts:870. * docs(mintlify): fix third-round review findings (real IDs + 4-state lifecycle) - api-scenarios (template example): replaced invented hormuz-closure-30d / ["hormuz"] with the actually-shipped hormuz-tanker-blockade / ["hormuz_strait"] from scenario- templates.ts:80. Listed the other 5 shipped template IDs so scripted users aren't dependent on a single example. - api-scenarios (status lifecycle): worker writes FOUR states, not three. Added the intermediate "processing" state with startedAt, written by the worker at job pickup (scenario- worker.mjs:411). Lifecycle now: pending → processing → done|failed. Both pending and processing are non-terminal. - scenario-engine (scripted use blurb): mirror the 4-state language and link into the lifecycle table. - scenario-engine (UI dismiss): replaced "Click Deactivate" with the actual × dismiss control on the scenario banner (aria-label: "Dismiss scenario") per src/components/SupplyChainPanel.ts:790. Also described the banner contents (name, chokepoints, countries, tagline). - api-shipping-v2: while fixing chokepoint IDs, also corrected "hormuz" → "hormuz_strait" and "bab-el-mandeb" → "bab_el_mandeb" across all four occurrences in the shipping v2 page (from PR #3209). Real IDs come from server/_shared/chokepoint- registry.ts (snake_case, not kebab-case, not bare "hormuz"). * docs(mintlify): fix fourth-round findings (banner DOM, webhook TTL refresh) - scenario-engine: accurate description of the rendered scenario banner. Always-present elements are the ⚠ icon, scenario name, top-5 impacted countries with impact %, and dismiss ×. Params chip (e.g. '14d · +110% cost') and 'Simulating …' tagline are conditional on the worker result carrying template parameters (durationDays, disruptionPct, costShockMultiplier). The banner never lists affected chokepoints by name — the map and the chokepoint cards surface those. Per renderScenarioBanner at src/components/SupplyChainPanel.ts:750. - api-shipping-v2 (webhook TTL): register extends both the record and the owner-index set's 30-day TTL via atomic pipeline (SET + SADD + EXPIRE). rotate-secret and reactivate only extend the record's TTL — neither touches the owner-index set, so the owner index can expire independently if a caller only rotates/reactivates within a 30-day window. Re-register to keep both alive. Per api/v2/shipping/webhooks.ts:230 (register pipeline) and :325 (rotate setCachedJson on record only). * docs(mintlify): fix PRO auth contract (trusted origin ≠ PRO) - api-scenarios: 'X-WorldMonitor-Key (or trusted browser origin) + PRO' was wrong — isCallerPremium() explicitly skips trusted-origin short-circuits (keyCheck.required === false) and only counts (a) an env-valid or user-owned wm_-prefixed API key with apiAccess entitlement, or (b) a Clerk bearer with role=pro or Dodo tier ≥ 1. Browser calls work because premiumFetch() injects one of those credentials per request, not because Origin alone authenticates. Per server/_shared/premium-check.ts:34 and src/services/premium-fetch.ts:66. - usage-auth: strengthened the 'Entitlement / tier gating' section to state outright that authentication and PRO entitlement are orthogonal, and that trusted Origin is NOT accepted as PRO even though it is accepted for public endpoints. Listed the two real credential forms that pass the gate. * docs(mintlify): fix stale line cite (MapContainer.activateScenario at :1010) Greptile review P2: prose cited MapContainer.ts:1004 but activateScenario is declared at :1010. Line 1004 landed inside the JSDoc block. * docs(mintlify): finish PR 1 — landing rewrite, features refresh, maritime link-out Completes the PR 1 items from docs/plans/2026-04-19-001-feat-docs-user- facing-ia-refresh-plan.md that were deferred after the checkpoint on Route Explorer + Scenario Engine + CRI nav. No new pages — only edits to existing pages to point at and cohere with the new workflow pages. - documentation.mdx: landing rewrite. Dropped brittle counts (344 news sources, 49 layers, 24 CII countries, 31+ sources, 24 typed services) in favor of durable product framing. Surfaced the shipped differentiators that were invisible on the landing previously: Country Resilience Index (222 countries, linked to its methodology page), AI daily brief, Route Explorer, Scenario Engine, MCP server. Kept CII and CRI as two distinct country-risk surfaces — do not conflate. - features.mdx: replaced the 'all 55 panels' Cmd+K claim and the stale inventory list with family-grouped descriptions that include the panels this audit surfaced as missing (disease- outbreaks, radiation-watch, thermal-escalation, consumer-prices, latest-brief, forecast, country-resilience). Added a Workflows section linking to Route Explorer and Scenario Engine, and a Country-level risk section linking CII + CRI. Untouched sections (map, marker clustering, data layers, export, monitors, activity tracking) left as-is. - maritime-intelligence.mdx: collapsed the embedded Route Explorer subsection to a one-paragraph pointer at /route-explorer so the standalone page is the canonical home. Panels nav group remains intentionally unadded; it waits on PR 2 content to avoid rendering an empty group in Mintlify.
This commit is contained in:
75
docs/scenario-engine.mdx
Normal file
75
docs/scenario-engine.mdx
Normal file
@@ -0,0 +1,75 @@
|
||||
---
|
||||
title: "Scenario Engine"
|
||||
description: "Run pre-built supply-chain disruption scenarios — conflicts, sanctions, tariff shocks, and weather events — and see which chokepoints, sectors, and countries are exposed, directly on the map."
|
||||
---
|
||||
|
||||
Scenario Engine turns WorldMonitor's live supply-chain graph into an interactive what-if tool. Instead of asking "what is the state of this lane today," you pick a named disruption scenario — a Hormuz closure, a Panama drought, a tariff shock on semiconductors — and the engine resolves the downstream impact on chokepoints, HS2 sectors, and countries, then paints the result onto the existing map.
|
||||
|
||||
## Who it is for
|
||||
|
||||
- **Supply-chain and commodity desks** stress-testing routing assumptions against a named event.
|
||||
- **Risk and policy teams** translating a geopolitical or environmental scenario into concrete country exposure.
|
||||
- **Leadership** building talking-tracks around "if X happens, what breaks first?"
|
||||
|
||||
## Opening the engine
|
||||
|
||||
Scenario Engine lives inside the **Supply Chain** panel on the main dashboard. Each pre-built scenario template renders as a trigger button; clicking a scenario starts an async job and activates the visual overlay once results land.
|
||||
|
||||
You can also drive it programmatically — see [Scenarios API](/api-scenarios) for the `/templates`, `/run`, and `/status` endpoints.
|
||||
|
||||
## Scenario templates
|
||||
|
||||
Templates are defined in `server/worldmonitor/supply-chain/v1/scenario-templates.ts`. Each template has a `type` drawn from a small, curated set so scenarios are browsable by category rather than a free-form list.
|
||||
|
||||
The currently shipped types are:
|
||||
|
||||
| Type | What it models |
|
||||
|---|---|
|
||||
| `conflict` | Chokepoint closure or degradation driven by an active conflict event (Taiwan Strait full closure, Suez + Bab-el-Mandeb simultaneous, Hormuz tanker blockade). |
|
||||
| `weather` | Climatic disruption — e.g. the Panama Canal 50% drought scenario. |
|
||||
| `sanctions` | Targeted trade restrictions (e.g. Russia / Baltic grain suspension). |
|
||||
| `tariff_shock` | A sudden tariff action and its cost pass-through (e.g. US tariff escalation on electronics). |
|
||||
|
||||
Each template declares the chokepoints it affects (IDs from the chokepoint registry), a duration in days, affected HS2 sectors, and a cost-shock multiplier. Run them as-is — there are no sliders in v1. The `ScenarioType` union leaves room for `infrastructure` and `pandemic` categories, but no templates of those types ship today.
|
||||
|
||||
## What you get back
|
||||
|
||||
A completed scenario returns:
|
||||
|
||||
- **Affected chokepoints** — which ones go red on the map.
|
||||
- **Impact ranking** — the top affected countries by ISO-2, ordered by exposure, with per-country import-value impact against the selected HS2 sectors.
|
||||
- **Sector call-outs** — which HS2 chapters take the biggest hit.
|
||||
- **A summary card** injected into the Supply Chain panel that stays visible until you deactivate the scenario.
|
||||
|
||||
The UI is state-driven, not modal — activating a scenario sets a `scenarioState` on every map renderer (deck.gl, globe, SVG fallback) so chokepoint colors and country choropleths reflect the disruption until you deactivate. This is coordinated by `MapContainer.activateScenario` at `src/components/MapContainer.ts:1010`, which is explicitly PRO-gated.
|
||||
|
||||
## Tier & gating
|
||||
|
||||
Scenario Engine is **PRO**. Free users see the trigger buttons but are blocked at activation: a `scenario-engine` gate-hit event is logged and the map is not repainted. The `/api/scenario/v1/run` endpoint itself also enforces PRO at the edge (`api/scenario/v1/run.ts`).
|
||||
|
||||
Rate limits on the API side — 10 jobs / minute / user, with a global queue cap at 100 in-flight — are documented in [Scenarios API](/api-scenarios#run-a-scenario).
|
||||
|
||||
## Run it yourself
|
||||
|
||||
The workflow is inherently async — the edge function enqueues a job, a Railway worker computes the impact, and the result is polled back:
|
||||
|
||||
1. Open the Supply Chain panel.
|
||||
2. Click a scenario trigger button (the template name).
|
||||
3. The button disables while the job runs (typically 5-30 s).
|
||||
4. When the result lands, the map repaints, and a scenario banner is prepended to the panel. The banner always shows: a ⚠ icon, the scenario name, the top 5 impacted countries with per-country impact %, and a **×** dismiss control. When the scenario's result payload includes template parameters (duration, disruption %, cost-shock multiplier), the banner additionally renders a chip row (e.g. `14d · +110% cost`) and a tagline line such as *"Simulating 14d / 100% closure / +110% cost on 1 chokepoint. Chokepoint card below shows projected score; map highlights disrupted routes."* The affected chokepoints themselves are highlighted on the map and on the chokepoint cards rather than listed by name in the banner.
|
||||
5. Click the **×** dismiss control on the banner (aria-label: "Dismiss scenario") to clear the scenario state — the map repaints to its baseline and the panel re-renders without the projected score and red-border callouts.
|
||||
|
||||
For scripted use, see [`POST /api/scenario/v1/run`](/api-scenarios#run-a-scenario) — enqueue, then poll `/status` until the response has a terminal status (`"done"` on success, `"failed"` on error). Non-terminal states are `"pending"` (queued) and `"processing"` (worker started); both can persist for several seconds. See the [status lifecycle table](/api-scenarios#poll-job-status) for the full contract.
|
||||
|
||||
## Data behind Scenario Engine
|
||||
|
||||
- **Scenario templates** — `server/worldmonitor/supply-chain/v1/scenario-templates.ts`. Additions require a proto-side change; not user-configurable today.
|
||||
- **Job queue** — Redis list `scenario-queue:pending`; worker results land at `scenario-result:{jobId}`.
|
||||
- **Chokepoint registry** — the same registry that backs live chokepoint status and Route Explorer, ensuring scenario results visually align with the rest of the product.
|
||||
- **Trade / impact data** — HS2 import exposure per country, sourced from the supply-chain cache set.
|
||||
|
||||
## Related workflows
|
||||
|
||||
- [Route Explorer](/route-explorer) — run a specific lane against *today's* state.
|
||||
- [Scenarios API](/api-scenarios) — the underlying HTTP contract.
|
||||
- [Supply Chain](/api/SupplyChainService.openapi.yaml) — the broader service that backs the Supply Chain panel.
|
||||
Reference in New Issue
Block a user