Files
worldmonitor/docs/api/EconomicService.openapi.yaml
Elie Habib c658b8eb94 feat(economic): National Debt Clock — live ticking debt estimates for 180+ countries (#1923)
* feat(economic): add National Debt Clock panel with IMF + Treasury data

- Proto: GetNationalDebt RPC in EconomicService with NationalDebtEntry message
- Seed: seed-national-debt.mjs fetches IMF WEO (debt%, GDP, deficit%) + US Treasury FiscalData in parallel; filters aggregates/territories; sorts by total debt; 35-day TTL for monthly Railway cron
- Handler: get-national-debt.ts reads seeded Redis cache key economic:national-debt:v1
- Registry: nationalDebt key added to cache-keys.ts, bootstrap.js (SLOW tier), health.js (maxStaleMin=10080), gateway.ts (daily cache tier)
- Service: getNationalDebtData() in economic/index.ts with bootstrap hydration + RPC fallback
- Panel: NationalDebtPanel.ts with sort tabs (Total/Debt-GDP/1Y Growth), search, live ticking via direct DOM manipulation (avoids setContent debounce)
- Tests: 10 seed formula tests + 8 ticker math tests; all 2064 suite tests green

* fix(economic): address code review findings for national debt clock

* fix(economic): guard runSeed() call to prevent process.exit in test imports

seed-national-debt.mjs called runSeed() at module top-level. When imported
by tests (to access computeEntries), the seed ran, hit missing Redis creds
in CI, and called process.exit(1), failing the entire test suite.

Guard with isMain check so runSeed() only fires on direct execution.
2026-03-20 16:08:48 +04:00

970 lines
39 KiB
YAML

openapi: 3.1.0
info:
title: EconomicService API
version: 1.0.0
paths:
/api/economic/v1/get-fred-series:
get:
tags:
- EconomicService
summary: GetFredSeries
description: GetFredSeries retrieves time series data from the Federal Reserve Economic Data.
operationId: GetFredSeries
parameters:
- name: series_id
in: query
description: FRED series ID (e.g., "GDP", "UNRATE", "CPIAUCSL").
required: false
schema:
type: string
- name: limit
in: query
description: Maximum number of observations to return. Defaults to 120.
required: false
schema:
type: integer
format: int32
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetFredSeriesResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/economic/v1/list-world-bank-indicators:
get:
tags:
- EconomicService
summary: ListWorldBankIndicators
description: ListWorldBankIndicators retrieves development indicator data from the World Bank.
operationId: ListWorldBankIndicators
parameters:
- name: indicator_code
in: query
description: World Bank indicator code (e.g., "NY.GDP.MKTP.CD").
required: false
schema:
type: string
- name: country_code
in: query
description: Optional country filter (ISO 3166-1 alpha-2).
required: false
schema:
type: string
- name: year
in: query
description: Optional year filter. Defaults to latest available.
required: false
schema:
type: integer
format: int32
- name: page_size
in: query
description: Maximum items per page.
required: false
schema:
type: integer
format: int32
- name: cursor
in: query
description: Cursor for next page.
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/ListWorldBankIndicatorsResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/economic/v1/get-energy-prices:
get:
tags:
- EconomicService
summary: GetEnergyPrices
description: GetEnergyPrices retrieves current energy commodity prices from EIA.
operationId: GetEnergyPrices
parameters:
- name: commodities
in: query
description: Optional commodity filter. Empty returns all tracked commodities.
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetEnergyPricesResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/economic/v1/get-macro-signals:
get:
tags:
- EconomicService
summary: GetMacroSignals
description: GetMacroSignals computes 7 macro signals from 6 upstream sources with BUY/CASH verdict.
operationId: GetMacroSignals
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetMacroSignalsResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/economic/v1/get-energy-capacity:
get:
tags:
- EconomicService
summary: GetEnergyCapacity
description: GetEnergyCapacity retrieves installed capacity data (solar, wind, coal) from EIA.
operationId: GetEnergyCapacity
parameters:
- name: energy_sources
in: query
description: |-
Energy source codes to query (e.g., "SUN", "WND", "COL").
Empty returns all tracked sources (SUN, WND, COL).
required: false
schema:
type: string
- name: years
in: query
description: Number of years of historical data. Default 20 if not set.
required: false
schema:
type: integer
format: int32
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetEnergyCapacityResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/economic/v1/get-bis-policy-rates:
get:
tags:
- EconomicService
summary: GetBisPolicyRates
description: GetBisPolicyRates retrieves central bank policy rates from BIS.
operationId: GetBisPolicyRates
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetBisPolicyRatesResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/economic/v1/get-bis-exchange-rates:
get:
tags:
- EconomicService
summary: GetBisExchangeRates
description: GetBisExchangeRates retrieves effective exchange rates from BIS.
operationId: GetBisExchangeRates
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetBisExchangeRatesResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/economic/v1/get-bis-credit:
get:
tags:
- EconomicService
summary: GetBisCredit
description: GetBisCredit retrieves credit-to-GDP ratio data from BIS.
operationId: GetBisCredit
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetBisCreditResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/economic/v1/get-fred-series-batch:
post:
tags:
- EconomicService
summary: GetFredSeriesBatch
description: GetFredSeriesBatch retrieves multiple FRED series in a single call.
operationId: GetFredSeriesBatch
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GetFredSeriesBatchRequest'
required: true
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetFredSeriesBatchResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/economic/v1/get-national-debt:
get:
tags:
- EconomicService
summary: GetNationalDebt
description: GetNationalDebt retrieves national debt clock data for all countries.
operationId: GetNationalDebt
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetNationalDebtResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
schemas:
Error:
type: object
properties:
message:
type: string
description: Error message (e.g., 'user not found', 'database connection failed')
description: Error is returned when a handler encounters an error. It contains a simple error message that the developer can customize.
FieldViolation:
type: object
properties:
field:
type: string
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')
description:
type: string
description: Human-readable description of the validation violation (e.g., 'must be a valid email address', 'required field missing')
required:
- field
- description
description: FieldViolation describes a single validation error for a specific field.
ValidationError:
type: object
properties:
violations:
type: array
items:
$ref: '#/components/schemas/FieldViolation'
description: List of validation violations
required:
- violations
description: ValidationError is returned when request validation fails. It contains a list of field violations describing what went wrong.
GetFredSeriesRequest:
type: object
properties:
seriesId:
type: string
minLength: 1
description: FRED series ID (e.g., "GDP", "UNRATE", "CPIAUCSL").
limit:
type: integer
format: int32
description: Maximum number of observations to return. Defaults to 120.
required:
- seriesId
description: GetFredSeriesRequest specifies which FRED series to retrieve.
GetFredSeriesResponse:
type: object
properties:
series:
$ref: '#/components/schemas/FredSeries'
description: GetFredSeriesResponse contains the requested FRED series data.
FredSeries:
type: object
properties:
seriesId:
type: string
minLength: 1
description: Series identifier (e.g., "GDP", "UNRATE", "CPIAUCSL").
title:
type: string
description: Series title.
units:
type: string
description: Unit of measurement.
frequency:
type: string
description: Data frequency (e.g., "Monthly", "Quarterly").
observations:
type: array
items:
$ref: '#/components/schemas/FredObservation'
required:
- seriesId
description: FredSeries represents a FRED time series with metadata.
FredObservation:
type: object
properties:
date:
type: string
description: Observation date as YYYY-MM-DD string.
value:
type: number
format: double
description: Observation value.
description: FredObservation represents a single data point from a FRED economic series.
ListWorldBankIndicatorsRequest:
type: object
properties:
indicatorCode:
type: string
minLength: 1
description: World Bank indicator code (e.g., "NY.GDP.MKTP.CD").
countryCode:
type: string
description: Optional country filter (ISO 3166-1 alpha-2).
year:
type: integer
format: int32
description: Optional year filter. Defaults to latest available.
pageSize:
type: integer
format: int32
description: Maximum items per page.
cursor:
type: string
description: Cursor for next page.
required:
- indicatorCode
description: ListWorldBankIndicatorsRequest specifies filters for retrieving World Bank data.
ListWorldBankIndicatorsResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/WorldBankCountryData'
pagination:
$ref: '#/components/schemas/PaginationResponse'
description: ListWorldBankIndicatorsResponse contains World Bank indicator data.
WorldBankCountryData:
type: object
properties:
countryCode:
type: string
minLength: 1
description: ISO 3166-1 alpha-2 country code.
countryName:
type: string
description: Country name.
indicatorCode:
type: string
minLength: 1
description: World Bank indicator code (e.g., "NY.GDP.MKTP.CD").
indicatorName:
type: string
description: Indicator name.
year:
type: integer
format: int32
description: Data year.
value:
type: number
format: double
description: Indicator value.
required:
- countryCode
- indicatorCode
description: WorldBankCountryData represents a World Bank indicator value for a country.
PaginationResponse:
type: object
properties:
nextCursor:
type: string
description: Cursor for fetching the next page. Empty string indicates no more pages.
totalCount:
type: integer
format: int32
description: Total count of items matching the query, if known. Zero if the total is unknown.
description: PaginationResponse contains pagination metadata returned alongside list results.
GetEnergyPricesRequest:
type: object
properties:
commodities:
type: array
items:
type: string
description: Optional commodity filter. Empty returns all tracked commodities.
description: GetEnergyPricesRequest specifies which energy commodities to retrieve.
GetEnergyPricesResponse:
type: object
properties:
prices:
type: array
items:
$ref: '#/components/schemas/EnergyPrice'
description: GetEnergyPricesResponse contains energy price data.
EnergyPrice:
type: object
properties:
commodity:
type: string
minLength: 1
description: Energy commodity identifier.
name:
type: string
description: Human-readable name (e.g., "WTI Crude Oil", "Henry Hub Natural Gas").
price:
type: number
format: double
description: Current price in USD.
unit:
type: string
description: Unit of measurement (e.g., "$/barrel", "$/MMBtu").
change:
type: number
format: double
description: Percentage change from previous period.
priceAt:
type: integer
format: int64
description: 'Price date, as Unix epoch milliseconds.. Warning: Values > 2^53 may lose precision in JavaScript'
required:
- commodity
description: EnergyPrice represents a current energy commodity price from EIA.
GetMacroSignalsRequest:
type: object
description: GetMacroSignalsRequest requests the current macro signal dashboard.
GetMacroSignalsResponse:
type: object
properties:
timestamp:
type: string
description: ISO 8601 timestamp of computation.
verdict:
type: string
description: 'Overall verdict: "BUY", "CASH", or "UNKNOWN".'
bullishCount:
type: integer
format: int32
description: Number of bullish signals.
totalCount:
type: integer
format: int32
description: Total number of evaluated signals (excluding UNKNOWN).
signals:
$ref: '#/components/schemas/MacroSignals'
meta:
$ref: '#/components/schemas/MacroMeta'
unavailable:
type: boolean
description: True when upstream data is unavailable (fallback result).
description: GetMacroSignalsResponse contains the full macro signal dashboard with 7 signals and verdict.
MacroSignals:
type: object
properties:
liquidity:
$ref: '#/components/schemas/LiquiditySignal'
flowStructure:
$ref: '#/components/schemas/FlowStructureSignal'
macroRegime:
$ref: '#/components/schemas/MacroRegimeSignal'
technicalTrend:
$ref: '#/components/schemas/TechnicalTrendSignal'
hashRate:
$ref: '#/components/schemas/HashRateSignal'
priceMomentum:
$ref: '#/components/schemas/PriceMomentumSignal'
fearGreed:
$ref: '#/components/schemas/FearGreedSignal'
description: MacroSignals contains all 7 individual signal computations.
LiquiditySignal:
type: object
properties:
status:
type: string
description: '"SQUEEZE", "NORMAL", or "UNKNOWN".'
value:
type: number
format: double
description: JPY 30d ROC percentage, absent if unavailable.
sparkline:
type: array
items:
type: number
format: double
description: Last 30 JPY close prices.
description: LiquiditySignal tracks JPY 30d rate of change as a liquidity proxy.
FlowStructureSignal:
type: object
properties:
status:
type: string
description: '"PASSIVE GAP", "ALIGNED", or "UNKNOWN".'
btcReturn5:
type: number
format: double
description: BTC 5-day return percentage.
qqqReturn5:
type: number
format: double
description: QQQ 5-day return percentage.
description: FlowStructureSignal compares BTC vs QQQ 5-day returns.
MacroRegimeSignal:
type: object
properties:
status:
type: string
description: '"RISK-ON", "DEFENSIVE", or "UNKNOWN".'
qqqRoc20:
type: number
format: double
description: QQQ 20d ROC percentage.
xlpRoc20:
type: number
format: double
description: XLP 20d ROC percentage.
description: MacroRegimeSignal compares QQQ vs XLP 20-day rate of change.
TechnicalTrendSignal:
type: object
properties:
status:
type: string
description: '"BULLISH", "BEARISH", "NEUTRAL", or "UNKNOWN".'
btcPrice:
type: number
format: double
description: Current BTC price.
sma50:
type: number
format: double
description: 50-day simple moving average.
sma200:
type: number
format: double
description: 200-day simple moving average.
vwap30d:
type: number
format: double
description: 30-day volume-weighted average price.
mayerMultiple:
type: number
format: double
description: Mayer multiple (BTC price / SMA200).
sparkline:
type: array
items:
type: number
format: double
description: Last 30 BTC close prices.
description: TechnicalTrendSignal evaluates BTC price vs moving averages and VWAP.
HashRateSignal:
type: object
properties:
status:
type: string
description: '"GROWING", "DECLINING", "STABLE", or "UNKNOWN".'
change30d:
type: number
format: double
description: Hash rate change over 30 days as percentage.
description: HashRateSignal tracks Bitcoin hash rate momentum.
PriceMomentumSignal:
type: object
properties:
status:
type: string
description: '"STRONG", "MODERATE", "WEAK", or "UNKNOWN".'
description: PriceMomentumSignal uses the Mayer Multiple (price/SMA200) as a market-adaptive signal.
FearGreedSignal:
type: object
properties:
status:
type: string
description: Classification label (e.g., "Extreme Fear", "Greed").
value:
type: integer
format: int32
description: Current index value (0-100).
history:
type: array
items:
$ref: '#/components/schemas/FearGreedHistoryEntry'
description: FearGreedSignal tracks the Crypto Fear & Greed index.
FearGreedHistoryEntry:
type: object
properties:
value:
type: integer
maximum: 100
minimum: 0
format: int32
description: Index value (0-100).
date:
type: string
description: Date string (YYYY-MM-DD).
description: FearGreedHistoryEntry is a single day's Fear & Greed index reading.
MacroMeta:
type: object
properties:
qqqSparkline:
type: array
items:
type: number
format: double
description: Last 30 QQQ close prices for sparkline.
description: MacroMeta contains supplementary chart data.
GetEnergyCapacityRequest:
type: object
properties:
energySources:
type: array
items:
type: string
description: |-
Energy source codes to query (e.g., "SUN", "WND", "COL").
Empty returns all tracked sources (SUN, WND, COL).
years:
type: integer
format: int32
description: Number of years of historical data. Default 20 if not set.
GetEnergyCapacityResponse:
type: object
properties:
series:
type: array
items:
$ref: '#/components/schemas/EnergyCapacitySeries'
EnergyCapacitySeries:
type: object
properties:
energySource:
type: string
name:
type: string
data:
type: array
items:
$ref: '#/components/schemas/EnergyCapacityYear'
EnergyCapacityYear:
type: object
properties:
year:
type: integer
format: int32
capacityMw:
type: number
format: double
GetBisPolicyRatesRequest:
type: object
description: GetBisPolicyRatesRequest requests central bank policy rates.
GetBisPolicyRatesResponse:
type: object
properties:
rates:
type: array
items:
$ref: '#/components/schemas/BisPolicyRate'
description: GetBisPolicyRatesResponse contains BIS policy rate data.
BisPolicyRate:
type: object
properties:
countryCode:
type: string
description: ISO 2-letter country code (US, GB, JP, etc.)
countryName:
type: string
description: Country or region name.
rate:
type: number
format: double
description: Current policy rate percentage.
previousRate:
type: number
format: double
description: Previous period rate percentage.
date:
type: string
description: Date as YYYY-MM.
centralBank:
type: string
description: Central bank name (e.g. "Federal Reserve").
description: BisPolicyRate represents a central bank policy rate from BIS.
GetBisExchangeRatesRequest:
type: object
description: GetBisExchangeRatesRequest requests effective exchange rates.
GetBisExchangeRatesResponse:
type: object
properties:
rates:
type: array
items:
$ref: '#/components/schemas/BisExchangeRate'
description: GetBisExchangeRatesResponse contains BIS effective exchange rate data.
BisExchangeRate:
type: object
properties:
countryCode:
type: string
description: ISO 2-letter country code.
countryName:
type: string
description: Country or region name.
realEer:
type: number
format: double
description: Real effective exchange rate index.
nominalEer:
type: number
format: double
description: Nominal effective exchange rate index.
realChange:
type: number
format: double
description: Percentage change from previous period (real).
date:
type: string
description: Date as YYYY-MM.
description: BisExchangeRate represents effective exchange rate indices from BIS.
GetBisCreditRequest:
type: object
description: GetBisCreditRequest requests credit-to-GDP ratio data.
GetBisCreditResponse:
type: object
properties:
entries:
type: array
items:
$ref: '#/components/schemas/BisCreditToGdp'
description: GetBisCreditResponse contains BIS credit-to-GDP data.
BisCreditToGdp:
type: object
properties:
countryCode:
type: string
description: ISO 2-letter country code.
countryName:
type: string
description: Country or region name.
creditGdpRatio:
type: number
format: double
description: Total credit as percentage of GDP.
previousRatio:
type: number
format: double
description: Previous quarter ratio.
date:
type: string
description: Date as YYYY-QN.
description: BisCreditToGdp represents total credit as percentage of GDP from BIS.
GetFredSeriesBatchRequest:
type: object
properties:
seriesIds:
type: array
items:
type: string
maxItems: 10
minItems: 1
description: FRED series IDs (e.g., "WALCL", "FEDFUNDS"). Max 10.
maxItems: 10
minItems: 1
limit:
type: integer
format: int32
description: Maximum number of observations per series. Defaults to 120.
description: GetFredSeriesBatchRequest looks up multiple FRED series in a single call.
GetFredSeriesBatchResponse:
type: object
properties:
results:
type: object
additionalProperties:
$ref: '#/components/schemas/FredSeries'
description: Map of series_id -> FRED series for found series.
fetched:
type: integer
format: int32
description: Number of series successfully fetched.
requested:
type: integer
format: int32
description: Number of series requested.
description: GetFredSeriesBatchResponse contains the requested FRED series data.
ResultsEntry:
type: object
properties:
key:
type: string
value:
$ref: '#/components/schemas/FredSeries'
GetNationalDebtRequest:
type: object
description: GetNationalDebtRequest requests national debt data for all countries.
GetNationalDebtResponse:
type: object
properties:
entries:
type: array
items:
$ref: '#/components/schemas/NationalDebtEntry'
seededAt:
type: string
description: ISO 8601 timestamp when seed data was written.
unavailable:
type: boolean
description: True when upstream data is unavailable (fallback result).
description: GetNationalDebtResponse wraps the full list of national debt entries.
NationalDebtEntry:
type: object
properties:
iso3:
type: string
description: ISO3 country code (e.g. "USA").
debtUsd:
type: number
format: double
description: Total debt in USD at baseline_ts.
gdpUsd:
type: number
format: double
description: GDP in USD (nominal, latest year).
debtToGdp:
type: number
format: double
description: Debt as % of GDP.
annualGrowth:
type: number
format: double
description: Year-over-year debt growth percent (2023->2024).
perSecondRate:
type: number
format: double
description: Deficit-derived accrual in USD per second.
perDayRate:
type: number
format: double
description: Deficit-derived accrual in USD per day.
baselineTs:
type: string
format: int64
description: UTC ms timestamp anchoring the debt_usd figure (2024-01-01T00:00:00Z).
source:
type: string
description: Human-readable source string.
description: NationalDebtEntry holds debt data for a single country.