Skip to content

feat(commodity): gold layer enhancements#2464

Merged
koala73 merged 7 commits intomainfrom
feat/gold-layer-commodity-variant
Mar 29, 2026
Merged

feat(commodity): gold layer enhancements#2464
koala73 merged 7 commits intomainfrom
feat/gold-layer-commodity-variant

Conversation

@koala73
Copy link
Copy Markdown
Owner

@koala73 koala73 commented Mar 29, 2026

Summary

  • Added 10 missing major gold mines to the commodity map mining layer (Muruntau, Kibali, Sukhoi Log, Ahafo, Loulo-Gounkoto, South Deep, Kumtor, Yanacocha, Cerro Negro, Tropicana)
  • Added 2 direct gold RSS feeds to the gold-silver panel (Gold Silver Worlds + FX Empire Gold)
  • Added 9 FX pairs to shared/commodities.json for auto-seeding (EURUSD, GBPUSD, USDJPY, USDCNY, USDINR, AUDUSD, USDCHF, USDCAD, USDTRY)
  • Fixed commodity variant AI brief: title now shows "⛏️ COMMODITY BRIEF", headline pool filtered to commodity/gold/mining/energy categories
  • Added XAU multi-currency widget to CommoditiesPanel showing live gold price in EUR, GBP, JPY, CNY, INR, AUD, CHF, CAD, TRY (computed from existing GC=F + the 9 new FX pairs)

Motivation

Reviewed Yazan-Abuawwad/gold-monitor fork (independent Angular/Spring Boot gold layer). Identified 4 concrete gaps vs our commodity variant: missing mines, missing feeds, generic brief title/categories, no cross-currency gold pricing. All changes are additive and commodity-variant-isolated.

Gold Standard Compliance

  • No new seeder scripts. All new FX symbols ride existing seedCommodityQuotes() 5-min cycle
  • All =X forex symbols added to YAHOO_ONLY_SYMBOLS in both server/worldmonitor/market/v1/_shared.ts and ais-relay.cjs
  • TTL inherited from existing MARKET_SEED_TTL = 7200 (2h, 24x the 5-min interval)
  • No 4-file bootstrap checklist changes needed: new symbols route through existing market:commodities-bootstrap:v1 key

Testing

  • npm run typecheck + npm run typecheck:api clean
  • npm run test:data passes (84/84, including bootstrap key parity check)
  • All lint checks pass (biome, boundaries, MD, edge bundles)

Post-Deploy Monitoring & Validation

  • Logs to watch: Railway ais-relay logs for [Yahoo] EURUSD=X etc. on next seed cycle (~5min after deploy)
  • Redis keys: market:commodities-bootstrap:v1 should contain 32 symbols vs previous 23
  • Expected healthy signal: All =X symbols return non-null prices; relay logs show no consecutive failure runs
  • Failure signal: 5+ consecutive Yahoo failures on FX symbols triggers circuit break in fetchYahooQuotesBatch(). If triggered, FX symbols return null and XAU widget shows --. Rollback: remove FX symbols from shared/commodities.json
  • Validation window: 1 seed cycle (5 min) post-deploy
  • Finance/full/tech variants: No change. All 4 phases are SITE_VARIANT === 'commodity' guarded

Plan

docs/plans/2026-03-29-001-feat-gold-layer-commodity-variant-plan.md


