我看到了一对跟踪器浮在MV Hondius hantavirus群集的周围,两个都是粗糙的或者是WHO PDF的旧版本。周末我把epidemap.com作为一个副项目运维起来。与Claude Code一起.pair-programmed,为什么一个人的项目会有这么多的表面面积。
如果你想知道它做什么以及一些技术细节,读下去。
它做什么
-实时世界地图,显示确认病例点(CartoDB Dark + Leaflet),以不同的可视化层呈现,以便区分WHO/CDC确认的病例和新闻中提到的病例
-按国家显示弹出窗口,引用WHO DON / CDC HAN / 部长的来源。 Counts从头条新闻中推断出来的,确认层是手动编辑的JSON
-巡航路线动画:SVG船舶跟踪MV Hondius的航迹和患者零点路径。纯故事,能让非专业人士了解情况
-预测层(随机分支过程模拟,R₀滑块默认值为~0.2,根据Castillo 2007)
-新闻获取(Google News RSS在en/es/pt/fr中 + CIDRAP + WHO News + PAHO + HealthMap + CDC + UKHSA + STAT News)
-隔离设施层(Bichat Paris,Nebraska NQU,Atlanta)
-全EN/FR国际化,基于URL的区域设置 + 自动检测
它是如何工作的
两个Docker容器共享一个命名卷:
Web: Next.js 16(App Router,Turbopack)+ React 19 + Tailwind 4。SSR用于情况室和区域页面,一个react-leaflet岛屿仅用于地图。SQLite读取通过better-sqlite3在WAL模式下。
Worker: tsx进程在10分钟的cron中。从每个源中拉取,去重以Canonical URL,通过一个嵌入的国家/地区/城市名称的地理匹配器,写入同一个SQLite文件。只在SHA-1值改变时保存确认病例计数 - > 不会写入多次,避免写入放大。
前端从不接触RSS。工作者预先填充了数据库,Next.js只读取。1000个访客=零额外的出站请求,且我可以重新启动Web容器而不丢失fetch历史。~250个信号,跨11个国家/14个源。
栈(所有docker化)
- Next.js 16 + React 19 + Tailwind 4
- Leaflet 1.9 + react-leaflet 5
- better-sqlite3(WAL模式)
- Node 20 + tsx + rss-parser + 自定义cron
- Cloudflare Tunnel(无公网IP,无nginx,无ACME)
- Hetzner VPS
限制
确认计数是手动编辑的来自WHO/CDC的通报,而不是自动提取的。当DON601掉落时,我会编辑一个JSON文件,推送一个提交,容器会接收它。可持续性适用于一个疾病,但不会适用于50个。预测层是故意简单的,真正的流行病学家会在它上面加上防护措施。没有自动测试,两个天的MVP后面才有特性。没有疾病选择器,schema是疾病中立的,但UI字符串硬编码了Hantavirus。
幽默小插曲:检查ChatGPT三天后,出于好奇心,已经链接到该网站了。当问到哪里可以追踪疫情时。没有提交任何内容,除了我的GitHub以外,没有任何外部链接。新的搜索表面似乎会在对话中爬行,而不是基于PageRank,所以在一个特定的领域有一个准确的网站可以在第一天就排名。
评论 (0)