# Phase 1 开发日志 — 后端骨架 + 前端骨架

> 《军事科技》栏目内部工作台 · Phase 1
> 撰写日期:2026-05-05
> 状态:**后端骨架完成,前端骨架待开发**

---

## 一、本 Phase 完成时间

- **开始日期**:2026-05-05(Phase 0 环境安装完成后接入)
- **后端骨架完成日期**:2026-05-05
- **前端骨架开发**:进行中
- **预计 Phase 1 整体收官**:Week 1 末

---

## 二、本 Phase 做了什么

1. **搭起后端项目骨架**(FastAPI + SQLModel + PostgreSQL),从零到可启动状态。目录结构遵循 dev_plan.md 第七章规划,共 16 个 Python 文件 + 1 个 SQL 脚本 + 1 个 .env。

2. **一次性建完所有数据库表**(共 12 张):users / episodes / yearly_targets / topics / topic_embeddings / schedules / knowledge_items / knowledge_embeddings / review_comments / shooting_resources / radar_items / radar_user_actions。Phase 1 只用 users 表,但其他表的 SQL 一次到位,后续 Phase 直接用,不再分批加表。

3. **实现登录认证体系**:Session + Cookie 方案(不上 JWT),三个核心接口齐备 —— `POST /api/auth/login`、`POST /api/auth/logout`、`GET /api/auth/me`。密码用 passlib + bcrypt 加密存储。

4. **预埋 2.0 兼容字段**:knowledge_items 表已包含 tags / related_entities / related_concepts 三个 JSONB 字段,embedding 维度统一 1536(为未来 Karpathy LLM Wiki 形态做准备)。

5. **创建管理员引导脚本**:backend/scripts/create_admin.py,交互式输入用户名 / 显示名 / 密码,生成首个 zhipianren 角色账号 —— 这是 Phase 1 验收的必需前置。

---

## 三、关键决策记录(以后会忘但很重要)

### 3.1 角色英文枚举值最终命名:**拼音方案**

经过取舍,栏目三种角色的数据库 / 代码层枚举值定为:

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

**为什么选拼音不选英文**:栏目内部系统、几年内无外部协作者、无歧义压倒美观。英文版的 chief_editor(责编)和 editor(编导)极易被 AI 写错,拼音绝对不会混。

**这个决策已写入**:001_init.sql 的 CHECK 约束、UserRole Enum、create_admin.py 默认角色。后续所有权限判断、前端菜单、API 鉴权一律使用这套值,**不再改**。

### 3.2 数据库一次建完不分批

原本 Sonnet 方案是 Phase 1 只建 users 表。后修订为**一次建 12 张表**,理由:dev_plan 字段定义已很明确,分批建反而每次要写新 SQL + 改 SQLModel,不如一次到位。SQLModel 模型仍按 Phase 分批写。

### 3.3 依赖锁定关键版本

- `bcrypt==4.0.1`(显式锁旧版,避免新版 bcrypt 与 passlib 1.7.4 的兼容警告——不锁会一直报红字误以为出错)
- `itsdangerous==2.2.0`(SessionMiddleware 必需,不装会运行时报错)
- `python-multipart==0.0.9`(FastAPI 接收表单必需)
- starlette **不单独装**(它是 FastAPI 的传递依赖)

### 3.4 CORS 配置必须 allow_credentials=True

Session + Cookie 跨域时,CORS 必须 `allow_credentials=True`,且 `allow_origins` 不能用 `["*"]` —— 用 `*` 时浏览器会拒绝携带 cookie。所以必须显式写 `["http://localhost:5173"]`。

### 3.5 SQL 默认值与 SQLModel 协作策略

`created_at / updated_at` 字段用 `Field(default=None)` 配合数据库 `DEFAULT NOW()`,而非 `sa_column`,这样 SQLModel 不覆盖数据库默认值,时间戳由 PostgreSQL 兜底。

---

## 四、踩过的坑 + 怎么解决的

### 坑 1:DeepSeek v4-flash 调用工具漏参数

**现象**:Phase 1 一开始切到 Act 模式,Cline 弹红字 "execute_command without value for required parameter 'requires_approval'",连续重试 3 次都失败。

