Files
worldmonitor/docs/api/SupplyChainService.openapi.json
Elie Habib c72251178c feat(route-explorer): Sprint 4 — strategic-product impact tab + get-route-impact RPC (#2996)
* feat(route-explorer): Sprint 4 — strategic-product impact tab

Adds the Impact tab to the Route Explorer, powered by a new
get-route-impact RPC that returns strategic-product trade data for
any country pair.

Backend:
- New proto get_route_impact.proto with GetRouteImpact{Request,Response}
  + StrategicProduct message
- New handler server/worldmonitor/supply-chain/v1/get-route-impact.ts:
  reads comtrade:bilateral-hs4:{iso2}:v1 store, computes lane value for
  selected HS2, top 5 strategic products by value with chokepoint
  exposure, resilience score (server-side from Redis), dependency flags
- Cache key ROUTE_IMPACT_KEY in cache-keys.ts (NOT in BOOTSTRAP_KEYS)
- Gateway + premium-paths registered as slow-browser premium RPC
- Client wrapper fetchRouteImpact in supply-chain/index.ts

Impact tab UI:
- CountryImpactTab.ts: strategic products table (top 5 by value),
  lane value card for selected HS2, hs2InSeededUniverse banner when
  HS2 is not in the 14 seeded sectors, comtradeSource states
  (missing/empty/bilateral-hs4), drill-sideways on product row click
- LeftRail.updateDependencyFlags: renders flags from Impact response
  with color-coded badges (compound_risk/single_source/diversifiable)

Data flow:
- fetchImpact fires in parallel with fetchResilience after lane data
  loads, generation-scoped
- Impact response updates left-rail flags + resilience score
- Drill-sideways: clicking a product row switches the explorer's HS2
  and re-queries all tabs

Server-side resilience:
- get-route-impact reads resilience:score:v8:{iso2} from Redis directly
  so the data is available for future email briefs without client calls

Plan: docs/plans/2026-04-11-001-feat-worldwide-route-explorer-plan.md

* fix(route-explorer): real exposure score for flags + tabstrip sync on drill

P1: computeDependencyFlags hardcoded primaryExposure=80 whenever any
chokepoint existed, fabricating SINGLE_CORRIDOR_CRITICAL without using
real exposure data. Replaced with computeRealExposureScore that uses the
same route-cluster overlap logic as get-sector-dependency, computing the
actual exposure percentage before comparing against the >80 threshold.

P2: handleDrillSideways set state.tab=1 directly without going through
setTab(), leaving the tabstrip visually and semantically on Impact while
content showed Current. Now calls setTab(1) which updates both the
tabstrip active state and aria-selected.

* fix(route-explorer): guard resilience overwrite + normalize HS2 filter

P1: fetchImpact could zero the left-rail resilience score when
get-route-impact returned resilienceScore=0 (Redis miss fallback),
overwriting a valid score set by the concurrent fetchResilience call.
Now only applies the server-side score when it is actually > 0.

P2: HS4-to-HS2 matching used a redundant dual-condition filter
(hs4ToHs2 + startsWith) that masked a potential normalization bug.
Simplified to normalize hs2 once via parseInt then use a single
hs4ToHs2 comparison.
2026-04-12 10:25:13 +04:00

1 line
27 KiB
JSON
Raw 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.
{"components":{"schemas":{"BypassCorridorOption":{"description":"BypassCorridorOption is a single enriched bypass corridor for the Route Explorer UI.\n Includes coordinate endpoints so the client can call MapContainer.setBypassRoutes\n directly without any client-side geometry lookup.","properties":{"addedCostMultiplier":{"format":"double","type":"number"},"addedTransitDays":{"format":"int32","type":"integer"},"fromPort":{"$ref":"#/components/schemas/GeoPoint"},"id":{"type":"string"},"name":{"type":"string"},"status":{"description":"Status of a bypass corridor for UI labeling. \"active\" means usable today;\n \"proposed\" means documented but not yet built/operational; \"unavailable\"\n means blockaded or otherwise blocked from use.","enum":["CORRIDOR_STATUS_UNSPECIFIED","CORRIDOR_STATUS_ACTIVE","CORRIDOR_STATUS_PROPOSED","CORRIDOR_STATUS_UNAVAILABLE"],"type":"string"},"toPort":{"$ref":"#/components/schemas/GeoPoint"},"type":{"type":"string"},"warRiskTier":{"type":"string"}},"type":"object"},"BypassOption":{"properties":{"activationThreshold":{"type":"string"},"addedCostMultiplier":{"format":"double","type":"number"},"addedTransitDays":{"format":"int32","type":"integer"},"bypassWarRiskTier":{"description":"*\n War risk tier derived from Lloyd's JWC Listed Areas + OSINT threat classification.\n This is a FREE field (no PRO gate) — it exposes the existing server-internal\n threatLevel from ChokepointConfig, making it available to clients for badges\n and bypass corridor scoring.","enum":["WAR_RISK_TIER_UNSPECIFIED","WAR_RISK_TIER_NORMAL","WAR_RISK_TIER_ELEVATED","WAR_RISK_TIER_HIGH","WAR_RISK_TIER_CRITICAL","WAR_RISK_TIER_WAR_ZONE"],"type":"string"},"capacityConstraintTonnage":{"format":"int64","type":"string"},"id":{"type":"string"},"liveScore":{"format":"double","type":"number"},"name":{"type":"string"},"notes":{"type":"string"},"suitableCargoTypes":{"items":{"type":"string"},"type":"array"},"type":{"type":"string"},"waypointChokepointIds":{"items":{"type":"string"},"type":"array"}},"type":"object"},"ChokepointExposureEntry":{"description":"ChokepointExposureEntry holds per-chokepoint exposure data for a country.","properties":{"chokepointId":{"description":"Canonical chokepoint ID from the chokepoint registry.","type":"string"},"chokepointName":{"description":"Human-readable chokepoint name.","type":"string"},"coastSide":{"description":"Which ocean/basin side the country's ports face (atlantic, pacific, indian, med, multi, landlocked).","type":"string"},"exposureScore":{"description":"Exposure score 0100; higher = more dependent on this chokepoint.","format":"double","type":"number"},"shockSupported":{"description":"Whether the shock model is supported for this chokepoint + hs2 combination.","type":"boolean"}},"type":"object"},"ChokepointExposureSummary":{"properties":{"chokepointId":{"type":"string"},"chokepointName":{"type":"string"},"exposurePct":{"format":"int32","type":"integer"}},"type":"object"},"ChokepointInfo":{"properties":{"activeWarnings":{"format":"int32","type":"integer"},"affectedRoutes":{"items":{"type":"string"},"type":"array"},"aisDisruptions":{"format":"int32","type":"integer"},"congestionLevel":{"type":"string"},"description":{"type":"string"},"directionalDwt":{"items":{"$ref":"#/components/schemas/DirectionalDwt"},"type":"array"},"directions":{"items":{"type":"string"},"type":"array"},"disruptionScore":{"format":"int32","type":"integer"},"flowEstimate":{"$ref":"#/components/schemas/FlowEstimate"},"id":{"type":"string"},"lat":{"format":"double","type":"number"},"lon":{"format":"double","type":"number"},"name":{"type":"string"},"status":{"type":"string"},"transitSummary":{"$ref":"#/components/schemas/TransitSummary"},"warRiskTier":{"description":"*\n War risk tier derived from Lloyd's JWC Listed Areas + OSINT threat classification.\n This is a FREE field (no PRO gate) — it exposes the existing server-internal\n threatLevel from ChokepointConfig, making it available to clients for badges\n and bypass corridor scoring.","enum":["WAR_RISK_TIER_UNSPECIFIED","WAR_RISK_TIER_NORMAL","WAR_RISK_TIER_ELEVATED","WAR_RISK_TIER_HIGH","WAR_RISK_TIER_CRITICAL","WAR_RISK_TIER_WAR_ZONE"],"type":"string"}},"type":"object"},"CriticalMineral":{"properties":{"globalProduction":{"format":"double","type":"number"},"hhi":{"format":"double","type":"number"},"mineral":{"type":"string"},"riskRating":{"type":"string"},"topProducers":{"items":{"$ref":"#/components/schemas/MineralProducer"},"type":"array"},"unit":{"type":"string"}},"type":"object"},"DirectionalDwt":{"properties":{"direction":{"type":"string"},"dwtThousandTonnes":{"format":"double","type":"number"},"wowChangePct":{"format":"double","type":"number"}},"type":"object"},"Error":{"description":"Error is returned when a handler encounters an error. It contains a simple error message that the developer can customize.","properties":{"message":{"description":"Error message (e.g., 'user not found', 'database connection failed')","type":"string"}},"type":"object"},"FieldViolation":{"description":"FieldViolation describes a single validation error for a specific field.","properties":{"description":{"description":"Human-readable description of the validation violation (e.g., 'must be a valid email address', 'required field missing')","type":"string"},"field":{"description":"The field path that failed validation (e.g., 'user.email' for nested fields). For header validation, this will be the header name (e.g., 'X-API-Key')","type":"string"}},"required":["field","description"],"type":"object"},"FlowEstimate":{"properties":{"baselineMbd":{"format":"double","type":"number"},"currentMbd":{"format":"double","type":"number"},"disrupted":{"type":"boolean"},"flowRatio":{"format":"double","type":"number"},"hazardAlertLevel":{"type":"string"},"hazardAlertName":{"type":"string"},"source":{"type":"string"}},"type":"object"},"GeoPoint":{"description":"GeoPoint is a [longitude, latitude] pair.","properties":{"lat":{"format":"double","type":"number"},"lon":{"format":"double","type":"number"}},"type":"object"},"GetBypassOptionsRequest":{"properties":{"cargoType":{"description":"container | tanker | bulk | roro (default: \"container\")","type":"string"},"chokepointId":{"type":"string"},"closurePct":{"description":"0-100, percent of capacity blocked (default: 100)","format":"int32","type":"integer"}},"required":["chokepointId"],"type":"object"},"GetBypassOptionsResponse":{"properties":{"cargoType":{"type":"string"},"chokepointId":{"type":"string"},"closurePct":{"format":"int32","type":"integer"},"fetchedAt":{"type":"string"},"options":{"items":{"$ref":"#/components/schemas/BypassOption"},"type":"array"},"primaryChokepointWarRiskTier":{"description":"*\n War risk tier derived from Lloyd's JWC Listed Areas + OSINT threat classification.\n This is a FREE field (no PRO gate) — it exposes the existing server-internal\n threatLevel from ChokepointConfig, making it available to clients for badges\n and bypass corridor scoring.","enum":["WAR_RISK_TIER_UNSPECIFIED","WAR_RISK_TIER_NORMAL","WAR_RISK_TIER_ELEVATED","WAR_RISK_TIER_HIGH","WAR_RISK_TIER_CRITICAL","WAR_RISK_TIER_WAR_ZONE"],"type":"string"}},"type":"object"},"GetChokepointStatusRequest":{"type":"object"},"GetChokepointStatusResponse":{"properties":{"chokepoints":{"items":{"$ref":"#/components/schemas/ChokepointInfo"},"type":"array"},"fetchedAt":{"type":"string"},"upstreamUnavailable":{"type":"boolean"}},"type":"object"},"GetCountryChokepointIndexRequest":{"description":"GetCountryChokepointIndexRequest specifies the country and optional HS2 chapter.","properties":{"hs2":{"description":"HS2 chapter (2-digit string). Defaults to \"27\" (energy/mineral fuels) when absent.","type":"string"},"iso2":{"description":"ISO 3166-1 alpha-2 country code (uppercase).","pattern":"^[A-Z]{2}$","type":"string"}},"required":["iso2"],"type":"object"},"GetCountryChokepointIndexResponse":{"description":"GetCountryChokepointIndexResponse returns exposure scores for all relevant chokepoints.","properties":{"exposures":{"items":{"$ref":"#/components/schemas/ChokepointExposureEntry"},"type":"array"},"fetchedAt":{"description":"ISO timestamp of when this data was last seeded.","type":"string"},"hs2":{"description":"HS2 chapter used for the computation.","type":"string"},"iso2":{"description":"ISO 3166-1 alpha-2 country code echoed from the request.","type":"string"},"primaryChokepointId":{"description":"Canonical ID of the chokepoint with the highest exposure score.","type":"string"},"vulnerabilityIndex":{"description":"Composite vulnerability index 0100 (weighted sum of top-3 exposures).","format":"double","type":"number"}},"type":"object"},"GetCountryCostShockRequest":{"properties":{"chokepointId":{"type":"string"},"hs2":{"description":"HS2 chapter (default: \"27\")","type":"string"},"iso2":{"pattern":"^[A-Z]{2}$","type":"string"}},"required":["iso2","chokepointId"],"type":"object"},"GetCountryCostShockResponse":{"properties":{"chokepointId":{"type":"string"},"coverageDays":{"description":"Energy stockpile coverage in days (IEA data, HS 27 only; 0 for non-energy sectors or net exporters)","format":"int32","type":"integer"},"fetchedAt":{"type":"string"},"hasEnergyModel":{"description":"Whether supply_deficit_pct and coverage_days are modelled (true) or unavailable (false)","type":"boolean"},"hs2":{"type":"string"},"iso2":{"type":"string"},"supplyDeficitPct":{"description":"Average refined-product supply deficit % under full closure (Gasoline/Diesel/Jet fuel/LPG average; HS 27 only)","format":"double","type":"number"},"unavailableReason":{"description":"Null/unavailable explanation for non-energy sectors","type":"string"},"warRiskPremiumBps":{"description":"War risk insurance premium in basis points for this chokepoint","format":"int32","type":"integer"},"warRiskTier":{"description":"*\n War risk tier derived from Lloyd's JWC Listed Areas + OSINT threat classification.\n This is a FREE field (no PRO gate) — it exposes the existing server-internal\n threatLevel from ChokepointConfig, making it available to clients for badges\n and bypass corridor scoring.","enum":["WAR_RISK_TIER_UNSPECIFIED","WAR_RISK_TIER_NORMAL","WAR_RISK_TIER_ELEVATED","WAR_RISK_TIER_HIGH","WAR_RISK_TIER_CRITICAL","WAR_RISK_TIER_WAR_ZONE"],"type":"string"}},"type":"object"},"GetCriticalMineralsRequest":{"type":"object"},"GetCriticalMineralsResponse":{"properties":{"fetchedAt":{"type":"string"},"minerals":{"items":{"$ref":"#/components/schemas/CriticalMineral"},"type":"array"},"upstreamUnavailable":{"type":"boolean"}},"type":"object"},"GetRouteExplorerLaneRequest":{"properties":{"cargoType":{"description":"One of: container, tanker, bulk, roro","type":"string"},"fromIso2":{"pattern":"^[A-Z]{2}$","type":"string"},"hs2":{"description":"HS2 chapter code, e.g. \"27\", \"85\"","type":"string"},"toIso2":{"pattern":"^[A-Z]{2}$","type":"string"}},"required":["fromIso2","toIso2","hs2","cargoType"],"type":"object"},"GetRouteExplorerLaneResponse":{"properties":{"bypassOptions":{"items":{"$ref":"#/components/schemas/BypassCorridorOption"},"type":"array"},"cargoType":{"type":"string"},"chokepointExposures":{"items":{"$ref":"#/components/schemas/ChokepointExposureSummary"},"type":"array"},"disruptionScore":{"format":"double","type":"number"},"estFreightUsdPerTeuRange":{"$ref":"#/components/schemas/NumberRange"},"estTransitDaysRange":{"$ref":"#/components/schemas/NumberRange"},"fetchedAt":{"type":"string"},"fromIso2":{"type":"string"},"hs2":{"type":"string"},"noModeledLane":{"description":"True when the wrapper fell back to the origin's first route (no shared route\n between origin and destination clusters). Signals \"no modeled lane\" to the UI.","type":"boolean"},"primaryRouteGeometry":{"items":{"$ref":"#/components/schemas/GeoPoint"},"type":"array"},"primaryRouteId":{"description":"Primary trade route ID from TRADE_ROUTES config. Empty when no modeled lane.","type":"string"},"toIso2":{"type":"string"},"warRiskTier":{"type":"string"}},"type":"object"},"GetRouteImpactRequest":{"properties":{"fromIso2":{"pattern":"^[A-Z]{2}$","type":"string"},"hs2":{"type":"string"},"toIso2":{"pattern":"^[A-Z]{2}$","type":"string"}},"required":["fromIso2","toIso2","hs2"],"type":"object"},"GetRouteImpactResponse":{"properties":{"comtradeSource":{"type":"string"},"dependencyFlags":{"items":{"description":"DependencyFlag classifies how a country+sector dependency can fail.","enum":["DEPENDENCY_FLAG_UNSPECIFIED","DEPENDENCY_FLAG_SINGLE_SOURCE_CRITICAL","DEPENDENCY_FLAG_SINGLE_CORRIDOR_CRITICAL","DEPENDENCY_FLAG_COMPOUND_RISK","DEPENDENCY_FLAG_DIVERSIFIABLE"],"type":"string"},"type":"array"},"fetchedAt":{"type":"string"},"hs2InSeededUniverse":{"type":"boolean"},"laneValueUsd":{"format":"double","type":"number"},"primaryExporterIso2":{"type":"string"},"primaryExporterShare":{"format":"double","type":"number"},"resilienceScore":{"format":"double","type":"number"},"topStrategicProducts":{"items":{"$ref":"#/components/schemas/StrategicProduct"},"type":"array"}},"type":"object"},"GetSectorDependencyRequest":{"properties":{"hs2":{"description":"HS2 chapter code, e.g. \"27\" (mineral fuels), \"85\" (electronics)","type":"string"},"iso2":{"pattern":"^[A-Z]{2}$","type":"string"}},"required":["iso2","hs2"],"type":"object"},"GetSectorDependencyResponse":{"properties":{"fetchedAt":{"type":"string"},"flags":{"items":{"description":"DependencyFlag classifies how a country+sector dependency can fail.","enum":["DEPENDENCY_FLAG_UNSPECIFIED","DEPENDENCY_FLAG_SINGLE_SOURCE_CRITICAL","DEPENDENCY_FLAG_SINGLE_CORRIDOR_CRITICAL","DEPENDENCY_FLAG_COMPOUND_RISK","DEPENDENCY_FLAG_DIVERSIFIABLE"],"type":"string"},"type":"array"},"hasViableBypass":{"description":"Whether at least one viable bypass corridor exists for the primary chokepoint.","type":"boolean"},"hs2":{"type":"string"},"hs2Label":{"description":"Human-readable HS2 chapter name.","type":"string"},"iso2":{"type":"string"},"primaryChokepointExposure":{"description":"Exposure score for the primary chokepoint (0100).","format":"double","type":"number"},"primaryChokepointId":{"description":"Chokepoint ID with the highest exposure score for this country+sector.","type":"string"},"primaryExporterIso2":{"description":"ISO2 of the country supplying the largest share of this sector's imports.","type":"string"},"primaryExporterShare":{"description":"Share of imports from the primary exporter (01). 0 = no Comtrade data available.","format":"double","type":"number"}},"type":"object"},"GetShippingRatesRequest":{"type":"object"},"GetShippingRatesResponse":{"properties":{"fetchedAt":{"type":"string"},"indices":{"items":{"$ref":"#/components/schemas/ShippingIndex"},"type":"array"},"upstreamUnavailable":{"type":"boolean"}},"type":"object"},"GetShippingStressRequest":{"type":"object"},"GetShippingStressResponse":{"properties":{"carriers":{"items":{"$ref":"#/components/schemas/ShippingStressCarrier"},"type":"array"},"fetchedAt":{"description":"Warning: Values \u003e 2^53 may lose precision in JavaScript","format":"int64","type":"integer"},"stressLevel":{"description":"\"low\" | \"moderate\" | \"elevated\" | \"critical\".","type":"string"},"stressScore":{"description":"Composite stress score 0100 (higher = more disruption).","format":"double","type":"number"},"upstreamUnavailable":{"description":"Set to true when upstream data source is unavailable and cached data is stale.","type":"boolean"}},"type":"object"},"MineralProducer":{"properties":{"country":{"type":"string"},"countryCode":{"type":"string"},"productionTonnes":{"format":"double","type":"number"},"sharePct":{"format":"double","type":"number"}},"type":"object"},"NumberRange":{"description":"Inclusive integer range for transit days / freight USD estimates.","properties":{"max":{"format":"int32","type":"integer"},"min":{"format":"int32","type":"integer"}},"type":"object"},"ShippingIndex":{"properties":{"changePct":{"format":"double","type":"number"},"currentValue":{"format":"double","type":"number"},"history":{"items":{"$ref":"#/components/schemas/ShippingRatePoint"},"type":"array"},"indexId":{"type":"string"},"name":{"type":"string"},"previousValue":{"format":"double","type":"number"},"spikeAlert":{"type":"boolean"},"unit":{"type":"string"}},"type":"object"},"ShippingRatePoint":{"properties":{"date":{"type":"string"},"value":{"format":"double","type":"number"}},"type":"object"},"ShippingStressCarrier":{"description":"ShippingStressCarrier represents market stress data for a carrier or shipping index.","properties":{"carrierType":{"description":"Carrier type: \"etf\" | \"carrier\" | \"index\".","type":"string"},"changePct":{"description":"Percentage change from previous close.","format":"double","type":"number"},"name":{"description":"Human-readable name.","type":"string"},"price":{"description":"Current price.","format":"double","type":"number"},"sparkline":{"items":{"description":"30-day price sparkline.","format":"double","type":"number"},"type":"array"},"symbol":{"description":"Ticker or identifier (e.g., \"BDRY\", \"ZIM\").","type":"string"}},"type":"object"},"StrategicProduct":{"properties":{"hs4":{"type":"string"},"label":{"type":"string"},"primaryChokepointId":{"type":"string"},"topExporterIso2":{"type":"string"},"topExporterShare":{"format":"double","type":"number"},"totalValueUsd":{"format":"double","type":"number"}},"type":"object"},"TransitDayCount":{"properties":{"capContainer":{"format":"double","type":"number"},"capDryBulk":{"format":"double","type":"number"},"capGeneralCargo":{"format":"double","type":"number"},"capRoro":{"format":"double","type":"number"},"capTanker":{"format":"double","type":"number"},"cargo":{"format":"int32","type":"integer"},"container":{"format":"int32","type":"integer"},"date":{"type":"string"},"dryBulk":{"format":"int32","type":"integer"},"generalCargo":{"format":"int32","type":"integer"},"other":{"format":"int32","type":"integer"},"roro":{"format":"int32","type":"integer"},"tanker":{"format":"int32","type":"integer"},"total":{"format":"int32","type":"integer"}},"type":"object"},"TransitSummary":{"properties":{"disruptionPct":{"format":"double","type":"number"},"history":{"items":{"$ref":"#/components/schemas/TransitDayCount"},"type":"array"},"incidentCount7d":{"format":"int32","type":"integer"},"riskLevel":{"type":"string"},"riskReportAction":{"type":"string"},"riskSummary":{"type":"string"},"todayCargo":{"format":"int32","type":"integer"},"todayOther":{"format":"int32","type":"integer"},"todayTanker":{"format":"int32","type":"integer"},"todayTotal":{"format":"int32","type":"integer"},"wowChangePct":{"format":"double","type":"number"}},"type":"object"},"ValidationError":{"description":"ValidationError is returned when request validation fails. It contains a list of field violations describing what went wrong.","properties":{"violations":{"description":"List of validation violations","items":{"$ref":"#/components/schemas/FieldViolation"},"type":"array"}},"required":["violations"],"type":"object"}}},"info":{"title":"SupplyChainService API","version":"1.0.0"},"openapi":"3.1.0","paths":{"/api/supply-chain/v1/get-bypass-options":{"get":{"description":"GetBypassOptions returns ranked bypass corridors for a chokepoint. PRO-gated.","operationId":"GetBypassOptions","parameters":[{"in":"query","name":"chokepointId","required":false,"schema":{"type":"string"}},{"description":"container | tanker | bulk | roro (default: \"container\")","in":"query","name":"cargoType","required":false,"schema":{"type":"string"}},{"description":"0-100, percent of capacity blocked (default: 100)","in":"query","name":"closurePct","required":false,"schema":{"format":"int32","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetBypassOptionsResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}},"description":"Validation error"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error response"}},"summary":"GetBypassOptions","tags":["SupplyChainService"]}},"/api/supply-chain/v1/get-chokepoint-status":{"get":{"operationId":"GetChokepointStatus","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetChokepointStatusResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}},"description":"Validation error"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error response"}},"summary":"GetChokepointStatus","tags":["SupplyChainService"]}},"/api/supply-chain/v1/get-country-chokepoint-index":{"get":{"description":"GetCountryChokepointIndex returns per-chokepoint exposure scores for a country. PRO-gated.","operationId":"GetCountryChokepointIndex","parameters":[{"description":"ISO 3166-1 alpha-2 country code (uppercase).","in":"query","name":"iso2","required":false,"schema":{"type":"string"}},{"description":"HS2 chapter (2-digit string). Defaults to \"27\" (energy/mineral fuels) when absent.","in":"query","name":"hs2","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCountryChokepointIndexResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}},"description":"Validation error"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error response"}},"summary":"GetCountryChokepointIndex","tags":["SupplyChainService"]}},"/api/supply-chain/v1/get-country-cost-shock":{"get":{"description":"GetCountryCostShock returns cost shock and war risk data for a country+chokepoint. PRO-gated.","operationId":"GetCountryCostShock","parameters":[{"in":"query","name":"iso2","required":false,"schema":{"type":"string"}},{"in":"query","name":"chokepointId","required":false,"schema":{"type":"string"}},{"description":"HS2 chapter (default: \"27\")","in":"query","name":"hs2","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCountryCostShockResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}},"description":"Validation error"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error response"}},"summary":"GetCountryCostShock","tags":["SupplyChainService"]}},"/api/supply-chain/v1/get-critical-minerals":{"get":{"operationId":"GetCriticalMinerals","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCriticalMineralsResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}},"description":"Validation error"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error response"}},"summary":"GetCriticalMinerals","tags":["SupplyChainService"]}},"/api/supply-chain/v1/get-route-explorer-lane":{"get":{"description":"GetRouteExplorerLane returns the primary maritime route, chokepoint exposures,\n bypass options with geometry, war risk, and static transit/freight estimates for\n a country pair + HS2 + cargo type. PRO-gated. Wraps the route-intelligence vendor\n endpoint's compute with browser-callable auth and adds fields needed by the\n Route Explorer UI.","operationId":"GetRouteExplorerLane","parameters":[{"in":"query","name":"fromIso2","required":false,"schema":{"type":"string"}},{"in":"query","name":"toIso2","required":false,"schema":{"type":"string"}},{"description":"HS2 chapter code, e.g. \"27\", \"85\"","in":"query","name":"hs2","required":false,"schema":{"type":"string"}},{"description":"One of: container, tanker, bulk, roro","in":"query","name":"cargoType","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetRouteExplorerLaneResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}},"description":"Validation error"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error response"}},"summary":"GetRouteExplorerLane","tags":["SupplyChainService"]}},"/api/supply-chain/v1/get-route-impact":{"get":{"operationId":"GetRouteImpact","parameters":[{"in":"query","name":"fromIso2","required":false,"schema":{"type":"string"}},{"in":"query","name":"toIso2","required":false,"schema":{"type":"string"}},{"in":"query","name":"hs2","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetRouteImpactResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}},"description":"Validation error"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error response"}},"summary":"GetRouteImpact","tags":["SupplyChainService"]}},"/api/supply-chain/v1/get-sector-dependency":{"get":{"description":"GetSectorDependency returns dependency flags and risk profile for a country+HS2 sector. PRO-gated.","operationId":"GetSectorDependency","parameters":[{"in":"query","name":"iso2","required":false,"schema":{"type":"string"}},{"description":"HS2 chapter code, e.g. \"27\" (mineral fuels), \"85\" (electronics)","in":"query","name":"hs2","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSectorDependencyResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}},"description":"Validation error"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error response"}},"summary":"GetSectorDependency","tags":["SupplyChainService"]}},"/api/supply-chain/v1/get-shipping-rates":{"get":{"operationId":"GetShippingRates","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetShippingRatesResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}},"description":"Validation error"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error response"}},"summary":"GetShippingRates","tags":["SupplyChainService"]}},"/api/supply-chain/v1/get-shipping-stress":{"get":{"description":"GetShippingStress returns carrier market data and a composite stress index.","operationId":"GetShippingStress","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetShippingStressResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}},"description":"Validation error"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error response"}},"summary":"GetShippingStress","tags":["SupplyChainService"]}}}}