# dev_plan.md — TPS 中台开发计划

> 项目:TPS(Topic Planning System)中台
> 仓库:`tps-dashboard`(Gitea)
> 修订版本:v4 · 2026-05-14
> 配套文档:`project_plan.md`(产品宪法)+ `.clinerules`(协作规则)+ `docs/git_workflow.md`(Git 操作手册)

---

## 一、文档定位

本文是**技术与阶段宪法**——讲"怎么做、什么时候做、用什么做"。

产品 / 业务问题归 `project_plan.md`;协作流程归 `.clinerules`;Git 操作细则归 `docs/git_workflow.md`。

---

## 二、首要目标(再申明一次)

**2-3 个月内交付可用版本,让 8 人团队真的开始用。**

**Week 6 末必须有 MVP 上线**(登录 + 仪表盘 + 报题单生成 + 知识库基础设施)——这条比"功能齐全"重要。

---

## 三、当前进度状态(2026-05-06)

### 3.1 家用机已完成

> 家用电脑路径:`D:\myApp\Topic Planning\V2`

- ✅ Phase 0 环境(Python 3.12 / Node 20 / PG 16 + pgvector / VS Code + Cline)*[家用机记录,单位 4090D 已升级为 Node 22 LTS]*
- ✅ Phase 1 后端骨架(FastAPI + SQLModel + Session 认证三件套验证通过)
- ✅ 12 张表 SQL 已写完(`backend/sql/001_init.sql`)
- ✅ create_admin.py 已写完
- ❌ Phase 1 前端骨架未做

详见 `logs/phase1_log.md`。

### 3.2 单位机器(本仓库主战场)

- ❌ 一切从零开始
- ✅ Gitea 已配置(单位 4090D,与爱德华项目共用同一台 Gitea)
- ✅ 本仓库 `tps-dashboard` 已规划(待创建)

---

## 四、单位机器接手策略

### 4.1 Phase 0 必须重做,但有避坑捷径

环境从 0 装,但**家用机踩过的坑全部记入 `.clinerules` 第八章避坑清单**——单位机直接绕过。

### 4.2 Phase 1 后端代码:推荐"路径 B"(代码迁移)

**两条路可选,制片人在 Phase 1 启动时拍板**:

**路径 A — 重写**:Sonnet + DeepSeek 在单位机重新生成所有后端文件
- 优点:全新干净
- 缺点:浪费一天

**路径 B — 迁移(推荐)**:
1. 制片人在家用机把 `backend/` 整个目录打包 zip
2. 拷到单位机,解压进 `tps-dashboard/backend/`
3. Cline 跑一遍 Plan,MiniMax M2.7 审一遍代码确认与新版宪法一致
4. 修任何不一致(目前看应无重大不一致)
5. 跑一遍 `pip install + psql + create_admin + uvicorn` 验证

**推荐 B 的核心理由**:家用机后端代码已通过认证三件套实测,质量已验证;重写无新增价值,纯浪费 token 与时间。

### 4.3 Phase 1 前端代码

无家用机参考,**单位机正式启动前端骨架开发**——这是 Phase 1 的真正起点。

---

## 五、技术选型(锁定不变,与 v2 一致)

| 层级 | 选型 | 备注 |
|---|---|---|
| 前端框架 | React 18 + Vite | — |
| 前端语言 | **JavaScript**(不用 TS) | 1.0 求快,二期再迁 |
| UI 库 | Ant Design 5 + 中文 locale | — |
| 状态管理 | Zustand | 轻,够用 |
| 路由 | React Router v6 | — |
| 后端框架 | FastAPI | — |
| ORM | **SQLModel(同步)** | 不用 async |
| 数据库迁移 | **手写 SQL**(`backend/sql/00X_*.sql`) | 不用 Alembic |
| 关系数据库 | PostgreSQL 16 | — |
| 向量检索 | **pgvector**(PG 扩展) | 不用独立向量库 |
| 向量维度 | **1536**(为 2.0 wiki 兼容) | 不可改 |
| AI 嵌入模型 | DeepSeek 或 OpenAI 兼容 embedding API | — |
| AI 编程模型 | **MiniMax M2.7**(Cline Plan + Act 模式) | 详见 `.clinerules` 第二章 |
| 认证 | **Session + Cookie** | 不用 JWT |
| Word 生成 | docxtpl | — |
| 甘特图前端库 | frappe-gantt | 不自己用 D3 画 |
| 定时任务 | APScheduler | Phase 4c 才用 |
| 部署 | Nginx 反向代理 | — |
| 版本控制 | **Git + Gitea**(单位 4090D)| 本版新增 |