**原因**:DeepSeek v4-flash 是便宜快速款,工具调用(尤其参数多的工具)经常漏字段。Cline 的复杂任务(建项目结构、跑命令)刚好踩在它能力边界上。

**解决**:Start New Task,把 Act 模式的 Model 从 `deepseek-v4-flash` 临时切换到 `deepseek-v4-pro`,问题消失。**.clinerules 第 9 行已写明"复杂任务时临时切换 v4-pro"** —— 这就是那种情况。

**经验提炼成口诀**:
- 写新代码 / 建项目结构 / 改架构 → 用 v4-pro
- 改一两行小 bug / 加字段 / 改文案 → v4-flash 够用

### 坑 2:Sonnet 初始方案漏了几个隐性必备依赖

**现象**:Sonnet 第一版 requirements.txt 只列了 starlette(其实不需要单独装),漏了 itsdangerous、python-multipart、pydantic-settings,bcrypt 也没锁版本。

**解决**:在切 Act 之前的 Plan 阶段,Opus 4.7 一次性给出 5 条补充指令,Sonnet 全部消化落地。

**经验**:**关键技术节点(改 schema / 认证逻辑 / 依赖清单)在切 Act 前必须由 Opus 过一遍**,不能直接让 Sonnet 出方案就切 Act。

### 坑 3:PowerShell + psql + 中文注释的 UTF-8/GBK 撞车

**现象**:在 4090D 上跑 `psql -f sql/001_init.sql` 报 "character with byte sequence ... in encoding GBK has no equivalent in encoding UTF8" 一连串错误,12 张表仅建出 2 张。

**原因**:Windows PowerShell 默认代码页 GBK(936),psql 把 UTF-8 编码的 SQL 文件(含中文注释)按 GBK 读,导致中文字节序列在 GBK 里无对应字符。

**解决**:跑 psql 前先设环境变量:
```powershell
$env:PGCLIENTENCODING="UTF8"
```
每个新 PowerShell 窗口都要重设(只在当前会话有效)。

**经验**:Windows 上跑任何含中文注释的 SQL 文件,都先设这个变量。Phase 2 导数据、Phase 3 导知识库、Phase 5 部署上线都会再用到。

### 坑 4:Cline 工具终端无法处理交互式密码 / 输入

**现象**:`psql` 提示输 PG 密码、`create_admin.py` 中的 `input()` 和 `getpass()`,Cline 工具终端会挂起或超时。

**原因**:Cline 内置终端是非交互式的,不支持 stdin tty。

**解决**:遇到要凭据 / 互动的命令,Cline 给命令清单,制片人在自己的 PowerShell 窗口手动跑。

**经验**:Phase 2+ 凡是涉及交互式输入(部署、备份、ssh 凭据、psql 密码、应用初始化等)默认走人工,不让 Cline 尝试用 `--password`、stdin 重定向、heredoc 等方式绕过。这条值得 Phase 1 收尾时进 .clinerules 第三章作为正式规则。

---

## 五、遗留事项(Phase 1 收尾或未来 Phase 必须处理)

### 5.1 Phase 1 内部待完成

- [ ] **前端骨架开发**:Vite + React + AntD + Zustand 初始化,登录页 + 主布局 + 路由鉴权
- [ ] **前后端联调验收**:浏览器登录 → 看到主框架 → 刷新登录态保持 → 登出回到登录页
- [ ] **本地后端首次启动验证**:psql 跑 001_init.sql、create_admin.py 创管理员、uvicorn 启动后端、curl 或浏览器测三个接口

- [x] **路径 B 启动前一致性审查完成**(2026-05-11):
    - 1 项必改(.env 密码)、2 项建议改(create_admin.py 注释 + editor_name_snapshot NOT NULL)、
      4 项漏点已落实(.env 全审、cookie.txt 删除、__pycache__ 清理、.env.example 立项)
    - 1 项 user.py sa_column 写法留至 Phase 1 末再决
    - 1 项 schemas/auth.py 旧式 Config 留至 Phase 2+

