From 4168aca107f9e49e903feb2649d7de43cf97a3ce Mon Sep 17 00:00:00 2001 From: chiguyong Date: Mon, 1 Jun 2026 20:36:10 +0800 Subject: [PATCH] chore: Plan 005 - tech debt cleanup sprint (timezone, API client, security) --- ...6-01-geo-tech-debt-cleanup-requirements.md | 130 +++++++++ ...01-005-chore-geo-tech-debt-cleanup-plan.md | 270 ++++++++++++++++++ 2 files changed, 400 insertions(+) create mode 100644 docs/brainstorms/2026-06-01-geo-tech-debt-cleanup-requirements.md create mode 100644 docs/plans/2026-06-01-005-chore-geo-tech-debt-cleanup-plan.md diff --git a/docs/brainstorms/2026-06-01-geo-tech-debt-cleanup-requirements.md b/docs/brainstorms/2026-06-01-geo-tech-debt-cleanup-requirements.md new file mode 100644 index 0000000..9c5a47f --- /dev/null +++ b/docs/brainstorms/2026-06-01-geo-tech-debt-cleanup-requirements.md @@ -0,0 +1,130 @@ +--- +date: "2026-06-01" +topic: geo-tech-debt-cleanup +--- + +## Summary + +GEO 平台技术债清理冲刺,分三批交付:第一批修复 29 个模型文件中 73 个缺失 `DateTime(timezone=True)` 的 datetime 列(按 API 调用路径优先级排序);第二批统一前端 2 个页面组件的 API 客户端调用;第三批完成前端端到端验证和部署安全加固。每批有明确交付物和验证门。 + +## Problem Frame + +Plan 004 的端到端验证暴露了一个系统性问题:asyncpg 驱动严格检查 timezone-aware datetime 与 `TIMESTAMP WITHOUT TIME ZONE` 列的兼容性,任何写入 `datetime.now(UTC)` 到未标记 timezone 的列都会直接报运行时错误。当前仅修复了变现闭环涉及的 4 个核心表(diagnosis_records、payment_orders、subscriptions、users),其余 29 个模型文件的 73 个列仍是确定的运行时炸弹。与此同时,前端 2 个页面组件绕过统一 API 客户端直接调用 `fetch`,认证 token 不被附加,用户访问会 401。Docker 部署从未验证成功,Redis/PostgreSQL 安全配置缺失。这些技术债不清理,系统无法真正上线。 + +## Key Decisions + +**时区修复按 API 调用路径优先级排序,而非一次性全量迁移。** 全量迁移风险高(73 列同时 ALTER TABLE),且部分 API 路径尚未被触发。按实际调用路径修复,每批修完验证对应 API 可用,风险可控。 + +**前端 API 客户端统一排在时区修复之后。** 401 错误是确定的问题但影响范围有限(2 个页面),时区 bug 影响所有涉及 datetime 写入的 API。先修高影响再修低影响。 + +**部署安全加固排在最后。** 安全配置(Redis 密码、PostgreSQL 弱密码、.env.production)在本地开发环境不影响功能,但上线前必须完成。作为第三批交付。 + +**前端 E2E 验证与部署安全加固合并为第三批。** E2E 验证需要浏览器环境,与部署配置调整可以并行进行。 + +## Requirements + +**时区修复(Batch 1)** + +R1. 所有 29 个模型文件的 73 个 datetime 列添加 `DateTime(timezone=True)`,PostgreSQL 对应列类型改为 TIMESTAMPTZ + +R2. 时区修复按 API 调用路径分三批执行:核心变现路径(brand、query、citation_record、attribution_record、content、geo_plan、suggestion)→ Agent 框架路径(agent、detection_task、monitoring、monitoring_record、competitor_insight、trend_insight)→ 辅助路径(knowledge、knowledge_graph、organization、lifecycle、distribution、alert、alert_setting、platform_rule、platform_rule_version、usage_record、api_key、query_task、brand_knowledge、competitor) + +R3. 每批修复后验证对应 API 路径可正常写入和读取 datetime 数据 + +R4. 生成对应的 Alembic 迁移脚本,迁移可从当前数据库状态执行 + +**前端 API 客户端统一(Batch 2)** + +R5. `reports/page.tsx` 的 CSV 导出改用统一 API 客户端,认证 token 正确传递 + +R6. `lifecycle/new/page.tsx` 的项目创建改用统一 API 客户端,认证 token 正确传递 + +R7. 统一 API 客户端支持非 JSON 响应(如 blob/PDF 导出),避免 `reports.ts` 等模块被迫绕过 + +**前端端到端验证(Batch 3)** + +R8. 浏览器中可完成完整变现闭环:注册→登录→创建品牌→诊断→查看健康分→付费墙→支付→解锁 + +R9. 公开健康分页面无需登录即可访问并生成报告 + +R10. Onboarding 流程在浏览器中可正常走通 + +**部署安全加固(Batch 3)** + +R11. Redis 配置密码保护,非本地环境禁止无密码连接 + +R12. PostgreSQL 默认弱密码更换为强密码 + +R13. 创建 `.env.production` 模板,包含所有生产环境必需配置项 + +R14. Docker Compose 部署验证通过,4 个服务均可正常启动和通信 + +## Key Flows + +- F1. 时区修复验证流程 + - **Trigger:** 某批模型文件完成 DateTime(timezone=True) 修改 + - **Steps:** 修改模型 → 生成 Alembic 迁移 → 执行迁移 → 调用对应 API 写入数据 → 验证写入成功 → 读取数据验证时区正确 + - **Outcome:** 该批 API 路径的 datetime 读写不再触发 asyncpg 时区错误 + - **Covers:** R1, R2, R3, R4 + +- F2. 前端变现闭环验证流程 + - **Trigger:** 浏览器打开 GEO 平台 + - **Steps:** 注册→登录→创建品牌→触发诊断→查看健康分→尝试付费功能→触发付费墙→Mock支付→功能解锁→验证 reports 和 lifecycle 页面正常 + - **Outcome:** 用户在浏览器中完成从获客到付费的完整链路,所有页面认证正常 + - **Covers:** R5, R6, R8, R9, R10 + +## Scope Boundaries + +**In scope:** +- 29 个模型文件的 DateTime(timezone=True) 修复 +- 对应 Alembic 迁移生成和执行 +- 前端 2 个页面组件 API 客户端统一 +- 统一 API 客户端非 JSON 响应支持 +- 浏览器端到端验证 +- Docker Compose 部署验证 +- Redis/PostgreSQL 安全配置 +- .env.production 模板 + +**Deferred for later:** +- 真实微信/支付宝 SDK 接入 +- CI/CD 流水线 +- 性能优化和压力测试 +- 生产环境域名和 HTTPS 配置 +- 完整测试覆盖 +- pgvector 镜像优化(改用 pgvector/pgvector:pg15) +- JWT_SECRET 强密钥生成 + +**Outside this sprint:** +- UI 打磨和视觉优化 +- 新功能开发 +- 代码重构(除时区修复外) + +## Dependencies / Assumptions + +- PostgreSQL 15 + pgvector 扩展可用(Plan 004 已验证) +- Redis 7 可用(Plan 004 已验证) +- asyncpg 驱动严格时区检查行为不变(这是正确行为,不是 bug) +- 已修复的 4 个核心表(diagnosis_records、payment_orders、subscriptions、users)不需要再次修改 +- `monitoring.py` 和 `monitoring_record.py` 可能存在重复模型定义,需确认哪个是实际使用的 +- Docker Hub 网络问题可能影响 Docker 部署验证(Plan 004 中曾因此失败) + +## Outstanding Questions + +**Resolve Before Planning:** +- `monitoring.py` 和 `monitoring_record.py` 都定义了 MonitoringRecord 和 ContentBaseline,需确认哪个是实际使用的,避免重复修复 + +**Deferred to Planning:** +- Alembic 迁移策略:是生成一个大的迁移脚本还是按批次生成多个 +- 统一 API 客户端非 JSON 响应的具体实现方式(扩展 fetchWithAuth 还是新增 fetchWithAuthBlob) +- Docker 部署验证是否需要解决 Docker Hub 网络问题(镜像源配置等) + +## Sources / Research + +- Plan 004 端到端验证记录:时区 bug 在 diagnosis_records 和 payment_orders 上的具体表现 +- `backend/app/models/` — 29 个待修复模型文件,73 个 datetime 列 +- `frontend/lib/api/client.ts` — 统一 API 客户端,导出 fetchWithAuth 和 API_BASE +- `frontend/app/(dashboard)/dashboard/reports/page.tsx` — 绕过统一客户端,手动 fetch + Authorization header +- `frontend/app/(dashboard)/dashboard/lifecycle/new/page.tsx` — 绕过统一客户端,手动 fetch + Authorization header +- `frontend/lib/api/reports.ts` — PDF blob 导出被迫绕过统一客户端(fetchWithAuth 只返回 JSON) +- `docker-compose.yml` — Redis 无密码、PostgreSQL 弱密码(geo:geo123) +- `docker-compose.prod.yml` — 依赖不存在的 .env.production diff --git a/docs/plans/2026-06-01-005-chore-geo-tech-debt-cleanup-plan.md b/docs/plans/2026-06-01-005-chore-geo-tech-debt-cleanup-plan.md new file mode 100644 index 0000000..dbfcd9b --- /dev/null +++ b/docs/plans/2026-06-01-005-chore-geo-tech-debt-cleanup-plan.md @@ -0,0 +1,270 @@ +--- +title: "chore: GEO Tech Debt Cleanup Sprint" +type: chore +status: active +date: "2026-06-01" +origin: docs/brainstorms/2026-06-01-geo-tech-debt-cleanup-requirements.md +--- + +## Summary + +分三批清理 GEO 平台技术债:Batch 1 修复 28 个模型文件中 68 个缺失 `DateTime(timezone=True)` 的 datetime 列(`monitoring_record.py` 是废弃文件不修);Batch 2 统一前端 2 个页面组件的 API 客户端调用并扩展 `fetchWithAuth` 支持非 JSON 响应;Batch 3 完成前端端到端验证和部署安全加固。 + +## Problem Frame + +Plan 004 端到端验证暴露了 asyncpg 严格时区检查的系统性问题。当前仅修复了变现闭环涉及的 4 个核心表,其余 28 个模型文件的 68 个 datetime 列仍是确定的运行时炸弹——任何写入 `datetime.now(UTC)` 到未标记 timezone 的列都会直接报错。同时前端 2 个页面绕过统一 API 客户端,认证 token 不被附加导致 401。Docker 部署从未验证成功,Redis/PostgreSQL 安全配置缺失。这些技术债不清理,系统无法真正上线。 + +--- + +## Requirements + +**时区修复(Batch 1)** + +R1. 28 个模型文件的 68 个 datetime 列添加 `DateTime(timezone=True)`,PostgreSQL 对应列类型改为 TIMESTAMPTZ + +R2. 时区修复按 API 调用路径分三批执行:核心变现路径 → Agent 框架路径 → 辅助路径 + +R3. 每批修复后验证对应 API 路径可正常写入和读取 datetime 数据 + +R4. 生成对应的 Alembic 迁移脚本 + +R5. 删除废弃的 `monitoring_record.py` 文件(无任何代码引用,与 `monitoring.py` 定义同名表但字段不同) + +**前端 API 客户端统一(Batch 2)** + +R6. `reports/page.tsx` 的 CSV 导出改用统一 API 客户端 + +R7. `lifecycle/new/page.tsx` 的项目创建改用统一 API 客户端 + +R8. 统一 API 客户端支持非 JSON 响应(blob/PDF 导出) + +**前端端到端验证(Batch 3)** + +R9. 浏览器中可完成完整变现闭环:注册→登录→创建品牌→诊断→查看健康分→付费墙→支付→解锁 + +R10. 公开健康分页面无需登录即可访问 + +R11. Onboarding 流程在浏览器中可正常走通 + +**部署安全加固(Batch 3)** + +R12. Redis 配置密码保护 + +R13. PostgreSQL 默认弱密码更换为强密码 + +R14. 创建 `.env.production` 模板 + +R15. Docker Compose 部署验证通过 + +--- + +## Key Technical Decisions + +KTD1. **时区修复按 API 调用路径分批,而非一次性全量迁移。** 68 列同时 ALTER TABLE 风险高,按实际调用路径修复风险可控。核心变现路径(brand、query、content 等)最优先,因为这是用户最可能触发的路径。 + +KTD2. **`monitoring_record.py` 是废弃文件,删除而非修复。** 代码引用分析确认所有 import 都指向 `monitoring.py`,`monitoring_record.py` 无任何引用。两个文件定义同名表但字段结构不同,保留 `monitoring.py`(更完整,有 relationship 和 user_id/query_id 外键)。 + +KTD3. **扩展 `fetchWithAuth` 支持非 JSON 响应,而非新增独立函数。** `reports.ts` 的 PDF blob 导出被迫绕过统一客户端,因为 `fetchWithAuth` 只返回 JSON。扩展一个 `responseType` 参数比新增 `fetchWithAuthBlob` 更符合 DRY 原则,且对现有调用方无侵入。 + +KTD4. **Alembic 迁移按 Batch 生成,而非一个大迁移。** 每个 Batch 生成一个迁移文件,便于回滚和增量部署。Batch 1 因模型数量多可能需要 2-3 个迁移文件。 + +--- + +## Implementation Units + +### U1. Batch 1a: 核心变现路径时区修复 + +- **Goal:** 修复核心变现路径涉及的模型文件 datetime 列,确保品牌创建、查询、内容管理、GEO 计划、建议生成等 API 不再触发 asyncpg 时区错误 +- **Requirements:** R1, R2, R3, R4 +- **Dependencies:** none +- **Files:** + - `backend/app/models/brand.py` — 4 列(last_queried_at, next_query_at, created_at, updated_at) + - `backend/app/models/query.py` — 4 列(last_queried_at, next_query_at, created_at, updated_at) + - `backend/app/models/citation_record.py` — 1 列(queried_at) + - `backend/app/models/attribution_record.py` — 4 列(published_at, window_end_at, created_at, updated_at) + - `backend/app/models/content.py` — 4 列(Content: created_at, updated_at; ContentVersion: created_at; ContentReview: created_at) + - `backend/app/models/geo_plan.py` — 5 列(GeoPlan: created_at, updated_at; GeoPlanAction: completed_at, created_at, updated_at) + - `backend/app/models/suggestion.py` — 2 列(generated_at, updated_at) + - `backend/app/models/competitor.py` — 1 列(created_at) + - `backend/app/models/competitor_insight.py` — 2 列(created_at, updated_at) + - `backend/app/models/distribution.py` — 2 列(created_at, updated_at) + - `backend/app/models/brand_knowledge.py` — 3 列(BrandKnowledge: created_at, updated_at; Keyword: created_at) +- **Approach:** 每个文件添加 `DateTime` import(如缺失),将所有 `Mapped[datetime]` 列的 `mapped_column()` 添加 `DateTime(timezone=True)` 参数。对于已有 `DateTime` 但无 `timezone=True` 的列(如 brand.py 的 last_queried_at),改为 `DateTime(timezone=True)`。修复后启动后端服务,通过 curl 验证品牌创建和查询 API 的 datetime 读写正常。 +- **Patterns to follow:** 已修复的 4 个核心表(diagnosis_record.py, payment_order.py, subscription.py, user.py)的修改模式 +- **Test scenarios:** + - 品牌创建 API 返回的 created_at 包含时区信息 + - 查询品牌列表 API 返回的 datetime 字段包含时区信息 + - 创建 GEO 计划后 completed_at 可写入 timezone-aware datetime + - attribution_record 的 published_at 和 window_end_at 可写入 timezone-aware datetime +- **Verification:** 启动后端服务,通过 curl 调用品牌创建、查询、内容管理 API,确认 datetime 读写无 asyncpg 时区错误 + +### U2. Batch 1b: Agent 框架路径时区修复 + +- **Goal:** 修复 Agent 框架和监控相关模型文件的 datetime 列 +- **Requirements:** R1, R2, R3, R4 +- **Dependencies:** U1 +- **Files:** + - `backend/app/models/agent.py` — 9 列(AgentRegistry: last_heartbeat, created_at, updated_at; AgentConfig: updated_at; AgentTask: scheduled_at, started_at, completed_at, created_at; AgentTaskLog: created_at) + - `backend/app/models/detection_task.py` — 4 列(last_run_at, next_run_at, created_at, updated_at) + - `backend/app/models/monitoring.py` — 5 列(MonitoringRecord: last_checked_at, next_check_at, created_at, updated_at; ContentBaseline: recorded_at) + - `backend/app/models/trend_insight.py` — 4 列(period_start, period_end, created_at, updated_at) + - `backend/app/models/query_task.py` — 3 列(scheduled_at, started_at, completed_at) + - `backend/app/models/usage_record.py` — 2 列(timestamp, created_at) + - `backend/app/models/api_key.py` — 3 列(last_verified_at, created_at, updated_at) +- **Approach:** 同 U1 模式。注意 `detection_task.py` 的 `next_run_at` 有 `default=lambda: datetime.now(timezone.utc)`,这已经是 timezone-aware 的,但列类型仍是 `DateTime`(无 timezone),需要改为 `DateTime(timezone=True)`。 +- **Patterns to follow:** U1 的修改模式 +- **Test scenarios:** + - Agent 注册时 last_heartbeat 可写入 timezone-aware datetime + - AgentTask 的 scheduled_at、started_at、completed_at 可写入 timezone-aware datetime + - detection_task 的 next_run_at 默认值写入不触发时区错误 + - monitoring_record 的 last_checked_at、next_check_at 可写入 timezone-aware datetime +- **Verification:** 启动后端服务,通过 curl 调用 Agent 相关 API,确认 datetime 读写无错误 + +### U3. Batch 1c: 辅助路径时区修复 + 废弃文件清理 + +- **Goal:** 修复剩余辅助路径模型文件的 datetime 列,删除废弃的 monitoring_record.py +- **Requirements:** R1, R2, R3, R4, R5 +- **Dependencies:** U2 +- **Files:** + - `backend/app/models/knowledge.py` — 6 列(KnowledgeBase: created_at, updated_at; KnowledgeDocument: created_at, updated_at; KnowledgeChunk: created_at; KnowledgeSearchLog: created_at) + - `backend/app/models/knowledge_graph.py` — 3 列(KnowledgeEntity: created_at, updated_at; KnowledgeRelation: created_at) + - `backend/app/models/organization.py` — 3 列(Organization: created_at, updated_at; OrgMember: joined_at) + - `backend/app/models/lifecycle.py` — 4 列(LifecycleProject: created_at, updated_at; ProjectStage: started_at, completed_at) + - `backend/app/models/alert.py` — 1 列(created_at) + - `backend/app/models/alert_setting.py` — 2 列(created_at, updated_at) + - `backend/app/models/platform_rule.py` — 1 列(updated_at) + - `backend/app/models/platform_rule_version.py` — 1 列(created_at) + - `backend/app/models/schema_suggestion.py` — 2 列(created_at, updated_at) + - `backend/app/models/monitoring_record.py` — 删除整个文件 + - `backend/app/models/__init__.py` — 移除 monitoring_record 的 import(如有) +- **Approach:** 同 U1 模式。删除 `monitoring_record.py` 前确认 `__init__.py` 无引用(已验证无任何代码 import 此文件)。删除后检查 `__init__.py` 是否有相关 import 需清理。 +- **Patterns to follow:** U1 的修改模式 +- **Test scenarios:** + - knowledge 相关 API 的 created_at/updated_at 可写入 timezone-aware datetime + - lifecycle project 的 started_at/completed_at 可写入 timezone-aware datetime + - 删除 monitoring_record.py 后后端服务正常启动,无 import 错误 +- **Verification:** 启动后端服务,确认无 import 错误;调用 knowledge 和 lifecycle API 验证 datetime 读写 + +### U4. Alembic 迁移生成与执行 + +- **Goal:** 为 U1-U3 的所有模型变更生成 Alembic 迁移脚本,并在本地数据库执行 +- **Requirements:** R4 +- **Dependencies:** U1, U2, U3 +- **Files:** + - `backend/alembic/versions/` — 新增迁移文件 +- **Approach:** 运行 `alembic revision --autogenerate` 生成迁移。检查生成的迁移脚本确认所有 ALTER COLUMN 操作正确(`TIMESTAMP → TIMESTAMPTZ`)。执行迁移后验证数据库列类型已更新。如果项目未配置 Alembic,则通过 `init_schema.py` 或手动 SQL 完成数据库更新。 +- **Patterns to follow:** 已有的 Alembic 迁移文件(如存在) +- **Test scenarios:** + - 迁移脚本可成功执行,无错误 + - 迁移后数据库列类型为 TIMESTAMPTZ + - 迁移可回滚(downgrade) +- **Verification:** 执行迁移,检查数据库列类型 + +### U5. 前端 API 客户端统一 + +- **Goal:** 统一前端 2 个页面组件的 API 调用,扩展 fetchWithAuth 支持非 JSON 响应 +- **Requirements:** R6, R7, R8 +- **Dependencies:** none(可与 U1-U4 并行) +- **Files:** + - `frontend/lib/api/client.ts` — 扩展 fetchWithAuth 支持 responseType 参数 + - `frontend/app/(dashboard)/dashboard/reports/page.tsx` — CSV 导出改用 fetchWithAuth + - `frontend/app/(dashboard)/dashboard/lifecycle/new/page.tsx` — 项目创建改用 fetchWithAuth + - `frontend/lib/api/reports.ts` — PDF blob 导出改用 fetchWithAuth(responseType: 'blob') +- **Approach:** 在 `fetchWithAuth` 中添加可选 `responseType` 参数,默认 `'json'`,当为 `'blob'` 时返回 `Response` 对象而非解析 JSON。修改 reports/page.tsx 和 lifecycle/new/page.tsx 使用 `fetchWithAuth` 替代手动 `fetch`。修改 reports.ts 使用 `fetchWithAuth` 的 blob 模式。 +- **Patterns to follow:** `frontend/lib/api/client.ts` 现有的 fetchWithAuth 实现 +- **Test scenarios:** + - fetchWithAuth 默认行为不变(返回 JSON) + - fetchWithAuth responseType='blob' 返回 Response 对象 + - reports 页面 CSV 导出认证 token 正确传递 + - lifecycle/new 页面项目创建认证 token 正确传递 + - PDF 导出通过 fetchWithAuth blob 模式正常工作 +- **Verification:** 前端构建通过,浏览器中访问 reports 和 lifecycle/new 页面无 401 错误 + +### U6. 前端端到端验证 + +- **Goal:** 在浏览器中验证完整变现闭环和关键用户流程 +- **Requirements:** R9, R10, R11 +- **Dependencies:** U4, U5 +- **Files:** + - 无代码修改,纯验证 +- **Approach:** 启动前后端服务,在浏览器中手动走通完整变现闭环。重点验证:注册→登录→Onboarding→创建品牌→诊断→健康分→付费墙→支付→解锁。同时验证公开健康分页面无需登录可访问。 +- **Test scenarios:** + - 完整变现闭环:注册→登录→创建品牌→诊断→健康分→付费墙→支付→解锁 + - 公开健康分页面无需登录可访问并生成报告 + - Onboarding 流程可正常走通 + - reports 页面 CSV 导出正常 + - lifecycle/new 页面项目创建正常 +- **Verification:** 所有流程在浏览器中走通,无 401、无页面报错 + +### U7. 部署安全加固 + +- **Goal:** Redis 密码保护、PostgreSQL 强密码、.env.production 模板、Docker Compose 部署验证 +- **Requirements:** R12, R13, R14, R15 +- **Dependencies:** U4 +- **Files:** + - `docker-compose.yml` — Redis 添加密码配置、PostgreSQL 密码更新 + - `backend/.env` — Redis 密码和 PostgreSQL 密码同步更新 + - `backend/.env.production` — 新建生产环境配置模板 + - `docker-compose.prod.yml` — 更新生产环境配置(如存在) +- **Approach:** 在 docker-compose.yml 中为 Redis 添加 `--requirepass` 命令和环境变量。PostgreSQL 密码从弱密码 `geo123` 改为强密码。创建 `.env.production` 模板包含所有必需配置项。后端代码中 Redis 连接需同步添加密码参数。执行 `docker compose up` 验证 4 个服务正常启动和通信。 +- **Patterns to follow:** docker-compose.yml 现有配置结构 +- **Test scenarios:** + - Redis 无密码连接被拒绝 + - Redis 有密码连接成功 + - PostgreSQL 弱密码连接被拒绝 + - PostgreSQL 强密码连接成功 + - Docker Compose 4 个服务正常启动 + - 后端服务可连接 Redis 和 PostgreSQL +- **Verification:** `docker compose up` 成功,4 个服务健康检查通过,后端 API 可正常响应 + +--- + +## Scope Boundaries + +**In scope:** +- 28 个模型文件的 DateTime(timezone=True) 修复 +- 废弃文件 monitoring_record.py 删除 +- Alembic 迁移生成和执行 +- 前端 2 个页面组件 API 客户端统一 +- 统一 API 客户端非 JSON 响应支持 +- 浏览器端到端验证 +- Docker Compose 部署验证 +- Redis/PostgreSQL 安全配置 +- .env.production 模板 + +**Deferred for later:** +- 真实微信/支付宝 SDK 接入 +- CI/CD 流水线 +- 性能优化和压力测试 +- 生产环境域名和 HTTPS 配置 +- 完整测试覆盖 +- pgvector 镜像优化 +- JWT_SECRET 强密钥生成 +- UI 打磨和视觉优化 + +**Outside this sprint:** +- 新功能开发 +- 代码重构(除时区修复和废弃文件删除外) + +--- + +## Risks & Dependencies + +- **Alembic 未配置或配置不完整。** 如果项目未正确配置 Alembic,自动迁移生成可能失败。回退方案:通过 `init_schema.py` 或手动 SQL 完成 ALTER COLUMN。 +- **Docker Hub 网络问题。** Plan 004 中 Docker 部署因网络问题失败,U7 可能遇到同样问题。回退方案:配置 Docker 镜像源或使用本地构建。 +- **前端构建可能暴露其他问题。** 前端代码从未在浏览器中完整验证,E2E 验证可能发现新的 bug,这些 bug 需要额外修复。 +- **Redis 密码变更影响后端连接。** 后端代码中 Redis 连接配置需同步更新,否则服务启动失败。 + +--- + +## Sources / Research + +- Plan 004 端到端验证记录:时区 bug 在 diagnosis_records 和 payment_orders 上的具体表现 +- `backend/app/models/` — 28 个待修复模型文件,68 个 datetime 列 +- `backend/app/models/monitoring.py` — 实际使用的监控模型(被 4 处代码引用) +- `backend/app/models/monitoring_record.py` — 废弃文件(零引用) +- `frontend/lib/api/client.ts` — 统一 API 客户端 +- `frontend/app/(dashboard)/dashboard/reports/page.tsx` — 绕过统一客户端 +- `frontend/app/(dashboard)/dashboard/lifecycle/new/page.tsx` — 绕过统一客户端 +- `frontend/lib/api/reports.ts` — PDF blob 导出被迫绕过 +- `docker-compose.yml` — Redis 无密码、PostgreSQL 弱密码