Overview
This map links each major Pharos data domain from upstream source to frontend consumption:
external source -> worker cron / sync -> D1 table or cache key -> API endpoint -> frontend hook -> page(s)
Core Flows
| Domain | External Sources | Worker Ingest / Compute | Storage Layer | API Surface | Frontend Hook(s) | Primary UI |
|---|---|---|---|---|---|---|
| Stablecoin core list + prices | DefiLlama, CoinGecko, CMC, DexScreener, DexPaprika, CoinGecko Onchain, Alchemy Prices, Moralis token prices, Birdeye token prices, Pyth Network, Binance, Kraken, Bitstamp, Coinbase, RedStone, GeckoTerminal pool probes, Curve on-chain, protocol redemption quotes, Chainlink FX/commodity overlays, FX sources (Frankfurter, Open Exchange Rates, fawazahmed0/currency-api, ExchangeRate-API), and gold-api.com commodity references | worker/src/cron/sync-fx-rates.ts, worker/src/cron/sync-stablecoins.ts, stage modules under worker/src/cron/sync-stablecoins/, worker/src/lib/address-price-providers/index.ts, worker/src/lib/authoritative-price-sources/, worker/src/lib/price-consensus.ts, worker/src/lib/price-validation.ts | cache keys: fx-rates, stablecoins; surface_publication_generations after migration for generic publication status | GET /api/stablecoins, GET /api/status (publicationHealth.surfaces["stablecoins"]) | useStablecoins | Homepage, Compare, Dependency Map, many cards, /status publication health |
| Aggregate stablecoin charts | DefiLlama aggregate chart history, D1 supply_history overlays for structural supplemental tracked assets, live stablecoins cache for the trailing point | worker/src/cron/sync-stablecoin-charts.ts + read-time hydration in worker/src/api/cache-handlers.ts | cache key: stablecoin-charts (+ live stablecoins cache at read time) | GET /api/stablecoin-charts | useStablecoinCharts | Homepage charts |
| Stablecoin detail history | DefiLlama detail/chart, CoinGecko fallback, supply_history fallback paths | On-demand detail handler plus worker/src/cron/snapshot-supply.ts / worker/src/api/backfill-supply-history.ts | Handler-computed detail payload, per-coin D1 cache, supply_history | GET /api/stablecoin/:id for public detail-prefetch/API consumers; GET /api/supply-history for chart history | Detail page view model composes useSupplyHistory, useStablecoins, peg/liquidity/report-card/redemption/yield/stress/flow/blacklist/reserve hooks; usePrefetchStablecoin uses /api/stablecoin/:id for hover prefetch | Stablecoin detail market chart, Compare |
| Per-coin supply history | Cached stablecoins payload snapshot, CoinGecko or DefiLlama backfills | worker/src/cron/snapshot-supply.ts, worker/src/api/backfill-supply-history.ts | supply_history | GET /api/supply-history | useSupplyHistory, useCompareDataModel | Stablecoin detail page, Compare |
| Depeg events + peg summary | Stablecoin cache prices + DEX corroboration | worker/src/cron/detect-depegs.ts (+ pending confirmation) | depeg_events, depeg_pending | GET /api/depeg-events, GET /api/peg-summary | useInfiniteDepegEvents, usePegSummary | Depeg page, homepage peg columns, detail cards |
| Depeg Duration Resolver + Reviewer | Confirmed canonical depeg incidents, stablecoin metadata, supply history, DEWS, liquidity, redemption backstops, first-publication manifests, errata, and later canonical outcomes | worker/src/cron/compute-depeg-resolver.ts plus worker/src/cron/compute-depeg-resolver-review.ts helper after DDRv2 sealing/publication | DDRv2 incident/link/lock-state/public-prediction/publication/errata tables, depeg_resolver_assessments, cache["depeg-resolver:snapshot"], cache["depeg-resolver-review:snapshot"], cache["ddr:repair-debt:v1"], worker_repair_tasks (ddr-repair-required-event) | GET /api/depeg-resolver, GET /api/depeg-resolver-review, GET /api/status (dataQuality.repairDebt) | useDepegResolver, useDepegResolverReview | Depeg page DDR and DDRR modules, /status repair-debt diagnostics |
| DEX liquidity + DEX implied prices | DefiLlama Yields, DefiLlama Protocols, Curve, Uniswap/Aerodrome/PancakeSwap subgraphs, protocol-native APIs (Fluid, Balancer, Raydium, Orca, Meteora), Fluid DexReservesResolver on supported EVM chains, Aerodrome/Velodrome Slipstream Sugar view contracts on Base/Optimism, plus CG/GT/DexScreener/CG Tickers -> [discovery cron] -> dex_pool_staging (D1) | worker/src/cron/dex-discovery/orchestrator.ts (t1/t2/t3 tiered priority + exponential backoff, staleness sorting + live FX/metal validation refs) and worker/src/cron/dex-liquidity/* orchestrator merge (max(0.5, 1 - ageHours / 48) confidence decay, pools older than 24h dropped entirely + live FX/metal validation refs); GeckoTerminal request/parse normalization is shared in worker/src/cron/dex-liquidity/geckoterminal-shared.ts; direct/API/subgraph/view-contract fetchers (fetch-fluid.ts, fetch-balancer.ts, fetch-raydium.ts, fetch-orca.ts, fetch-meteora.ts, fetch-pancakeswap.ts, fetch-slipstream.ts) run during Step 1 of syncDexLiquidity() through worker/src/lib/provider-execution.ts lane/provider policies, normalized via DexApiPool type (worker/src/lib/dex-api-common.ts), preferred over overlapping DL pools only when identity is exact/uniquely derived and either measured 24h volume exists or the trusted Slipstream source exposes no volume field, source family direct_api | dex_pool_staging -> dex_liquidity_run_rows / dex_liquidity_publication_generations -> published dex_liquidity, plus dex_liquidity_history, dex_prices, per-source cache["circuit:<source>"] breaker rows aggregated on read into providerCircuitHealth | GET /api/dex-liquidity, GET /api/dex-liquidity-history, GET /api/status (publicationHealth.surfaces["dex-liquidity"], providerCircuitHealth, dependencyHealth.dependencies["dex-liquidity"]) | useDexLiquidity, useDexLiquidityHistory | Liquidity page, Compare, report-card inputs, /status liquidity health, provider-circuit health, publication-health, and dependency root-cause cards |
| Blacklist / freeze tracker | Etherscan v2, TronGrid, RPC providers, frozen operator recovery manifests | worker/src/cron/sync-blacklist.ts + helper modules under worker/src/cron/blacklist/; guarded one-off recovery in worker/scripts/reconcile-night-watch-blacklist.ts | blacklist_events, typed/generation-fenced blacklist_sync_state, blacklist_current_balances, blacklist_amount_repair_queue, blacklist_provider_scan_telemetry, blacklist_reconciliation_runs | GET /api/blacklist, GET /api/blacklist-summary, GET /api/status (dataQuality.blacklistReconciliation) | useBlacklistEventsPage, useBlacklistSummary | FreezeWatch page, public/admin recovery diagnostics |
| Mint/Burn flow tracker | Alchemy logs (configured issuance chains; currently Ethereum plus native Arbitrum for USDai) | worker/src/cron/sync-mint-burn.ts + worker/src/cron/mint-burn/run-state.ts, slot dispatch via worker/src/handlers/scheduled/mint-burn-slot.ts | mint_burn_events, mint_burn_hourly, mint_burn_sync_state | GET /api/mint-burn-flows, GET /api/mint-burn-events | useMintBurnFlows, useMintBurnFlowsCoin, useMintBurnEvents | Flows page, homepage flow snapshot, coin overlays |
| Live reserve composition | Protocol reserve APIs, dashboards, and on-chain/accounting reads via adapter-specific fetches | worker/src/cron/sync-live-reserves.ts; isolated recovery in worker/src/handlers/scheduled/reserve-recovery.ts | reserve_composition, reserve_sync_state, generation-fenced worker_scheduled_checkpoints | GET /api/stablecoin-reserves/:id, GET /api/report-cards, GET /api/status | useStablecoinReserves, useReportCards | Stablecoin detail reserve card, report-card collateral quality inputs, reserve-drift/status surfaces |
| Redemption backstops + effective exit | Stablecoin cache, DEX liquidity snapshot, live reserve-sync metadata, and redeemability config registry | worker/src/cron/sync-redemption-backstops.ts | redemption_backstop, redemption_backstop_history | GET /api/redemption-backstops, GET /api/report-cards | useRedemptionBackstops, useReportCards | Stablecoin detail redemption card, report-card liquidity inputs |
| Stability Index (PSI) | Stablecoin cache + active depeg state + DEWS stress breadth | worker/src/cron/stability-index.ts, daily worker/src/cron/snapshot-psi.ts | stability_index_samples, stability_index | GET /api/stability-index, GET /api/status (publicationHealth.surfaces["psi"], dependencyHealth.dependencies["psi"]) | useStabilityIndex, useStabilityIndexDetail | Stability Index pages, digest snapshot, /status publication/dependency health |
| DEWS stress signals | Stablecoins + liquidity + blacklist + mint/burn + yield + PSI inputs | worker/src/cron/compute-dews.ts | stress_signals, stress_signal_history, stress_signals_latest, cache dews freshness sentinel, exact publication pointer cache["dews:published-generation"] | GET /api/stress-signals, GET /api/status (publicationHealth.surfaces["dews"], dependencyHealth.dependencies["dews"]) | useStressSignals, useStressSignalDetail | Depeg tracker risk panels, homepage radar snapshot, /status publication/dependency health |
| Yield intelligence | Exact compact report_card_cache publication, current full report-card snapshot or computed fallback for API hydration, on-chain rate calls, DefiLlama pools, cached supplemental protocol snapshots, CoinGecko price fallback, New York Fed/FRED/Treasury/central-bank benchmark feeds, risk-free rate cache, plus optional gated vaults.fyi detailed-vault telemetry and allowlisted supplemental rows | worker/src/cron/sync-yield-data.ts, worker/src/cron/sync-yield-supplemental.ts, helper modules under worker/src/cron/yield-sync/, worker/src/cron/fetch-tbill-rate.ts, worker/src/api/yield-rankings-cache.ts | yield_data, source-aware yield_history, yield_publication_generations, yield_source_decisions, cache yield-rankings with immutable hourly report-card evidence plus response-only live hydration provenance, structured benchmark cache risk_free_rates, legacy USD mirror risk_free_rate, supplemental/on-chain health caches | GET /api/yield-rankings, GET /api/yield-history, GET /api/yield-adapter-manifest, GET /api/status (publicationHealth.surfaces["yield-rankings"], dependencyHealth.dependencies["yield-rankings"]) | useYieldRankings, useYieldHistory, useYieldAdapterManifest | Yield page, stablecoin detail, methodology yield-source monitor, /status yield, publication-health, and dependency root-cause cards |
| Daily digest | Anthropic Claude + PSI snapshot context | worker/src/cron/daily-digest.ts, worker/src/lib/telegram-digest-outbox.ts | daily_digest, exact-payload telegram_digest_outbox, + static build sync to data/digests.json | GET /api/daily-digest, GET /api/digest-archive, GET /api/digest-snapshot | useDailyDigest, useDigestArchive, useDigestSnapshot | Digest page + archive |
| Bluechip ratings | Bluechip rating publications | worker/src/cron/sync-bluechip.ts | cache key: bluechip-ratings | GET /api/bluechip-ratings | useBluechipRatings | /about/bluechip/, Compare, stablecoin badges, Screener Picker |
| USDS freeze status | USDS contract storage/call probes | worker/src/cron/sync-usds-status.ts | cache key: usds-status | GET /api/usds-status | useUsdsStatus | USDS status card |
| Public daily dataset snapshots | Completed D1/cache artifacts: stablecoins cache, report-card cache, prior-day PSI snapshot, exact published DEWS generation, and optional current DEX liquidity rows | worker/src/cron/snapshot-public-dataset.ts | public_snapshots | GET /api/snapshots/index, GET /api/snapshots/:date.json, GET /api/snapshot/:date/stablecoin/:id | — | External integrations and historical dataset consumers |
| Report cards + dependency graph | Peg summary + DEX liquidity + redemption backstops + bluechip + stablecoin metadata/dependencies | worker/src/api/report-cards.ts compute fallback; worker/src/cron/publish-report-card-cache.ts exact-set validates and atomically publishes full, compact/yield-safety, and Telegram projections under one generation | API read path: report-cards:snapshot with compute fallback; downstream artifacts: report-cards:snapshot, report_card_cache, cache["alert:safety-source-cache"] | GET /api/report-cards, GET /api/status (publicationHealth.surfaces["report-card-cache"], dependencyHealth.dependencies["report-card-cache"]) | useReportCards | Safety Scores, Portfolio, Dependency Map, homepage safety snapshot, Yield safety hydration, /status publication/dependency health |
| Status reliability | Internal router probes + production-domain HTTP canaries + DB/cache-only structural canaries + status synthesis | worker/src/cron/status-self-check.ts, worker/src/cron/data-invariant-canary.ts, worker/src/api/status.ts, worker/src/api/public-status-history.ts, static dependency registry shared/lib/data-dependency-registry.ts | status_state, status_transitions, status_probe_runs, status_discrepancy_state, worker_canary_runs; derived dependencyHealth is response-only | Public: GET /api/health, GET /api/public-status-history; admin: GET /api/status, GET /api/status-history (canaries) | Public: useHealth, usePublicEndpointProbes, usePublicStatusHistory; admin: useStatus, useEndpointProbes, useStatusHistory | /status public health board, /admin operator dashboard |
| Telegram pulse | Telegram subscribers, pending queue, usage analytics, and delivery diagnostics | worker/src/api/telegram-pulse.ts snapshot publisher on the five-minute Telegram lane | cache key: telegram:pulse:snapshot | GET /api/telegram-pulse | useTelegramPulse | /pharoswatchbot/ pulse strip |
| Personalized Telegram daily recap | Canonical tape_events plus existing D1 subscriber, direct-watchlist, preset, snooze, and global-family state; no provider/API or AI calls | worker/src/cron/telegram-recap-planner.ts (DB-only due-page planner), worker/src/lib/telegram-recap-facts.ts, worker/src/lib/telegram-recap-ranking.ts, worker/src/lib/telegram-recap-formatting.ts | telegram_recap_preferences, telegram_recap_targets, exact telegram_pending_alerts rows with source_type = personalized_recap | No public API; private commands and signed Mini App state/mutation | Mini App Settings Daily Recap section | Private Telegram chats, one material recap message per local date |
| Coverage discovery | CoinGecko category API, DL stablecoins residuals | worker/src/cron/discovery-scan.ts (weekly, Monday-only), worker/src/cron/sync-stablecoins/intake.ts (DL residuals) | discovery_candidates | GET /api/status (discoveryCandidates field), plus direct admin GET /api/discovery-candidates / POST /api/discovery-candidates/:id/dismiss | — (admin only) | /admin/ operator dashboard, Pipeline section |
| Chain analytics | Stablecoins cache aggregate circulating buckets, chainCirculating buckets (already aggregated by DefiLlama), report card cache (safety scores for quality sub-factor) | worker/src/api/chains.ts (compute on read from stablecoins + report-card D1 caches and emit freshness metadata); worker/src/cron/snapshot-chain-supply.ts writes daily totals to D1 | Live leaderboard: computed on-the-fly from D1 caches with _meta freshness; history: chain_supply_history | GET /api/chains | useChains, useChainProfileData, useChainStablecoins | /chains/ leaderboard, /chains/[chain]/ profile pages |
| Alt-peg / non-USD share | supply_history rows for commodity-pegged and fiat non-USD stablecoins | worker/src/api/non-usd-share.ts computes historical aggregate shares on read from daily supply snapshots | supply_history | GET /api/non-usd-share | useNonUsdShare | /alt-pegs/ market-share chart and non-USD/commodity context |
| Timeline / Tape events | Depeg, freeze, safety-score, PSI, DEWS, mint/burn, yield, methodology, cemetery, and lifecycle source tables/static registries | worker/src/cron/project-tape.ts projects source transitions through class-specific tape projectors on the DEWS/PSI DB-only lane | tape_events | GET /api/events | useEvents, useLatestEvents, useTimelineFeedData | /timeline/ cross-class event feed and homepage timeline modules |
The DEX flow has an additive shadow measured-execution subflow. Pinned Uniswap
V3 and PancakeSwap V3 QuoterV2/factory RPC reads, plus the Fluid resolver
adapter, enter worker/src/cron/measured-execution/ through the isolated
sync-cl-exit-depth job. The prior retained-pool target generation is stored in
dex_measured_execution_targets; raw proof and validated quote profiles are
generation-fenced in dex_measured_execution_quotes. The following
sync-dex-liquidity run consumes only a published prior quote generation and
exposes proof-free profiles and explicit capability gates through the existing
DEX API. All measured deployment cohorts remain score-ineligible while their
activation evidence is pending.
The private report-cards:snapshot row is checksum-verified gzip/base64 with
bounded decompression; its decoded public V8 JSON is unchanged, and the new
reader also accepts legacy plain envelopes during rolling deploys.
The report-card publication flow also runs a candidate-only Safety Score V9
sidecar after the atomic V8 publication commits. It reuses the exact normalized
base generation, adds reviewed V9 facts, and writes the latest candidate/diff,
one compact summary per UTC day, selected content-addressed replay evidence,
and append-only movement reviews. A failed attempt can be retried later on the
same day; routine successful runs do not retain a full artifact bundle.
GET /api/admin-safety-score-v9 and its review mutation remain the operator
surface. The additive GET /api/report-cards/v9 route now exposes a strict,
fully identified shadow contract for dark consumer verification. Shadow state
still does not feed GET /api/report-cards, the active frontend, yield,
Telegram, chain analytics, or V8-compatible public history; those remain V8 until the
independent validation, coverage, shadow-window, and consumer-cutover gates are
satisfied. See Safety Score V9 Rollout.
Scheduling Backbone
Cron expressions are deployed from worker/wrangler.toml; shared/lib/cron-jobs.ts owns canonical schedule/job metadata and shared/lib/scheduled-runner-registry.ts owns expression-to-runner dispatch. Use Worker Infrastructure: Cron Scheduling for execution details and npm run check:cron-sync / npm run check:cron-connections for the authoritative live inventory and connection-budget report.
Freshness Contract (Frontend)
API hooks that use useApiQuery follow the interval supplied by their caller:
staleTime = intervalrefetchInterval = 2 * interval
Defined centrally in src/hooks/use-api-query.ts. Cron-backed hooks should pass the producer cadence unless a documented route-specific exception applies. Current exceptions include /api/health (1-minute diagnostic polling, not cron-backed) and /api/usds-status (15-minute UI polling over a daily source snapshot).
Notes
- Core aggregate boundary:
shared/data/stablecoins/listing-decisions.jsonclassifies the catalog, whileshared/lib/stablecoins/aggregate-registry.tsprojects activecore-stablecoinandcash-equivalententries for monetary aggregates. PSI, digest market/supply totals, current homepage market cap, chain totals/history, and non-USD share consume that projection. Depeg, DEWS, price, per-asset history, and digest risk-signal lanes continue monitoring every active listing, including variants and stable-value investments. Client ranking filters use the compactlistingClassfield incoins.client.generated.json, not the full decision ledger. New PSI and digest snapshots identify the aggregate boundary ascore-stablecoins-v1so consumers can distinguish legacy rows. - DEX price bridge: The half-hourly DEX liquidity cron now rebuilds
dex_prices.price_sources_jsonfrom the final retained priced-pool surface after dedupe, caps, scoring filters, and unit normalization, publishing one aggregate per protocol. The quarter-hourly pricing cron reads these vialoadDexPriceSources()and promotes at most one individually-weighted consensus source per protocol:fluid-dex(weight 3),balancer-dex(weight 3),curve-dex(weight 3),uniswap-v3-dex(weight 2),uniswap-v4-dex(weight 2),raydium-dex(weight 2),orca-dex(weight 2),meteora-dex(weight 2),pancakeswap-dex(weight 2),aerodrome-dex(weight 2),velodrome-dex(weight 2). These promoted protocol sources only enter primary consensus when corroborated or when no non-DEX voices exist, and the overlappingdex-promotedaggregate (weight 1) is withheld whenever at least one promoted protocol candidate passes freshness and TVL validation for the same asset, even if that candidate is then excluded for lack of corroboration. The aggregate DEX fallback enters consensus only when no protocol candidate clears those pre-corroboration checks. DEX admission/merge skip reasons are emitted into logs and cron metadata so stale rows, malformed snapshots, TVL filters, missing registry mappings, and duplicate identities can be traced without scraping the raw tables. - Abort-aware high-volume publication: DEX liquidity and DEWS persistence pass the cron
AbortSignalinto chunked D1 batches, retrying D1 operations, and final freshness-sentinel guards. If timeout or lease-loss aborts the run after a partial batch, the run fails before publishingfreshness:dex-liquidity,freshness:dews, or the exact DEWS publication pointer. Durable DEWS consumers, canaries, and freshness reporting use the pointer rather than rawMAX(computed_at)rows. - Cache passthrough endpoints include freshness metadata via
_metaand/orX-Data-Age. - Chain profile pages intentionally coordinate two APIs:
GET /api/chainsfor the summary card andGET /api/stablecoinsfor composition. The detailed sections stay hidden until both snapshots share the sameupdatedAt, which keeps incomplete or mismatched data from being presented as a full per-chain breakdown. chain_supply_historyremains a forward-only internal dataset until the post-2026-04-08 baseline. Earlier rows were written before shared chain-label canonicalization and are not approved for public charting./api/dex-liquidityis meta-aware on the frontend: the page uses worker freshness metadata (and degraded-runWarningheaders) rather than client fetch time to assess staleness.- Liquidity history now carries
coverageClass/coverageConfidence; trend and durability consumers should treat low-confidence snapshots as informational, not authoritative baselines. dex_liquidity_historyis retained for the public 365-day history window; older daily snapshots are pruned during successfulsync-dex-liquiditypersistence instead of living as an indefinite research archive.- Admin/backfill endpoints bypass edge cache via
cacheBypassflags inshared/lib/api-endpoints/. - The stablecoins cache loader distinguishes
ok,degraded, anderrorstates. Operator-facing or published consumers (/status, daily digest, safety snapshot) now fail closed on non-okcache reads instead of treating broken cache state as an empty valid dataset. consensusSourcesflows from the price-consensus cron stage through thestablecoinscache →/api/stablecoinsand/api/peg-summary→useStablecoins/usePegSummaryhooks →PriceTransparencyCardon the detail page andCoverageBadgesource-count enrichment on the coverage page.priceSourceConfidenceProfileflows from DEX-inclusive primary pricing through thestablecoinscache and/api/stablecoins. It is omitted for non-DEX prices and currently remains a data/API transparency field rather than a UI dependency.