- [x] **路径 B 后端跑通验证完成**(2026-05-11 当日):
    - pip install + 001_init.sql + create_admin + uvicorn 全部跑通
    - 三接口实测全 200,/me 返回 role:zhipianren(拼音生效)
    - 创建首个管理员账号 simonkoson(ID 1),角色 zhipianren
    - **Phase 1 后端骨架完工**,前端骨架另开 Task

### 5.2 跨 Phase 遗留(后续 Phase 触发时处理)

- [ ] **SECRET_KEY 占位符**:`.env` 当前是 `change-me-to-a-random-string-in-production`,**Phase 5 部署到腾讯云前必须改**为真实随机值。生成命令:`python -c "import secrets; print(secrets.token_urlsafe(32))"`

- [ ] **`.gitignore` 确认 .env 已忽略**:首次 git init 时检查,绝不能把 .env 上传

- [ ] **Pydantic v2 写法统一**:schemas/auth.py 当前用旧式 `class Config: from_attributes = True`,后续新建 schemas 文件统一用 `model_config = ConfigDict(from_attributes=True)`,旧文件随手改

- [ ] **pgvector 索引启用时机**:001_init.sql 中索引被注释掉,**待数据量到 ~1000 行**(大约 Phase 4a 中后期)再取消注释启用,前期低维度 + 少数据下顺序扫描更快

- [ ] **session 跨域 cookie 部署配置**:目前 `same_site="lax"` + `https_only=False` 是本地开发配置,**部署上线时改为 `same_site="strict"` + `https_only=True`**

- [ ] **其他 Phase 的 SQLModel 模型文件**:001_init.sql 已建齐 12 张表,但模型文件目前只有 user.py。各 Phase 启动时再建对应的 episode.py / topic.py / knowledge_item.py 等

