架构¶
仓库为 monorepo:React 19 + Vite + TypeScript 单页应用与聚合公开漏洞源的 Express API。SPA 不直接访问 NVD 或 OSV;所有出站流量经服务端,以便集中管理密钥、缓存与速率限制。
本章映射目录职责、说明 scan/watch 经 handler 的流程,并指向运行时提供的 OpenAPI 文档。
高层拓扑¶
flowchart LR
classDef ui fill:#e9edf5,stroke:#00baba,color:#253343
classDef api fill:#f3fcfc,stroke:#008c8c,color:#253343
classDef ext fill:#fff7ed,stroke:#eda232,color:#253343
Browser[Browser SPA]:::ui --> API[Express /api]:::api
API --> NVD[NVD]:::ext
API --> OSV[OSV]:::ext
API --> GH[GitHub]:::ext
API --> CISA[CISA KEV]:::ext
API --> RSS[RSS]:::ext
图解说明¶
浏览器在 localStorage 中保存栈、语言与源开关,然后调用 POST /api/scan 或 POST /api/watch。API 层校验 JSON 体,调用 server/services/scan.ts 中的 scanStack,返回合并后的漏洞。各 provider 逻辑在 server/services/;共享去重在 server/lib/merge.ts;翻译 enrichment 在 server/services/enrich.ts。
完整扫描请求路径¶
server/routes/scan.ts接收POST /scan。server/handlers/scanHandlers.ts经stackValidation.ts解析 body。scanStack解析已启用内置源与自定义 RSS。- 各工具并行 fetch 完成后 merge 并排序。
translate: true时可选运行enrichVulnsWithTranslations。- JSON
ScanResponse返回客户端;src/lib/scanCache.ts中的persistLastScan写入带栈键的cve-radar:last-scan。
数据库层(可选 PostgreSQL)¶
设置 DATABASE_URL 后,扫描元数据经 server/db/scanHistory.ts 持久化到 PostgreSQL,tenant 栈经 server/db/tenants.ts 存储。SQL 迁移位于 server/db/migrations/*.sql,pool 启动时自动执行。
类型安全 schema 定义用于渐进式 ORM 迁移,位于 server/db/schema.ts(Drizzle ORM)。server/db/drizzle.ts 通过共享 pg pool 暴露 getDb()。tenant 与 scan-history 持久化(server/db/tenants.ts、server/db/scanHistory.ts)使用 Drizzle 查询构建器;server/db/migrations/*.sql 中的 SQL 迁移仍在 pool 启动时执行。
通知服务¶
Watch 模式服务端告警使用 server/services/notifications/NotificationService.ts。通道适配器(Slack、Discord、Telegram、SMTP、通用 webhook)读取 配置 中的 env。server/services/alerts.ts 为兼容 ALERT_WEBHOOK_URL 委托该服务。
共享契约层¶
类型与 severity 排序位于 shared/(shared/api/vulnerability.ts、shared/constants/severityOrder.ts)。src/ 与 server/ 均通过 @shared/* 导入;server/types.ts 为向后兼容 re-export。npm run build:server 将 shared/ 编译到 dist-server/。
API 层结构¶
| 模块 | 角色 |
|---|---|
server/index.ts |
Express 应用、挂载路由 |
server/routes/health.ts |
GET /health |
server/routes/meta.ts |
capabilities、sources、openapi.json |
server/routes/scan.ts |
scan、watch、scan/validate |
server/routes/v1.ts |
同 handler 的版本化挂载 |
server/routes/translateLocale.ts |
POST /translate |
server/handlers/scanHandlers.ts |
共享 scan/watch/validate 逻辑 |
server/openapi/spec.json |
OpenAPI 3.1 契约 |
旧路径仍在 /api/* 下;集成应优先使用 /api/v1/*(见 API 参考)。
前端地图¶
| 区域 | 路径 |
|---|---|
| Shell | src/components/layout/AppShell.tsx、SubNav.tsx、SetupWizard.tsx |
| 标签页 | src/components/tabs/* |
| 扫描缓存 | src/lib/scanCache.ts |
| API 客户端 | src/api/scan.ts、watch.ts、scanPayload.ts |
| i18n | src/i18n/messages/*.ts |
| Hooks | useVulnScan、useWatch、useVulnTranslations、useFontScale |
| Middleware | server/middleware/rateLimit.ts、scanTimeout.ts |
后端服务(源)¶
| Provider | 模块 |
|---|---|
| NVD | server/services/nvd.ts |
| OSV | server/services/osv.ts |
| GitHub | server/services/github.ts |
| CISA KEV | server/services/cisa.ts |
| RSS | server/services/rss.ts |
| 翻译 | server/services/translate.ts |
缓存与限制¶
内存缓存(server/lib/cache.ts)支撑 RSS XML 与翻译字符串。NVD 延迟来自 server/lib/rateLimit.ts(upstream pacing)。scan/watch 的 请求速率限制 在 server/middleware/rateLimit.ts 执行(独立桶;validate 豁免)。客户端扫描结果经 scanCache.ts 持久化于 localStorage。GET /api/capabilities 公布的限制与校验器硬限制一致(50 工具、20 自定义源)。
下一章:告警