feat(trade): add US Treasury customs revenue to Trade Policy panel (#1663)

* feat(trade): add US Treasury customs revenue to Trade Policy panel

US customs duties revenue spiked 4-5x under Trump tariffs (from
$7B/month to $27-31B/month) but the WTO tariff data only goes to
2024. Adds Treasury MTS data showing monthly customs revenue.

- Add GetCustomsRevenue RPC (proto, handler, cache tier)
- Add Treasury fetch to seed-supply-chain-trade.mjs (free API, no key)
- Add Revenue tab to TradePolicyPanel with FYTD YoY comparison
- Fix WTO gate: per-tab gating so Revenue works without WTO key
- Wire bootstrap hydration, health, seed-health tracking

* test(trade): add customs revenue feature tests

22 structural tests covering:
- Handler: raw key mode, empty-cache behavior, correct Redis key
- Seed: Treasury API URL, classification filter, timeout, row
  validation, amount conversion, sort order, seed-meta naming
- Panel: WTO gate fix (per-tab not panel-wide), revenue tab
  defaults when WTO key missing, dynamic FYTD comparison
- Client: no WTO feature gate, bootstrap hydration, type exports

* fix(trade): align FYTD comparison by fiscal month count

Prior FY comparison was filtering by calendar month, which compared
5 months of FY2026 (Oct-Feb) against only 2 months of FY2025
(Jan-Feb), inflating the YoY percentage. Now takes the first N
months of the prior FY matching the current FY month count.

* fix(trade): register treasury_revenue DataSourceId and localize revenue tab

- Add treasury_revenue to DataSourceId union type so freshness
  tracking actually works (was silently ignored)
- Register in data-freshness.ts source config + gap messages
- Add i18n keys: revenue tab label, empty state, unavailable banner
- Update infoTooltip to include Revenue tab description

* fix(trade): complete revenue tab localization

Use t() for all remaining hardcoded strings: footer source labels,
FYTD summary headline, prior-year comparison, and table column
headers. Wire the fytdLabel/vsPriorFy keys that were added but
not used.

* fix(test): update revenue source assertion for localized string
This commit is contained in:
Elie Habib
2026-03-15 19:04:23 +04:00
committed by GitHub
parent cfab17d0f1
commit 4c11b46be3
22 changed files with 537 additions and 32 deletions

View File

@@ -187,6 +187,32 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/trade/v1/get-customs-revenue:
get:
tags:
- TradeService
summary: GetCustomsRevenue
description: Get US customs duties revenue (Treasury MTS data, seeded by Railway).
operationId: GetCustomsRevenue
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetCustomsRevenueResponse'
"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:
@@ -459,3 +485,37 @@ components:
type: string
description: WTO source document URL (must be http/https protocol).
description: SPS or TBT trade barrier notification.
GetCustomsRevenueRequest:
type: object
GetCustomsRevenueResponse:
type: object
properties:
months:
type: array
items:
$ref: '#/components/schemas/CustomsRevenueMonth'
fetchedAt:
type: string
upstreamUnavailable:
type: boolean
CustomsRevenueMonth:
type: object
properties:
recordDate:
type: string
fiscalYear:
type: integer
format: int32
calendarYear:
type: integer
format: int32
calendarMonth:
type: integer
format: int32
monthlyAmountBillions:
type: number
format: double
fytdAmountBillions:
type: number
format: double
description: Monthly US customs duties revenue from Treasury MTS data.