Files
tps-dashboard/logs/phase2_log.md
T

146 lines
4.9 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.
# Phase 2 开发日志 — 仪表盘真数据 + 用户管理 + Excel 批量导入
> 《军事科技》栏目内部工作台 · Phase 2
> 撰写日期:2026-05-15
> 状态:**Task 1 后端 CRUD 完成,待实测验收**
---
## 一、本 Phase 完成时间
- **开始日期**:2026-05-15
- **Task 1 后端 CRUD**:2026-05-15 完成,待 Swagger UI 实测
- **Task 2 Excel 批量导入**:进行中
- **Task 3 前端**:待开始
- **预计 Phase 2 整体收官**:待定
---
## 二、本 Phase 做了什么
### Task 1 — 后端 CRUD2026-05-15
1. **models**`episode.py`(软引用+快照)、`yearly_target.py`year UNIQUE
2. **schemas**`episode.py``yearly_target.py``user_admin.py``auth.py` 顺手改 ConfigDict
3. **API**`users.py`(管理员 CRUD)、`episodes.py`(增改查)、`yearly_targets.py`(只增不改)
4. **路由注册**`main.py` 注册新路由
---
## 三、业务红线验证记录
| 红线 | 代码位置 | 验证结果 |
|------|----------|----------|
| 收视颜色只对 audience_share | `episode.py` 注释 | ✅ 未实现颜色逻辑,仅存字段 |
| 年度目标只增不改 year UNIQUE | `yearly_targets.py` create_target + `yearly_target.py` UNIQUE | ✅ 冲突报 409 |
| year 字段禁止 UPDATE 修改 | `yearly_targets.py` update_target pop("year") | ✅ 已拦截 |
| editor_id 可空+editor_name_snapshot 必填 | `episode.py` Field 设计 | ✅ editor_id 可空,snapshot 必填 |
| 角色枚举全拼音 | `UserRole` Enum + CHECK 约束 | ✅ 三角色全是拼音 |
| ON CONFLICT DO NOTHING(非 UPDATE | `yearly_targets.py` 注释 | ✅ 只增不改 |
| password_hash 明文传输开发配置 | `security.py` + `main.py` https_only=False | ⚠️ Phase 5 部署前必改 |
---
## 四、Swagger UI 验收清单
> 启动后端后访问:http://localhost:8000/docs
> 用管理员账号 simonkoson 登录后,点 Authorize 输入用户名密码
**最小验收集(共 6 步):**
**① POST /api/users — 新建 zebian 账号**
```json
{
"username": "test_zebian",
"display_name": "测试责编",
"password": "Test1234",
"role": "zebian"
}
```
预期:200,返回用户信息(id/username/display_name/role
**② POST /api/yearly_targets — 新建 2026 年度目标**
```json
{
"year": 2026,
"base_target": 0.65,
"stretch_target": 0.90
}
```
预期:201,返回目标信息
**③ POST /api/yearly_targets — 再建 2026 年(重复)**
```json
{
"year": 2026,
"base_target": 0.70,
"stretch_target": 0.95
}
```
预期:409detail 包含"2026 年目标已存在,历史年份不可覆盖"
**④ POST /api/episodes — editor_id 留空测软引用**
```json
{
"episode_number": 9999,
"program_name": "验收测试期次",
"air_date": "2026-05-15",
"editor_id": null,
"editor_name_snapshot": "测试编导张三",
"audience_share": 0.72
}
```
预期:201editor_id 为 nulleditor_name_snapshot 为"测试编导张三"
**⑤ GET /api/episodes — 列表查询**
预期:200,返回数组(包含上一步创建的 9999 期)
**⑥ PATCH /api/yearly_targets/{id} — 尝试改 year**
body: `{"year": 2027}`
预期:year 字段被忽略或报错(year 禁止修改)
---
## 五、遗留事项
### 5.1 Phase 2 内部待完成
- [ ] **Task 1 实测验收**:制片人 Swagger UI 过 6 步,上方可查验收清单
- [ ] **git push**:认证失败,需制片人手动 push(见 phase1_log.md 坑4
- [ ] **Task 2**:Excel 批量导入(收视数据 + 排期模板)
- [ ] **Task 3**:前端仪表盘 + 录入界面 + 用户管理界面
### 5.2 跨 Phase 遗留
#### Phase 4 或后续 Task 处理
- **PATCH /api/users 接口 password 相关权限**:当前 `UserUpdate` Schema 允许改 `is_active``role``display_name``profile_text`,但:
- `password_hash` **不允许**通过 API 修改(当前设计)
- 能否改自己密码?不能(当前设计)
- 改别人密码是否强制对方下次登录改密?未实现
- 建议 Phase 4+ 新增独立 `/api/users/change-password` 接口,设计时拉 Op
#### Phase 5 部署时处理(与 SECRET_KEY 并列)
- **传输安全**:当前 `password` 在请求体明文传输,仅 HTTPS 环境下可接受。Phase 5 部署到腾讯云后:
-`same_site="strict"` + `https_only=True`
- 确认 HTTPS 开启,强制全站 TLS
- 考虑 API 请求体密码加密或单独 `/api/auth/change-password` 接口
- **SECRET_KEY 占位符**`.env` 当前是 `change-me-to-a-random-string-in-production`**Phase 5 部署前必须改**为真实随机值。生成命令:
```python
python -c "import secrets; print(secrets.token_urlsafe(32))"
```
---
## 六、Git commit 记录
| commit | 内容 |
|--------|------|
| 143601c | docs: 合入第十三章 Opus task brief 节制原则,版本升至 v5 |
| 33bee0c | feat: 后端 CRUD 完成(episodes + yearly_targets + users 管理 API |
---
*本日志由 MiniMax M2.7(Cline Act 模式)于 2026-05-15 持续追加。*