---

## 六、开发策略

**骨架先行 + 早期上线 + 渐进迭代**:

- Week 1 把骨架搭好(登录走通)
- Week 6 末必须上线 MVP
- 后续每 2 周补一个模块,持续上线

**每个 Phase 收尾必做三件事**:

1. **写 phase{N}_log.md**(Claude Opus 4.7 协助生成)
2. **打 Git tag**:`git tag -a phaseN-complete -m "..." && git push origin phaseN-complete`
3. **关掉 Cline 当前 Task,新 Phase 起新 Task**

---

## 七、Phase 计划(2-3 个月版)

### Phase 0:环境 + Git(Day 1-2)

**Day 1 上午:核心运行时**

- 装 Python 3.12.x(从 python.org 官方,**不要 Microsoft Store 版**)
- 装 Node.js 20 LTS(用 nvm-windows)
- 装 PostgreSQL 16,安装后执行 `CREATE EXTENSION vector;` 验证 pgvector

**Day 1 下午:版本控制(本版新增)**

> 单位 4090D 已装 Git for Windows、已配置全局用户名+邮箱(爱德华项目时弄好的),本节从创建新仓库开始。

- 在 Gitea 创建 `tps-dashboard` 仓库(团队可见,不勾选自动初始化 README)
- 在本地 clone 仓库到 `D:\TPS-中台\` 或类似路径(避免中文路径)
- 把五件套(`.clinerules` / `project_plan.md` / `dev_plan.md` / `docs/git_workflow.md` / `README.md`)+ `logs/phase1_log.md` 拷进仓库目录
- 配置 `.gitignore`(详见 `.clinerules` 第 7.5 节)
- 首次提交并推送到 Gitea

具体操作步骤详见 `docs/git_workflow.md` 第 2 章"首次仓库初始化"。

**Day 2:开发工具**

- VS Code + Cline 扩展
- Cline 配置 Plan 模式(MiniMax M2.7)+ Act 模式(MiniMax M2.7),Plan 和 Act 用同一模型但物理隔离两个心智阶段(纪律性)
- VS Code 终端打开测试:能跑 `python --version` / `node --version` / `git --version` / `psql --version`

**Phase 0 收尾**:

```bash
git add -A
git commit -m "chore: Phase 0 环境与 Git 初始化完成"
git tag -a phase0-env-ready -m "Phase 0 完成,环境就绪"
git push origin main
git push origin phase0-env-ready
```

写 `logs/phase0_log.md`(可参考 phase1_log.md 格式)。

---

### Phase 1:后端骨架 + 前端骨架(Week 1)

**Day 3-4:后端骨架**

- **路径 B 推荐**:从家用机迁移 backend 整目录,MiniMax M2.7 审一遍,跑通验证
- **路径 A 备选**:从零开始重写
- 验收:`uvicorn app.main:app --reload` 能起,`/docs` 页面能开,`/api/auth/login` + `/api/auth/me` + `/api/auth/logout` 三接口验证通过

**Day 5-7:前端骨架**

- `npm create vite@latest frontend -- --template react`
- 装核心依赖:`antd`、`@ant-design/icons`、`zustand`、`react-router-dom`、`axios`
- 配 Vite 代理(`/api` → `localhost:8000`)
- `authStore`(Zustand,存当前用户信息)
- `authService.js`(封装 login / logout / me)
- 登录页(Ant Design Form)
- 主布局(侧边栏 + 顶栏 + 内容区)
- 路由守卫 AuthGuard(未登录跳登录页)

**Week 1 里程碑(Phase 1 完整收官)**:

- 打开浏览器 `http://localhost:5173`
- 输入 admin / 密码 → 登录成功
- 看到主框架(侧边栏 + 顶栏 + 占位仪表盘)
- 刷新页面登录态保持
- 点登出 → 回到登录页

**Phase 1 收尾动作**:

- 写 `logs/phase1_log.md`(可基于家用机版本扩充)
- `git tag phase1-complete`,push
- 关 Cline 当前 Task

---

### Phase 2:仪表盘 + 用户管理 + 历史数据导入(Week 2-3)

**后端**:
- 收视数据 / 排期 CRUD API
- 管理员创建账号 API
- 编辑 episodes / yearly_targets / users 的 SQLModel 模型