- [ ] **scripts 目录用途**:专门放运维脚本(create_admin.py 已就位,未来可能加 seed_data.py、reset_password.py),**不要混进 app/**
- [ ] **`.env.example` 文件待创建**:供其他开发机 / Phase 5 部署参考。结构应与 .env 一致,但所有真实秘密替换为占位符。Phase 2 或 Phase 5 触发时补建。

---

## 六、本 Phase 用到的工具 / 模型回顾

| 角色 | 工具 / 模型 | 用途 |
|---|---|---|
| 制片人(刘通) | 人脑 + 浏览器 | 拍板、审核、卡壳兜底咨询 |
| 高级技术顾问 | Claude Opus 4.7(Claude.ai 网页) | 架构指导、方案审核、风险预警 |
| 架构师 | Sonnet 4.6(VS Code Cline Plan 模式) | 项目内方案设计、Act 改动审查 |
| 执行者 | DeepSeek v4-flash → v4-pro(VS Code Cline Act 模式) | 实际写代码 |

**模型切换教训**:Phase 1 初始用 v4-flash 卡壳,切 v4-pro 后顺畅完成。后续骨架级任务直接 v4-pro 起步,日常小改用 v4-flash。

---

## 七、当前可启动命令(供下次接手参考)

```bash
# 第一次启动后端的完整流程:
cd backend

# 1. 装依赖
pip install -r requirements.txt

# 2. 建库 + 建表
psql -U postgres -d milsci_dev -f sql/001_init.sql

# 3. 创建管理员账号(交互式)
python scripts/create_admin.py

# 4. 启动 FastAPI
uvicorn app.main:app --reload

# 5. 验证(浏览器或 curl):
#    GET  http://localhost:8000/docs        ← FastAPI 自动文档
#    POST http://localhost:8000/api/auth/login
#    GET  http://localhost:8000/api/auth/me
```

---

## 八、下一步(Phase 1 剩余 / Phase 2 准备)

1. **当下立刻做**:在本机执行上面"七、可启动命令"全套,验证后端骨架能否真跑起来
2. **后端跑通后**:开 Cline 新 Task,Plan 模式让 Sonnet 出前端骨架方案,Act 模式 v4-pro 实施
3. **Phase 1 完整收官标志**:浏览器打开 → 登录 → 看到主框架 → 刷新还在 → 登出
4. **进入 Phase 2 前**:写 phase2_log.md 之前的"本 Phase 完成时间"部分起头,然后开始仪表盘 + 用户管理 + 历史数据导入工作

---

## 九、前端骨架完工记录(2026-05-15)

### 9.1 完成时间
- **前端骨架开发日期**:2026-05-15
- **前端骨架状态**:✅ 已完成

### 9.2 完成内容

1. **Vite + React 项目初始化**:`npm create vite@latest frontend -- --template react`

2. **核心依赖安装**:
   - `antd` (UI 库)
   - `@ant-design/icons`
   - `zustand` (状态管理)
   - `react-router-dom` v6
   - `axios`
   - `dayjs`

3. **Vite 代理配置**:`vite.config.js` 中 `/api` → `http://localhost:8000`

4. **AntD 中文 locale + 主题**:主色 `#6b8e6b`(深绿),圆角 12px/16px

5. **CSS 变量定义**:`src/index.css` 中定义奶油底 `#fbf9f1`、深绿 `#6b8e6b`、浅绿 `#c8d9b0`

6. **Auth 体系**:
   - `services/http.js`:axios 实例,`withCredentials: true`
   - `services/authService.js`:login/logout/me 三接口
   - `stores/authStore.js`:Zustand,含 user/isLoading/login/logout/fetchMe

7. **路由守卫**:`components/AuthGuard/AuthGuard.jsx`,挂载时调用 me() 一次,401 跳转登录

8. **主布局**:`components/Layout/AppLayout.jsx` (侧边栏 + 顶栏 + 内容区 Outlet)

9. **侧边栏**:`SideNav.jsx`,6 项菜单(含 doco 占位),图标用 AntD icons

10. **顶栏**:`TopBar.jsx`,搜索框 + 通知 + 头像下拉(退出)

11. **登录页**:`pages/Login/Login.jsx`,AntD Form,用户名 + 密码,提交后调用 store.login()

12. **仪表盘**:`pages/Dashboard/Dashboard.jsx`:
    - 顶部 Banner(题图占位)
    - 3 个 KPI 卡(平均收视/完成率/待排期)
    - 热点雷达占位(模块 H,Phase 4c)
    - **近 9 期收视柱图**(假数据,三种颜色都有)
    - 排播计划占位(模块 F,Phase 4b)
    - 柱图下方:期次标题 + 编导头像 + 姓名
    - 左下角颜色规则注释:红=优秀/蓝=达标/绿=待提升

13. **空页占位**:TPS / 知识库 / 编导首页 / 用户管理 / 文稿对齐(Doco 用 Result 组件)

14. **路由配置**:`App.jsx` 中 Routes 嵌套,AuthGuard 包裹,共 7 个路由

### 9.3 技术决策

- **角色拼音值**:前端代码中所有角色判断用 `zhipianren/zebian/biandao`,不得用英文别名
- **收视颜色判定(反直觉)**:红=优秀(>摸高)/蓝=达标(基础~摸高)/绿=待提升(<基础)
- **Session + Cookie**:axios `withCredentials: true`,Vite 代理 `/api`
- **刷新登录态保持**:Zustand 初始 user=null,AuthGuard 挂载时调用 me() 补全

### 9.4 文档修正(同期完成)

- `README.md`:近 4 期 → 近 9 期
- `dev_plan.md`:近 4 期 → 近 9 期
- `docs/git_workflow.md`:Z:\AIworks\ 路径残留 → E:\tps-dashboard\

### 9.5 Git commit 记录

| commit | 内容 |
|---|---|
| b39b7c8 | chore: 清理 indexUI 中文文件名空格与重复字符 |
| e907876 | docs: 仪表盘收视柱图统一为近 9 期(制片人 2026-05-15 拍板) |
| 233cb85 | docs: git_workflow.md 第 2/3 章路径残留 Z:\AIworks → E:\tps-dashboard 修正 |
| fef9e81 | feat: frontend skeleton done |

### 9.6 遗留事项

- `frontend/src/App.css` 和 `frontend/src/assets/` 是 Vite 模板自带,未使用但已 commit(不影响功能)
- Phase 2 需接入真实后端 API 数据
- Phase 2 仪表盘真实柱图需替换假数据

---

*本日志由 MiniMax M2.7(Cline Act 模式)于 2026-05-15 前端骨架完工后追加。*
