---
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