**前端**:
- 仪表盘页面(近 9 期收视 + 未来 6 期排期)
- 责编录入界面
- 管理员用户管理界面

**🔧 批量导入工具 v1**:Excel 收视数据一键导入(300 期约 5 分钟)
- 支持 .xlsx / .csv 上传
- 提供模板下载
- 字段映射 + 错误提示
- 后端用 pandas 解析,批量 INSERT
- **死规矩**:导入时检测 yearly_targets 是否对应年份齐全,缺则报错让责编先填(防止颜色判定时找不到目标)

**Phase 2 已进入**:Plan = Act = MiniMax M2.7,DeepSeek v4 pro 保留为备选。

**Phase 2 里程碑**:
- 责编可以开始录入(或导入)历史收视数据
- 制片人可以一次性导入已有 300 期 Excel 数据
- 仪表盘真实数据展示,颜色判定正确(红蓝绿见 `.clinerules` 5.1)

**收尾**:写 `logs/phase2_log.md`,打 `phase2-dashboard-done` tag。

---

### Phase 3:知识库基础设施 + 历史报题单 / 文稿导入(Week 4)

**后端**:
- 文档上传 + 解析(PDF / docx)
- embedding 调用(DeepSeek 或 OpenAI 兼容 embedding API)
- pgvector 存储 + 语义检索 API

**前端**:
- 知识库管理后台(批量上传、列表、删除)

**🔧 批量导入工具 v2**:

- **报题单批量导入**:支持文件夹整批上传,自动解析字段(选题名/内容概要/编导等)
  - 制片人 200 期 docx,上传 5-10 分钟,后台 embed 10-30 分钟
  - 解析失败的文件单独列出,提示制片人修正后重传
- **文稿单篇审核入库**:
  - 单文件上传 → 系统解析 + 自动摘要 + 关键词建议
  - 屏幕展示给制片人审核,确认后入库 + embed
  - 文稿质量制片人完全可控

**Phase 3 里程碑**:批量导入往期报题单和军报跑通,系统能跑语义检索;制片人审核后逐篇入库文稿。

**收尾**:写 `logs/phase3_log.md`,打 `phase3-knowledge-base` tag。

---

### Phase 4a:核心 MVP(Week 5-6)

**模块 G**:报题单生成与下载(docxtpl 模板)
- 模板严格遵守"双段结构"(`.clinerules` 5.4)

**模块 A**:选题查重(语义检索 + 历史收视展示)
- 联动模块 E 展示外拍资源

**模块 C**:知识库参考(检索往期文稿 / 军报)

**前端**:选题提交表单 + AI 反馈页面布局

**🎯 Week 6 末上线 MVP**——团队真的可以用了:登录、看仪表盘、提交选题、看到查重和知识库结果、生成报题单 docx 下载。

**收尾**:写 `logs/phase4a_log.md`,打 `phase4a-mvp-launch` tag。**这是项目第一次"对内发布",务必郑重打 tag**。

---

### Phase 4b:画像 + 甘特图 + 资源(Week 7-9)

- **模块 B**:编导画像建议(AI 反馈中的一段文字,粗框架)
- **模块 F**:时间可行性 + 甘特图(frappe-gantt)
- **模块 E**:拍摄资源关联(基础 CRUD + 关联展示)
- **模块 D**:历史审片意见展示(非预测,仅相似选题原文)

**Phase 4b 里程碑**:TPS 核心功能闭环,编导提交选题后能拿到完整 AI 反馈。

**收尾**:写 `logs/phase4b_log.md`,打 `phase4b-tps-complete` tag。

---

### Phase 4c:热点雷达(Week 10-11)

- 模块 H:今日热点雷达(每位编导个人首页)
- RSS 订阅源接入 + APScheduler 定时抓取
- AI 摘要 + 风格化改写(few-shot 用 Phase 3 已积累的往期文稿)
- 个人首页热点列表 UI(深入 / 收藏 / 忽略)
- 与 TPS 联动:点[深入了解]预填选题简介

**为什么排在最后**:需要 Phase 3 积累的稿子作为风格学习样本,数据量越大模仿越像。

**收尾**:写 `logs/phase4c_log.md`,打 `phase4c-radar` tag。

---

### Phase 5:部署上线 + Buffer(Week 11-12)

- **新服务器准备**:腾讯云 4核8G 轻量服务器(待租)
  - Ubuntu 22.04 LTS / Nginx / Python 3.12 / PostgreSQL 16 + pgvector / Node 22 LTS
