系统架构
三个 TanStack Start Worker、共享 D1、隔离 R2 与管理员授权边界。
部署拓扑
User Browser -> Web Worker -> D1/R2/providers required by enabled features
Admin Browser -> Admin Worker -> same D1/R2 when it manages those features
Docs Reader -> Docs Worker -> no business bindingsWeb 固定部署,Admin/Docs 由 Manifest 选择,三者源码始终构建。Admin 依赖 Authentication;Projects 不依赖 Auth/Admin,无 Auth 时保留公开只读并移除 authenticated audience/Favorites。Preview 只为当前 Profile 的真实消费者生成隔离资源。
Project Favorites = Projects ∩ Authentication,Transactional Email = (Authentication ∩ emailAndPassword) ∪ Newsletter,Consent = Analytics ∪ Newsletter。D1、R2、RateLimit、Turnstile、Resend、Queue/Cron 与 Workers AI 继续从最终能力集合派生。
Projects 链路
Admin 保存草稿时追加不可变 revision;Web 继续读取 published revision。发布在 D1 中原子切换 published pointer、slug、audience 和 featured 投影,页面无需重新构建。
图片和 H.264 MP4 先写 pending media row,再写服务端生成的 projects/v1/<project-id>/<asset-id> R2 key,成功后变为 ready。Web 媒体接口先校验 published revision 引用和 public | authenticated audience,再读取私有 R2;公开对象可缓存,登录对象 private, no-store。
代码地图
| 路径 | 职责 |
|---|---|
apps/web/src/pages | 用户页面与同源 API |
apps/admin/src/pages | 管理 UI、统一授权与 audit API |
packages/projects | Project/revision/media/favorite 领域与 D1/R2 adapters |
packages/auth | Better Auth role/ban/permission、公开 Admin endpoint 隔离、Social linking、protection 与邮件 |
packages/consent | 严格 Consent 快照与 effect gate |
packages/observability | correlation 与 allowlisted observations |
packages/db | 共享 Drizzle schema 与 migrations |
packages/user-assets | owner/quota/idempotency 私有上传状态机 |
依赖方向
UI -> same-origin API -> shared domain/service -> binding -> D1/R2/provider浏览器不持有 D1/R2 credential、完整 object key 或 Provider secret。Web/Admin 拥有独立 Session Cookie;Admin 业务 API 要求用户已验证、未封禁、持久化角色包含 admin,具体用户操作再检查 Better Auth permission。ADMIN_EMAILS 只约束 bootstrap/recovery 目标,公开 /api/auth/admin/* 固定返回 404。管理写入在统一授权边界后产生六字段 correlated audit,正文、文件名、R2 key 和请求 body 不进入 audit。
完整内部拓扑和数据恢复边界见仓库 ai-docs/architecture.md。