跳转到主要内容
本页属于设计哲学指南,该页索引全部主题。部署拓扑、目录结构与 CI/CD 请参阅 ARCHITECTURE.md。

Railway 种子数据管道

Railway 定时服务持续用从外部 API 预计算的数据刷新 Redis 缓存。下表每一行是一个种子脚本,而非单独的定时任务:捆绑服务会在同一计划中运行多个种子(例如,流离失所和边境种子都在 seed-bundle-health 中运行)。种子按可配置计划运行(从数分钟到每日),同时写入规范域名键(用于 RPC 处理器查找)和引导键(用于页面加载水合)。这种双键策略确保引导水合和 RPC 处理器在数据格式和新鲜度上始终一致。 种子使用 cachedFetchJson 配合进行中 Promise 合并 — 如果种子运行与前一次仍在写入的运行重叠,并发写入会被去重。每个种子脚本都是自包含的(单个 .mjs 文件,无构建步骤),在 Node.js 20+ 上运行,并通过 REST API 连接到 Upstash Redis。失败的种子运行会记录错误但绝不破坏现有缓存数据 — 之前的缓存条目会保留直到成功运行替换它。

边缘函数与部署

边缘函数架构

World Monitor 使用 Vercel Edge Functions 作为轻量 API 层,分为两代。api/*.js 中的遗留端点各自处理单一数据源问题 — 代理、缓存或转换外部 API。较新的 proto 优先端点使用每领域薄入口点,每个仅导入其自身的处理器模块。这取代了原来在每次冷启动时加载全部领域的单体网关。每个领域的函数经 tree-shaking 仅包含其依赖,将冷启动时间减少约 85%(大多数端点低于 100ms,而单体处理器需 500ms+)。共享的 server/gateway.ts 提供通用路由逻辑。两代共存,新功能以 proto 优先方式构建。此架构避免了单体后端同时保持 API 密钥服务端:
  • RSS 代理 — 域名白名单代理,支持完整的订阅源目录,防止 CORS 问题并隐藏源服务器。Edge 代理和 Railway 中继都保持重定向为手动,并在每一跳前重新检查 RSS 域名白名单。来自屏蔽 Vercel IP 的域名的订阅源自动通过 Railway 中继路由。
  • AI 管道 — Ollama 和 OpenRouter 摘要边缘函数配 Redis 去重,使并发用户间的相同标题仅触发一次 LLM 调用。classify-event 端点在 500 错误时暂停其队列以避免浪费 API 配额。
  • 数据适配器 — GDELT、ACLED、OpenSky、USGS、NASA FIRMS、FRED、Yahoo Finance、CoinGecko、mempool.space、BIS、WTO 等各自有专用边缘函数将响应归一化为一致 schema
  • 市场情报 — 宏观信号、ETF 资金流和稳定币监控在服务端计算衍生分析(VWAP、SMA、peg 偏差、资金流估算)并将结果缓存到 Redis
  • 时间基线 — Welford 算法状态在跨请求间持久化到 Redis,无需传统数据库即可构建统计基线
  • 自定义抓取器 — 没有 RSS 订阅源的来源(工信部新闻、GitHub Trending、科技事件)被抓取并转换为 RSS 兼容格式
  • 金融地理数据 — 证券交易所(29 个)、金融中心(19 个)、央行和超国家金融机构(14 个)和大宗商品枢纽(10 个)作为带类型的静态数据集提供,含市值、GFCI 排名、交易时间和大宗商品专长
  • BIS 集成 — 来自国际清算银行的政策利率、实际有效汇率和信贷/GDP 比率,缓存 30 分钟 TTL
  • WTO 贸易政策 — 来自世界贸易组织的贸易限制、关税趋势、双边贸易流和 SPS/TBT 壁垒
  • 供应链情报 — 海运咽喉点中断评分(交叉引用 NGA 警告 + AIS 数据)、带激增检测的 FRED 航运货运指数,以及通过 Herfindahl-Hirschman 指数分析的关键矿产供应集中度
  • 企业情报 — IntelligenceService.GetCompanyEnrichment 通过 SEC 股票代码→CIK 注册表(每日从 company_tickers.json 播种)解析公司身份,并将 EDGAR 身份与近期申报文件(10-K、10-Q、含条目代码的 8-K)、Finnhub 市场概况与盈利意外、以及近期新闻提及聚合到单一响应中。IntelligenceService.ListCompanySignals 仅对具备权威时间戳的 SEC 8-K 重大事件(第 1 层)与新闻提及(第 3 层)进行分类;Finnhub 财政期末仍作为丰富化事实,不会被误标为财报发布时间。SearchSecFilings 代理 EDGAR 全文搜索;ListMaterialEvents 提供播种的全市场重大 8-K 申报流。不做猜测性归因:未能在 SEC 注册表中解析的公司返回空响应(其启发式前身见 issue #3754/#3755)
所有边缘函数均包含熔断器逻辑,在上游 API 不可用时返回缓存过期数据,确保仪表盘从不显示空白面板。

冷启动优化 — 每领域边缘函数拆分

原来的单体边缘网关(api/[domain]/v1/[rpc].ts)将每个服务领域处理器导入到单个函数中。调用任何 RPC 时,边缘运行时加载整个处理器图 — 即使只需要 1 个领域,也要为每个领域初始化 Redis 客户端、解析配置和导入工具模块。 这被拆分为每领域薄入口点 — 每个服务领域一个 — 每个仅导入其自身的处理器模块。共享网关(server/gateway.ts)提供通用路由逻辑,但每个领域的边缘函数经 tree-shaking 仅包含其依赖。 影响:冷启动时间下降约 85% — 行情报价请求不再加载网络威胁情报解析器、OREF 告警处理器或气候异常检测器。在 Vercel 边缘运行时上,这转化为大多数端点低于 100ms 的冷启动,而单体处理器需 500ms+。

单一部署变体合并

所有六个仪表盘变体(World Monitor、Tech Monitor、Finance Monitor、Commodity Monitor、Happy Monitor、Energy Monitor)从单一 Vercel 部署提供服务。变体在运行时通过主机名检测确定: 在桌面应用上,变体存储在 localStorage['worldmonitor-variant'] 中,可在不重新构建的情况下切换。标题栏中的变体选择器在 Web 上在已部署域名间导航,或在桌面端切换 localStorage 值。 此架构取代了原来的多部署方式(每个变体一个独立 Vercel 项目),并提供以下优势:
  • 即时切换 — 用户在标题栏切换变体,无需整页导航或 DNS 查询
  • 共享 CDN 缓存 — 静态 SPA 资源在各变体间相同;只有运行时配置不同。CDN 缓存命中率比独立部署高 4 倍
  • 单一 CI 管道 — 一次构建、一次部署、一套边缘函数。无跨部署配置漂移
  • 社交机器人路由 — OG 图片端点根据请求主机名生成变体专属预览卡片,因此分享 Tech Monitor 链接会生成科技品牌社交预览