- **Nginx 反向代理整合**(`project_plan.md` 第八章规划):
  ```
  主域名/        → 工作台前端
  主域名/api     → 工作台后端
  主域名/tts     → 反代到 101.42.29.217 蓝皓 TTS
  主域名/mmim    → 反代到 101.42.29.217 MMIM
  ```
- **正式上线前必做**:
  - 把 .env 中 `SECRET_KEY` 改为真实随机值(`python -c "import secrets; print(secrets.token_urlsafe(32))"`)
  - SessionMiddleware 改 `same_site="strict"` + `https_only=True`
  - 配 SSL 证书(Let's Encrypt)
  - 关闭 FastAPI 自动文档 `/docs` 在生产环境的访问(或加密)
- 简单文档 + bug 修复
- 留 1 周 buffer

**收尾**:写 `logs/phase5_log.md`,打 `phase5-production` tag,**这是项目正式上线 tag**。

---

## 八、明确推迟到二期 / 砍掉的

- ❌ TypeScript:JS 先行
- ❌ Alembic:头 3 个月手动管理 schema
- ❌ async SQLAlchemy:8 人并发同步够用
- ❌ AI 模型配置 UI:配置文件写死,UI 二期做
- ❌ 模块 D 的 AI 预测能力:数据足够后再做
- ❌ 文稿写作辅助系统:二期
- ❌ Karpathy LLM Wiki 知识库形态:**2.0 重点,1.0 仅预埋接口**

---

## 九、1.0 预埋的 2.0 兼容接口

- 知识库存储格式向 **Markdown + frontmatter** 靠拢(未来可导出 Obsidian)
- 每条知识库条目预留 `tags`、`related_entities`、`related_concepts` JSONB 字段
- embedding 维度统一 **1536**(主流,未来通用)
- 知识库后台支持 .md 格式批量导入导出

---

## 十、项目目录结构

```
tps-dashboard/                  ← Git 仓库根
├── .clinerules                 # Cline 协作规则
├── .gitignore                  # Git 忽略清单
├── README.md                   # 项目入口说明
├── project_plan.md             # 产品宪法
├── dev_plan.md                 # 开发计划(本文档)
│
├── docs/                       # 项目文档目录
│   └── git_workflow.md         # Git 操作手册
│
├── logs/                       # 进度日志(只增不删)
│   ├── phase0_log.md
│   ├── phase1_log.md
│   ├── phase2_log.md
│   └── ...
│
├── samples/                    # 样本数据(收视 Excel 等,不进 .gitignore)
│   └── *.xlsx
│
├── frontend/                   # React 前端
│   ├── src/
│   │   ├── components/         # 通用组件
│   │   │   ├── Layout/
│   │   │   └── AuthGuard/
│   │   ├── pages/
│   │   │   ├── Login/
│   │   │   ├── Dashboard/      # 公共仪表盘
│   │   │   ├── EditorHome/     # 编导个人首页(含热点雷达)
│   │   │   ├── TPS/            # 选题策划
│   │   │   ├── KnowledgeBase/
│   │   │   └── UserManage/
│   │   ├── services/           # API 客户端
│   │   ├── stores/             # Zustand
│   │   ├── router/
│   │   ├── utils/
│   │   ├── App.jsx
│   │   └── main.jsx
│   ├── package.json
│   └── vite.config.js
│
├── backend/                    # FastAPI
│   ├── app/
│   │   ├── api/
│   │   │   ├── auth.py
│   │   │   ├── dashboard.py
│   │   │   ├── tps.py
│   │   │   ├── knowledge.py
│   │   │   ├── radar.py        # 热点雷达
│   │   │   └── users.py
│   │   ├── core/
│   │   │   ├── config.py
│   │   │   ├── security.py     # session 工具
│   │   │   └── deps.py
│   │   ├── models/             # SQLModel 模型(分 Phase 增量加)
│   │   ├── schemas/            # Pydantic
│   │   ├── services/
│   │   │   ├── ai_service.py   # AI 调用
│   │   │   ├── rag_service.py  # pgvector 检索
│   │   │   ├── docx_gen.py     # docxtpl 报题单
│   │   │   └── radar_service.py # 热点抓取 + 风格化
│   │   ├── db/
│   │   │   └── session.py
│   │   └── main.py
│   ├── sql/                    # 手写 SQL(替代 Alembic)
│   │   └── 001_init.sql        # 12 张表一次到位
│   ├── scripts/                # 运维脚本
│   │   └── create_admin.py     # 交互式创建管理员
│   ├── templates/              # docxtpl 模板
│   │   └── baoti_template.docx
│   ├── requirements.txt
│   └── .env                    # ⚠️ 不进 Git
│
└── nginx/                      # 部署配置(Phase 5 启用)
    └── nginx.conf
```

---

## 十一、数据库核心表(12 张,Phase 1 SQL 已建完)

| 表名 | 说明 | 启用 Phase |
|---|---|---|
| `users` | 用户/认证 | Phase 1 |
| `episodes` | 节目期次 + 收视数据 | Phase 2 |
| `yearly_targets` | 年度收视目标(只增不改) | Phase 2 |
| `topics` | 选题/报题单 | Phase 4a |
| `topic_embeddings` | 选题语义向量(1536 维)| Phase 4a |
| `schedules` | 节目排期 | Phase 4b |
| `knowledge_items` | 知识库条目(含 tags/related_entities/related_concepts JSONB) | Phase 3 |
| `knowledge_embeddings` | 知识库向量(1536 维)| Phase 3 |
| `review_comments` | 审片意见 | Phase 4b |
| `shooting_resources` | 拍摄资源/人脉 | Phase 4b |
| `radar_items` | 热点雷达条目 | Phase 4c |
| `radar_user_actions` | 编导操作记录 | Phase 4c |

> **重要**:`episodes` 表整合了"收视成绩"+"节目元数据"+"外拍信息",作为节目的全生命周期记录。
> **重要**:`yearly_targets` 表**只增不改**,详见 `.clinerules` 第 5.2 节。
> **重要**:编导关联用"软引用 + 快照"双字段,详见 `.clinerules` 第 5.3 节。

字段细节见 `backend/sql/001_init.sql`。

---

## 十二、用户与权限

| 角色拼音值 | 中文 | 主要权限 |
|---|---|---|
| `zhipianren` | 制片人/管理员 | 全部权限 |
| `zebian` | 责编 | 维护仪表盘 / 知识库 / 排期 |
| `biandao` | 编导 | 使用 TPS / 查看知识库 / 生成报题单 / 个人热点雷达 |

不开放公开注册。详见 `.clinerules` 第 5.5 节。

---

## 十三、待确认事项

- [x] 服务器配置:已确认旧机 2核2G,**新租 4核8G 轻量服务器**部署本系统
- [x] 技术栈(已落定 v2)
- [x] Phase 计划(已落定 v2)
- [x] 2.0 路线:Karpathy LLM Wiki 形态,1.0 预埋兼容接口
- [x] **Git + Gitea 工作流**(本版新增)
- [x] **Phase 2 起 Plan 切 MiniMax M2.7**(本版新增)
- [ ] 视觉风格(制片人提供参考图)
- [ ] 6 名编导初始画像描述(每位 200 字)
- [ ] 甘特图样本(可用通用电视节目模板起步)
- [ ] 腾讯云新服务器开租时机(Phase 4c 中段)

---

## 十四、会话恢复说明

**下次跟新对话框的 Claude 接力时,告诉它**:

> "请阅读 `project_plan.md`、`dev_plan.md`、`.clinerules`、`docs/git_workflow.md` 这是我们的项目宪法。`logs/` 下的 phase{N}_log.md 是已完成 Phase 的进度档案。从最新一份 log 的下一步继续。"

---

## 十五、版本演进

| 版本 | 日期 | 主要变化 |
|---|---|---|
| v1 | 2026-04 | 初版 |
| v2 | 2026-05-04 | 精简技术栈、Phase 拆分(避免 Phase 4 大爆炸)、明确每周里程碑 |
| v3 | 2026-05-06 | 加 Git + Gitea 工作流;Phase 0 重排(纳入 Git);Phase 2 起 Plan 切 MiniMax M2.7;明确单位机重启路径(路径 B 推荐);新增 docs/ 目录与 phase{N} tag 收尾仪式 |
| **v4** | **2026-05-14** | **家用机退役,唯一开发环境为单位 4090D;Phase 2 起 MiniMax M2.7 正式日常使用;更新版本演进记录** |

---

*本文件最高优先级中的"技术宪法"。任何阶段安排冲突以本文为准。*
*下次修订建议时机:Phase 4a MVP 上线后(根据使用反馈调整 Phase 4b/4c 优先级)。*