🤖 Generated with Claude Sonnet 4.6 via Claude Code (https://claude.ai/claude-code) + Compound Engineering v2.40.0

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Enrich the commodity variant with learnings from Yazan-Abuawwad/gold-monitor fork:

- Add 10 missing gold mines to MINING_SITES: Muruntau (world's largest
  open-pit gold mine), Kibali (DRC), Sukhoi Log (Russia, development),
  Ahafo (Ghana), Loulo-Gounkoto (Mali), South Deep (SA), Kumtor
  (Kyrgyzstan), Yanacocha (Peru), Cerro Negro (Argentina), Tropicana
  (Australia). Covers ~40% of top-20 global mines previously absent.

- Add XAUUSD=X spot gold and 9 FX pairs (EUR, GBP, JPY, CNY, INR, AUD,
  CHF, CAD, TRY) to shared/commodities.json. All =X symbols auto-seeded
  via existing seedCommodityQuotes() — no new seeder needed. Registered
  in YAHOO_ONLY_SYMBOLS in both _shared.ts and ais-relay.cjs.

- Add XAU/FX tab to CommoditiesPanel showing gold priced in 10 currencies.
  Computed live from GC=F * FX rates. Commodity variant only.

- Fix InsightsPanel brief title: commodity variant now shows
  "⛏️ COMMODITY BRIEF" instead of "🌍 WORLD BRIEF".

- Route commodity variant daily market brief to commodity feed categories
  (commodity-news, gold-silver, mining-news, energy, critical-minerals)
  via new newsCategories option on BuildDailyMarketBriefOptions.

- Add Gold Silver Worlds + FX Empire Gold direct RSS feeds to gold-silver
  panel (9 sources total, up from 7).
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 29, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
worldmonitor Ready Ready Preview, Comment Mar 29, 2026 7:14am

Request Review

@mintlify
Copy link
Copy Markdown

mintlify bot commented Mar 29, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
WorldMonitor 🟢 Ready View Preview Mar 29, 2026, 5:44 AM

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Mar 29, 2026

Greptile Summary

This PR enriches WorldMonitor's commodity variant with four additive improvements reviewed from the Yazan-Abuawwad/gold-monitor fork: 10 missing major gold mine markers (Muruntau, Kibali, Sukhoi Log, etc.), 2 direct gold RSS feeds, a commodity-aware AI brief title and headline categories, and a new XAU multi-currency widget in CommoditiesPanel. All changes are correctly gated on SITE_VARIANT === 'commodity' with zero impact on finance/full/tech variants.

Key observations:

  • FX direction logic is correct: all 9 multiply flags in XAU_CURRENCY_CONFIG correctly reflect Yahoo Finance symbol conventions (EURUSD=X → divide, USDJPY=X → multiply, etc.)
  • Symbol routing is clean: ais-relay.cjs reuses the existing =F spread-filter pattern to auto-include =X symbols in YAHOO_ONLY, and _shared.ts is updated in lockstep
  • MineralType: 'Gold' casing matches the TypeScript union — no type errors introduced
  • XAUUSD=X spot gold is seeded but never rendered in the current implementation; _renderXau() uses GC=F (futures) as the base price, so the spot symbol adds a Yahoo API call every 5 min with no user-facing benefit today (see inline comment)
  • Empty XAU grid state: when hasXau is true but all FX pairs return null, _renderXau() renders an empty grid rather than the -- fallback described in the PR monitoring notes (see inline comment)

Confidence Score: 5/5

Safe to merge — all findings are P2 quality-of-life improvements; no correctness, data-integrity, or security issues introduced.

All four feature phases are implemented correctly and fully isolated to the commodity variant. The FX arithmetic, symbol formats, type usage, and seeder wiring are all correct. Two P2 observations remain (unused XAUUSD=X seeding, missing empty-state in XAU grid), but neither constitutes a present defect that affects users.

src/components/MarketPanel.ts and scripts/shared/commodities.json — the unused XAUUSD=X symbol and missing empty-state for the XAU grid are worth a follow-up, but neither blocks merge.

Important Files Changed

Filename Overview
src/components/MarketPanel.ts Adds XAU/FX tab to CommoditiesPanel with cross-currency gold pricing; FX direction (multiply flag) and symbol format are correct for all 9 pairs; empty-state when all FX pairs are null is missing (P2).
scripts/shared/commodities.json Adds XAUUSD=X spot gold and 9 FX pairs to the commodity seeder list; XAUUSD=X is seeded but not currently rendered in any UI component (P2).
shared/commodities.json Identical change to scripts/shared/commodities.json — both files kept in sync as required by the dual-consumer pattern (frontend + ais-relay).
server/worldmonitor/market/v1/_shared.ts Adds all 10 new symbols (XAUUSD=X + 9 FX pairs) to YAHOO_ONLY_SYMBOLS; consistent with ais-relay's dynamic filter using .endsWith('=X').
scripts/ais-relay.cjs Extends YAHOO_ONLY set via dynamic spread filter for =X symbols — elegant reuse of the same pattern already used for =F futures; no seeder logic changes needed.
src/config/commodity-geo.ts Adds 10 missing major gold mines (Muruntau, Kibali, Sukhoi Log, etc.) using the correct MineralType: 'Gold' casing; all entries follow existing MineSite schema with operator, annualOutput, and status fields.
src/config/feeds.ts Adds 2 direct gold RSS feeds (Gold Silver Worlds, FX Empire Gold) to gold-silver block; uses rss() alias (= rssProxyUrl) consistently with all other feeds in the file.
src/components/InsightsPanel.ts Adds "⛏️ COMMODITY BRIEF" title variant and commodity-specific geoContext string for the AI prompt; correctly gated on SITE_VARIANT === 'commodity', no regressions for other variants.
src/services/daily-market-brief.ts Makes collectHeadlinePool accept an optional categories override so commodity variant gets gold/mining/energy headlines; backwards-compatible — non-commodity variants fall back to BRIEF_NEWS_CATEGORIES.
src/app/data-loader.ts Passes symbol through mapCommodity (needed by XAU widget lookups) and supplies variant-aware newsCategories to the daily brief builder.

Sequence Diagram

sequenceDiagram
    participant Relay as ais-relay.cjs
    participant Yahoo as Yahoo Finance
    participant Redis as Redis<br/>(market:commodities-bootstrap:v1)
    participant DL as DataLoaderManager
    participant CP as CommoditiesPanel
    participant IP as InsightsPanel

    Relay->>Yahoo: fetchYahooQuotesBatch([GC=F, XAUUSD=X, EURUSD=X … 9 FX pairs])
    Yahoo-->>Relay: quotes[]
    Relay->>Redis: SET market:commodities-bootstrap:v1 (TTL 2h)

    DL->>Redis: GET commodityQuotes (hydration)
    Redis-->>DL: quotes[] incl. GC=F + FX pairs
    DL->>DL: mapCommodity() → adds symbol field
    DL->>CP: renderCommodities([{symbol,display,price,…}])
    Note over CP: Metals tab: filters out =X symbols<br/>XAU/FX tab: computes XAU_FC = GC=F price × or ÷ FX rate

    DL->>IP: buildDailyMarketBrief({ newsCategories: ['commodity-news','gold-silver',…] })
    IP->>IP: geoContext = 'You are generating a commodities market brief…'
    IP-->>IP: render "⛏️ COMMODITY BRIEF"
Loading

Reviews (1): Last reviewed commit: "feat(commodity): add gold layer enhancem..." | Re-trigger Greptile

{ "symbol": "^VIX", "name": "VIX", "display": "VIX" },
{ "symbol": "GC=F", "name": "Gold", "display": "GOLD" },
{ "symbol": "XAUUSD=X", "name": "Gold Spot", "display": "XAU SPOT" },
{ "symbol": "SI=F", "name": "Silver", "display": "SILVER" },
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 XAUUSD=X seeded but never rendered

XAUUSD=X is added to both commodities.json files and YAHOO_ONLY_SYMBOLS in _shared.ts, meaning it is fetched every 5-minute seed cycle. However, it is never actually displayed anywhere in the current implementation: _renderXau() in MarketPanel.ts uses GC=F (futures) as the base gold price, and the metals grid explicitly excludes all =X symbols via:

const validData = this._commodityData.filter(
  (d) => d.price !== null && !d.symbol?.endsWith('=X'),
);

The plan mentions enabling a future "futures vs spot basis spread" display, which is a good motivation — but as shipped, XAUUSD=X consumes one of the ~49 safe Yahoo Finance API slots per cycle with no user-facing benefit. Consider either wiring the spot/futures spread into _renderXau() now, or deferring the symbol addition until it is actually used.

- Fix USDCHF=X multiply direction: was true (wrong), now false (USD/CHF is USD-per-CHF convention)
- Fix newsCategories augments BRIEF_NEWS_CATEGORIES instead of replacing (preserves macro/Fed context in commodity brief)
- Add goldsilverworlds.com + www.fxempire.com to RSS allowlist (api + shared + scripts/shared)
- Rename "Metals" tab label conditionally: commodity variant gets "Metals", others keep "Commodities"
- Reset _tab to "commodities" when hasXau becomes false (prevent stale XAU tab re-activation)
- Add Number.isFinite() guard in _renderXau() before computing xauPrice
- Narrow fxMap filter to =X symbols only
- Collapse redundant two-branch number formatter to Math.round().toLocaleString()
- Remove XAUUSD=X from shared/commodities.json: seeded but never displayed (saves 150ms/cycle)
@koala73 koala73 changed the title feat(commodity): gold layer enhancements from fork review feat(commodity): gold layer enhancements Mar 29, 2026
XAU widget uses GC=F as base price, not XAUUSD=X. Symbol was never
seeded (not in commodities.json) and never referenced in the UI.
@koala73 koala73 merged commit ba54dc1 into main Mar 29, 2026
7 of 8 checks passed
@koala73 koala73 deleted the feat/gold-layer-commodity-variant branch March 29, 2026 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant