Files
photo-live/docs/plans/2026-09-17-实施总纲.md
T
浅念 d973c714f0 chore: init repository skeleton
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-17 16:13:49 +08:00

180 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 图片直播项目实施总纲
版本:V1.0
日期:2026-09-17
执行模式:Claude Code 代理开发 + 显式人工关口
关联文档:[需求说明书](../01-需求说明书.md) · [项目计划](../02-项目计划.md) · [技术实施方案](../03-技术实施方案.md) · [优化方案](../04-优化方案.md)
本总纲把 V1.3 文档基线拆解为代理可执行的实施阶段序列,定义工程结构、技术选型锁定、阶段边界、人工关口与决策挂起清单。它不替代上述四份文档:需求以 R01 至 R31 为准,验收以 A01 至 A29 为准,工作包编号 T01 至 T30 沿用项目计划。各阶段的详细可执行计划在进入该阶段时另册编写(见 docs/plans/ 目录)。
## 1 执行模式与技术栈锁定
开发主体为 Claude Code 代理,按"每阶段交付可在本地完整运行、可自动化验证的端到端增量"推进;无法由代理完成的验证(真机、真实云资源、外部接口)显式登记为人工关口,不阻塞代理开发,但在对应阶段出口必须闭环。
D02 技术栈决策本次锁定如下,后续变更需评估返工范围后修订本总纲:
| 层 | 选型 | 说明 |
|---|---|---|
| App | Flutter,原生桥接(iOS background URLSession / Android 用户发起传输任务 + 前台服务) | P3 创建,双平台 |
| 管理后台 | Art Design Pro 模板(Vue 3 + Vite + TypeScript + Element Plus) | 锁定模板版本;P1 尾部接入 |
| 观众页 | Vue 3 + Vite + TypeScript 轻量入口 | 独立于后台 |
| 嵌入组件 | TypeScript 加载器 + 项目域内 iframe 轮播页 | P4b |
| API | NestJS + TypeScript,单代码库双部署入口 cn-app / ov-app | 模块按部署角色组织 |
| ORM | Prisma(MySQL 方言),cn 与 ov 各自独立 schema | 去重窗口清理等以原生 SQL / 调度任务实现 |
| 数据库 | MySQL 8 ×2:生产复用国内与海外 ECS 上 1Panel 既有 MySQL 容器,各建独立库与独立账号;本地开发用同版本 MySQL 容器保持方言一致 | 双库结构不同、互不直连,符合 A24 |
| 队列与缓存 | BullMQ + Redis ×2 | cn 承任务队列;ov 承限速与实时辅助(独立实例与命名空间) |
| 图片处理 | sharp(libvips) | HEIC 解码为验证关口,见 G2 |
| 对象存储 | StoragePort 适配层:开发环境 MinIO,生产阿里云 OSS | 见第 3 节 |
| 实时 | NestJS WebSocket(ws 适配器),部署于 ov-app | P2 |
| 测试 | 服务端 Jest + supertest;Web 端 Vitest;E2E Playwright | 基础设施依赖 docker-compose 固定版本 |
| Monorepo | pnpm workspaces + Turborepo | Flutter 子树用原生工具链 |
## 2 工程结构
```text
photo/
docs/
plans/ 实施总纲、各阶段详细计划与验收记录
apps/
mobile/ Flutter App(P3 创建)
admin/ 管理后台(Art Design Pro)
viewer/ 观众页
packages/
contracts/ OpenAPI 契约 + 生成 TS 类型 + 事件契约 + 稳定错误码
locales/ Web 公共翻译词条
embed-loader/ JS 悬浮组件加载器(P4b)
storage/ StoragePort 接口与 MinIO / OSS 适配器
services/
api/ NestJS:cn-app 与 ov-app 两个部署入口 + 共享领域模块
worker/ 图片处理 worker(BullMQ 消费者 + sharp)
sync/ outbox 发送 / inbox 接收 / 统计回传(P2)
infra/
docker-compose.yml MySQL×2、Redis×2、MinIO(P1 仅启用 cn 侧,P2 起以 profiles 启用 ov 侧;版本对齐生产 1Panel 环境)
migrations/ 原生 SQL 与清理任务(去重窗口等)
deploy/ 部署配置(P5)
```
Schema 所有权:国内库表(users、albums、photos、upload_sessions、outbox_events 等)归 `services/api` 的 cn schema 管理;海外库表(展示副本、inbox、点赞批次、浏览去重、统计权威)归 ov schema 管理。两端共享的数据形状只经 `packages/contracts` 传递,禁止互相引用对方 schema 生成物。
契约优先:`packages/contracts` 是接口与事件的单一事实源,三端类型由其生成;契约任务完成处设用户确认点后再开发消费端。
## 3 代理执行的核心工程决策
1. 本地双地域仿真:docker-compose 启动两套独立 MySQL 与 Redis;cn-api(:8080) 与 ov-api(:8081) 双进程;sync 服务经 HTTP 互推。跨境同步、墓碑、乱序去重、统计回传全部在集成测试中自动化验证,不依赖真实海外资源(真实部署见 P5)。
2. 存储适配层:`packages/storage` 定义 StoragePort(签发临时上传凭证、head 核验、服务端受控复制、禁止覆盖语义)。开发环境用 MinIO(presigned);生产用阿里云 OSS 适配器。生产适配器优先返回签名 PUT URL(与 MinIO 形态统一,App 保持单一 PUT 上传代码路径);STS/分片作为大文件增强备选,经 G1 验证后决定。凭证形态差异在接口上归一化,适配器各自的特殊语义用独立测试覆盖;真实 OSS 差异集中在 G1/G2 关口验证。
3. 用户源接口 Mock:按技术实施方案 3.1A 假设字段实现 mock provider 与适配器接口,同步调度、水位、幂等、失败不停用等逻辑先行开发测试;真实接口契约(D08)到位后仅替换适配器。配套 fixtures 覆盖改名、停用、分页中断、空响应、增量等场景。
横切关注点自 P1 内建:结构化日志贯穿三端并以 requestId / uploadId / photoId 关联;稳定错误码 + 本地化文案映射;audit_logs 记录管理与权限操作;/health 端点;密钥经环境注入且不入库。
## 4 阶段划分与交付物
| 阶段 | 可运行交付物 | T 映射 | A 映射 | 出口门 | 人工关口 |
|---|---|---|---|---|---|
| P1 底座 + 国内核心链路 | compose 一键起环境;密码登录→建相册→上传会话→核验→处理→自动发布→观众页瀑布流/大图/短期签名 URL 刷新(读 cn 公开 API);可见性状态机与单张隐藏/软删除;seed 与脚本化 E2E;admin 最小页(后段) | T02 T05(后端部分)T06 T07,T11 部分 | A01(API 与后台级,App 端随 P3)A02 A03 A06 A13(凭证设计级,OSS 生命周期全量核验随 G1/P5);A07/A08 基础级 | 回归全绿 + 验收记录;可选 G1 | G1(可选) |
| P2 双地域仿真 + 互动 | ov-app + outbox/inbox 同步(版本、墓碑、高优先级下线、补漏对账);点赞批次幂等;WebSocket 气泡(自身批次过滤、后台暂停);浏览统计窗口去重;统计快照回传;观众页切换至 ov-api 并新增最新/热门排序 | T25(仿真部分)T26 T13 T19 T27 T24,T11 完成 | A09 A10 A14 A21 A26 A27(仿真级) | 回归全绿 + 验收记录;D07/D11 初值确认 | 无 |
| P3 Flutter App | 登录、相册配置、协作、持久化上传队列(准备阶段状态机、账号隔离、跨设备服务端历史)、连拍入队、原生后台传输桥接 | T03 T08 T09 T21 | A04 A05 A15 A19(代码 + 模拟器级) | 回归全绿 + 验收记录 | G2(强制)、G3(资源) |
| P4a 后台完备 + 账号治理 | Art Design Pro 全功能后台:相册/照片/用量管理与告警、上传公开开关、批量隐藏、负责人交接、水印版本与历史重生成、下载两级控制、后台语言切换与账号管理(激活停用/重置密码/角色)、用户定期同步任务与管理页(mock 源) | T10 T20 T22 T12 T30 T04(mock 部分) | A16 A17 A18 A20 A23 A29(mock 级) | 回归全绿 + 验收记录;D06 前置 | G4(真实接口) |
| P4b 传播组件 | embed-loader + 展示位管理 + 轮播 iframe:configVersion 校验、旧响应丢弃、不可见暂停、postMessage 白名单、data-lang 语言配置 | T14 T23 T15 | A11 A12 A22;A23 组件部分 | 回归全绿 + 验收记录 + 全端语言验收(T15/A12) | 无 |
| P5 真实环境接入 | 真 OSS/STS 适配器验证、海外部署与域名、全球 CDN 接入与失效策略、用户接口真实对接、跨地域故障演练、容量压测、试运行与分发交接 | T16 T17 T25(真实)T28 T29 T18 | A24 A25 A28 + 全量 A 回归 + 容量报告 | 发布门槛(对齐项目计划 7.3) | G5、G6 |
阶段顺序 P1 → P2 → P3 → P4a → P4b → P5。P3 与 P4a 在 P2 契约稳定后可并行;P4b 依赖 P2 的公开列表契约与同步通道(展示位事件扩展),其 T15 全端语言验收还需 P3 完成;P5 依赖全部前序。
每阶段出口执行统一回归门:lint + typecheck + 单元 + 集成 + E2E 全绿,并产出《阶段验收记录》(docs/plans/progress/,逐项对照 A 编号登记证据与未尽事项)。
## 5 决策挂起清单
| 决策 | 内容 | 最晚确认时点 | 本次状态 |
|---|---|---|---|
| D01 | 首发语言(建议 zh-CN、en) | P1 开始前 | 待确认,P1 按建议值开发词条结构 |
| D02 | 后端与 Web 技术栈 | — | 已锁定(本总纲第 1 节) |
| D03 | iOS/Android 分发方式 | P3 开始前(资源自首周准备) | 待确认 |
| D04 | 删除回收策略 | 永久清理规则 P4a 前 | 软删除基线已随 V4 纳入 P1 |
| D05 | 数量并发与网络目标 | P5 压测计划前 | 待确认,按项目计划 L1/L2 阶梯准备 |
| D06 | 下载水印与原图默认值 | P4a 开始前 | 待确认 |
| D07 | 浏览统计窗口(建议 30 分钟)与主办字段 | P2 验收前给初值 | 待确认 |
| D08 | 用户接口契约(稳定 ID、字段、鉴权、停启用语义) | P4a 开始前 | 待确认,mock 先行 |
| D09 | 海外 ECS 地域规格确认与测试点 | P5 开始前 | 海外 ECS 已就绪(1Panel + Docker + MySQL),规格与地域待登记 |
| D10 | 缓存失效窗口、轮询周期、用量阈值 | 对应模块(P4b/P5)验收前 | 待确认 |
| D11 | 跨境同步参数(补漏周期、回传周期、中断策略) | P2 验收前给初值,P5 实测冻结 | 待确认 |
| D12 | 两台 ECS 的 MySQL 版本、字符集与配置确认 | P1 开始前 | 已确认为 8.0+(2026-09-17),本地容器用 8.4 对齐 |
| D13 | 代码托管平台与 CI 接入 | P5 镜像构建链路前(建议 P2 前) | 待确认,本地 git + 脚本先行 |
## 6 人工关口与外部资源
| 关口 | 内容 | 时点 | 阻塞范围 |
|---|---|---|---|
| G1 | 真实 OSS 冒烟:presign/STS、head 核验、禁止覆盖、staging→originals 受控复制、跨域、现有 Bucket 生命周期规则对项目前缀的影响检查 | P1 出口(有凭证即执行,无凭证显式跳过并登记) | OSS 适配器定稿 |
| G2 | 真机双平台 + 真 OSS 组合验证:锁屏、切后台、厂商后台管理、凭证过期恢复、HEIC 真机样本解码(对齐技术验证用例 6.4) | P3 出口(强制) | App 上传链路发布 |
| G3 | macOS/Xcode 构建链、签名与分发资质 | P3 资源(自 P1 起准备) | iOS 构建 |
| G4 | 用户接口真实契约与测试凭据 | P4a | T30 真实对接 |
| G5 | 海外 ECS(已装 1Panel + Docker + MySQL)规格与地域确认、域名、全球 CDN 权限 | P5 | 海外部署与 CDN |
| G6 | 试运行真实活动与业务验收 | P5 末 | 发布 |
## 7 工程治理
- 版本库:项目当前未初始化 git。P1 第一个任务执行 `git init`,trunk-based 单主干,约定式提交信息,每任务至少一次提交,阶段完成打 tag(p1、p2…)。
- 分支与回退:阶段 tag 作为回退基线;数据库迁移保持向前兼容,不做破坏性逆迁移(对齐技术实施方案 12.4)。
- 密钥:全部经 .env 注入,仓库只提交 .env.example;不提交任何 OSS、接口、签名凭据。
- 验收留痕:每阶段验收记录对照 A 编号登记;代理执行的关键决策(如契约变更)记录在阶段计划文档内。
- 代码托管与 CI:本地 git 起步即满足回归门;仓库托管平台与 CI 接入为待确认项(D13),确认前以本地脚本保证质量,P5 镜像构建发布链路随之补齐。
- T01 原型的替代:纸面原型由"契约评审(用户确认点)+ P1 即可运行的观众页与后台最小页"替代,页面字段与权限以 R 编号与契约为准。
## 8 各阶段范围明细
### P1 底座 + 国内核心链路
包含:
- git 初始化、monorepo 脚手架(pnpm + Turborepo)、compose(MySQL/Redis/MinIO,cn 侧,版本对齐生产)、基础 lint/typecheck/test 脚本。
- packages/contracts:P1 范围 OpenAPI 契约(auth、albums、members、uploads、photos、public read)+ 事件契约(photo.published 等)+ 错误码;完成后设用户确认点。
- Prisma cn schema 与迁移(MySQL 方言):users、sessions、albums、album_translations、album_members、categories、category_translations、album_assets、photos、photo_variants、upload_sessions、photo_jobs、outbox_events、audit_logs。
- 数据模型 PG→MySQL 语义复核清单:唯一约束与 upsert 行为、时间精度与 UTC 存储、排序与游标稳定性、token 大小写敏感(显式 binary 校对或受限字符集)、连接池上限。
- cn-api:密码登录/刷新/注销(成熟密码哈希、会话可撤销、登录失败基础限速);相册 CRUD 与多语言字段、成员与分类;上传会话幂等初始化(clientTaskId 唯一)、临时凭证签发(StoragePort)、续签、完成核验(head + 字节数 + 完整性)、staging→originals 受控复制(禁止覆盖);照片可见性状态机与单张隐藏/软删除;公开读接口(相册信息按语言回退、游标分页稳定排序、单图定位);图片短期签名 URL 签发与过期刷新;outbox 事务写入;CORS 来源按环境配置;/health。
- worker:BullMQ 消费者 + sharp 流水线(真实类型校验、解码、方向校正、缩略图/浏览图、EXIF 清理、尺寸记录),事务切换公开状态并写 photo.published 事件;失败归类与有限重试。
- viewer 基础页:活动信息区(宣传图、多语言回退、浏览次数占位、活动时间按相册时区展示)、双列瀑布流(宽高预留、按需渲染/懒加载)、大图基础交互(左右切换、双指缩放、关闭回原位)、单图分享定位路由、空相册本地化空态、新照片提示(轮询)、分类筛选、zh-CN/en 切换;最新/热门排序切换依赖点赞数,随 P2 提供。
- admin 最小页(后段低优先级):Art Design Pro 登录对接本地会话、相册列表/创建/编辑、成员管理。
- 宣传图/封面/Logo 上传接口与 viewer 展示(album_assets 的 presign+确认,复用照片上传机制)随 P1b 交付(R09 依赖,P1a 先建表不出接口)。
- E2E:脚本上传(多文件、同名、重复完成通知)→ worker 处理 → 公开 API 可见 → Playwright 观众页冒烟。
不包含:海外同步与互动(P2)、Flutter(P3)、批量隐藏/交接/水印/下载控制/用量(P4a)、展示位与组件(P4b)、真实 OSS 常态接入(G1/P5)。
P1 内部再切 1a(后端链路,API 级 E2E 先行)与 1b(观众页与 admin 界面);admin 最小页如遇模板接入风险可顺延至 P4a,不阻塞 P1 出口。
### P2 双地域仿真 + 互动
包含:ov schema(展示副本、inbox、水位、点赞批次、浏览会话与请求去重、统计权威)与 like_batches 去重窗口方案(MySQL 表分区要求分区键进入全部唯一键、会破坏批次唯一约束,故采用索引 + 定时清理任务 + 过期批次拒绝重放替代分区,清理任务纳入 infra/migrations 与调度);sync 服务(outbox 发送器签名鉴权、inbox 幂等消费、版本与墓碑、高优先级下线队列、定时补漏对账);海外紧急停用入口(独立于同步链路的 ov 侧运维端点,跨境中断时可达:仅允许更严屏蔽、不修改国内权威数据、不因普通同步事件自动解除——技术方案 §2A);ov-app 公开 API + WebSocket(相册隔离订阅、点赞批次幂等、合并广播、自身批次过滤、断线降级轮询);浏览统计(跨标签页共享匿名标识、窗口去重、requestId 幂等、并发首访唯一、排除规则:分页请求/图片资源请求/轮播/后台预览不计入,后台预览走独立路由);统计快照回传(statVersion 单调替换);观众页切换 ov-api 并接入实时更新,新增最新/热门排序切换(热门按点赞数版本化短期快照)。D07、D11 初值在验收前确认。
### P3 Flutter App
包含:登录与账号隔离、修改密码;App 内语言切换(zh-CN/en,跟随设备与手动选择);相册配置与协作页面(含相册分享链接与二维码入口);本地任务库与状态机(preparing/preparation_failed/queued/uploading/…);准备阶段(源文件获取、空间检查);连续拍摄自动入队;原生后台上传桥接(iOS URLSession background、Android 用户发起传输任务/前台服务)与任务映射恢复;凭证过期续签(单文件 PUT 为上传基线,分片上传作为后续大文件验证项);跨设备服务端历史。出口强制 G2 真机验证:未通过不标志 P3 完成、不阻塞 P4a/P4b 推进,但阻塞 P5 试运行并触发重估。
### P4a 后台完备 + 账号治理
包含:后台全功能(相册/照片管理、筛选、批量隐藏逐项结果、上传公开独立开关、负责人转移、用量统计与阈值告警(含统计数字与同步时间后台展示)、相册分享链接与二维码展示、后台语言切换、账号管理:激活停用/重置密码/角色);水印配置版本化与历史重生成任务(进度、可重试、不覆盖原图、原子切换引用);下载两级控制与微信等浏览器引导;用户定期同步任务(调度锁、水位、幂等、失败记录、手动补拉、状态页)接 mock 源。G4 后替换真实适配器。
### P4b 传播组件
包含:embed-loader(版本化地址、防重复初始化、postMessage 白名单、data-lang 语言配置);展示位管理与权限(展示位实体与 configVersion 纳入 cn→ov 内容同步,海外公开组件 API 读取本地副本,对应 R28);轮播 iframe(configVersion、旧响应丢弃、近期照片队列、不可见暂停、空态);接入样例站点与宿主 CSP 说明;出口执行 T15 全端语言验收与文案补齐(App、后台、观众页、组件四端切换、回退与漏译检查,对应 A12)。
### P5 真实环境接入
包含:OSS 真实适配器与 STS 验证;国内与海外两台 ECS(均已装 1Panel + Docker + 既有 MySQL 容器)上的部署:镜像与 compose 编排交由 1Panel 容器管理、域名与 TLS 经 1Panel OpenResty 反代、复用既有 MySQL 容器各建独立库与账号、Redis 以容器部署、1Panel 计划备份并演练恢复、数据库迁移由发布流程执行(不手工进容器操作);海外首次全量快照与增量追赶;全球 CDN 回源、URL 鉴权、缓存失效与预热策略;用户接口真实对接;跨地域故障演练(断网重放、乱序、重复回传、紧急停用、恢复);容量压测(L1/L2)与实测报告;监控告警、回滚演练;试运行与 App 分发交接(服务端保持必要的旧客户端兼容)。
## 9 风险与应对(实施总纲层)
| 风险 | 影响 | 应对 |
|---|---|---|
| MinIO 与 OSS 语义差异(STS 形态、禁止覆盖、分片) | 适配器返工 | StoragePort 归一化 + G1 前置冒烟 + G2 真机组合验证 |
| 数据模型从 PG 假设迁移到 MySQL 的语义差异 | 去重、并发、排序行为偏差 | P1 首批任务含语义复核清单(唯一约束、upsert、UTC 时间精度、token 校对、游标排序);去重窗口替代分区,P2 用真实并发事务测试验证 |
| 复用 1Panel 既有 MySQL 容器 | 与其他业务争用资源、备份耦合 | 独立库 + 独立账号 + 连接池上限;纳入 1Panel 计划备份并演练恢复;用量告警(A23)覆盖数据库资源 |
| 生产 MySQL 实际版本低于 8.0 | 迁移与去重 SQL 兼容性问题 | D12 于 P1 开始前确认;必要时在 1Panel 新建 8.x 容器专用本项目,原容器不动 |
| sharp HEIC 解码在 Windows 预编译不可用 | iPhone 照片失败 | P1 用样本 HEIC 验证;不可用则换 libheif 路线并登记 |
| Art Design Pro 模板升级或裁剪成本 | 后台进度受阻 | 锁定模板版本;接入置于 P1 尾部不阻塞主线 |
| 本地仿真与真实跨境网络差异 | P5 问题集中暴露 | 同步语义全部版本化/幂等;P5 演练清单对齐项目计划 7.3 |
| 决策挂起未按时确认 | 阶段出口阻塞 | 第 5 节清单随阶段计划再次提醒,未确认按建议值开发并标记 |
| 代理长周期执行上下文漂移 | 实现偏离文档 | 每阶段独立计划 + 验收记录 + 契约单一事实源 |
## 10 与项目计划(S1-S6 / 岗位人日)的关系
本总纲面向代理执行重新纵切,阶段与 S1-S6 不一一对应:S1 需求基线由本总纲 + 契约评审替代;S2 技术验证拆入 G1(P1 出口可选)与 G2/G3(P3)前置;S3 对应 P1;S4 对应 P2 + P3 + P4a 主体;S5 对应 P4a/P4b + P5 前段;S6 对应 P5 末段。T01-T30 全覆盖(T01 由契约评审与早可用页面替代;T04 由 P4a 的 mock 契约先行 + G4/P5 真实接口验证替代;T15 落在 P4b 出口的全端语言验收)。原岗位人日估算(156 至 231)作为规模参照,代理执行的实际节奏以阶段验收记录为准;对外承诺的日历工期仍以项目计划 W1-W16 基线管理,两者并行不悖。