603 lines
19 KiB
Markdown
603 lines
19 KiB
Markdown
# 老板一句话闭环 Implementation Plan
|
||
|
||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||
|
||
**Goal:** 建立第一版后端最小闭环:老板一句话生成 AI 草稿,人工确认后创建事项或提醒,通过飞书通知接收人并记录反馈和失败。
|
||
|
||
**Architecture:** 使用 Django 模块化单体。DRF view 负责请求入口,serializer 负责入参出参校验,service 负责权限、状态流转、事务和幂等,client 负责阿里百炼和飞书外部调用,audit 负责操作日志和失败记录。
|
||
|
||
**Tech Stack:** 部署 Python 3.12.13、本地开发 Python 3.11/3.12、Django 5.2 LTS、Django REST Framework、Django ORM、PostgreSQL 18.x、Django management command scheduler、阿里百炼 API、飞书开放平台。
|
||
|
||
---
|
||
|
||
## 施工前必须阅读
|
||
|
||
1. `AGENTS.md`
|
||
2. `ARCHITECTURE.md`
|
||
3. `docs/specs/01_老板AI秘书与AI草稿.md`
|
||
4. `docs/specs/02_事项任务.md`
|
||
5. `docs/specs/03_飞书通知与反馈.md`
|
||
6. `docs/specs/04_定时提醒.md`
|
||
7. `docs/specs/05_权限日志失败记录.md`
|
||
8. `docs/contracts/API接口约定.md`
|
||
9. `docs/contracts/数据对象约定.md`
|
||
10. `docs/contracts/状态流转约定.md`
|
||
11. `docs/contracts/安全权限日志约定.md`
|
||
12. `docs/checklists/AI生成代码检查清单.md`
|
||
13. `docs/checklists/后端Review清单.md`
|
||
|
||
## 范围边界
|
||
|
||
本计划只做第一版最小闭环:
|
||
|
||
```text
|
||
老板一句话
|
||
-> AI 草稿
|
||
-> 人工确认
|
||
-> 创建事项或定时提醒
|
||
-> 飞书通知
|
||
-> 接收人反馈
|
||
-> 页面/API/Admin 可看到结果和失败记录
|
||
```
|
||
|
||
本计划不做 AI 工作台、技能市场、文件上传、多模态处理、会议纪要、日报、文档摘要、复杂反馈看板、复杂 BI、成本驾驶舱、完整工作流、完整项目管理、多级子任务、甘特图、复杂审批流、复杂组织架构、cron 表达式、日历系统、自动操作交易系统、自动操作历史数据库、自动读取员工本地文件、手机端网页完整适配,也不把飞书机器人开放为程经理或普通员工通用派活入口。
|
||
|
||
## 可执行性门禁
|
||
|
||
1. 本计划先跑通 mock-first 后端闭环;单元测试和最小闭环测试不得访问真实百炼、真实飞书或公网回调。
|
||
2. 真实联调前必须确认飞书正式应用、HTTPS 回调地址、个人消息权限、交互卡片权限、老板 / 程经理 / 第一批试用人员映射,以及百炼 API Key 环境变量。
|
||
3. Docker / 部署环境固定 Python 3.12.13;本地开发允许 Python 3.11 或 3.12,但提交前必须在 Python 3.12.13 环境跑完整测试。
|
||
4. scheduler 必须作为独立进程运行,同一环境同一应用库同时只能启动一个 scheduler 进程。
|
||
5. tests 是真实约束;每个任务完成前必须说明新增或修改了哪些测试、覆盖哪些 spec / contract 约定和如何运行。
|
||
|
||
## 文件结构
|
||
|
||
第一轮代码施工建议创建这些目录和文件:
|
||
|
||
```text
|
||
requirements.txt
|
||
manage.py
|
||
config/
|
||
__init__.py
|
||
settings.py
|
||
urls.py
|
||
wsgi.py
|
||
apps/
|
||
accounts/
|
||
people/
|
||
prompts/
|
||
audit/
|
||
drafts/
|
||
tasks/
|
||
reminders/
|
||
notifications/
|
||
feedbacks/
|
||
feishu/
|
||
tests/
|
||
```
|
||
|
||
每个 Django app 采用统一结构:
|
||
|
||
```text
|
||
apps/<app>/
|
||
__init__.py
|
||
admin.py
|
||
apps.py
|
||
models.py
|
||
serializers.py
|
||
services.py
|
||
urls.py
|
||
views.py
|
||
tests/
|
||
```
|
||
|
||
外部 API 封装放在:
|
||
|
||
```text
|
||
apps/drafts/ai_client.py
|
||
apps/feishu/client.py
|
||
apps/feishu/signature.py
|
||
```
|
||
|
||
---
|
||
|
||
### Task 1: Django 项目骨架和依赖基线
|
||
|
||
**Files:**
|
||
- Create: `requirements.txt`
|
||
- Create: `manage.py`
|
||
- Create: `config/__init__.py`
|
||
- Create: `config/settings.py`
|
||
- Create: `config/urls.py`
|
||
- Create: `config/wsgi.py`
|
||
- Create: `apps/__init__.py`
|
||
- Create: `apps/accounts/__init__.py`
|
||
- Create: `apps/accounts/apps.py`
|
||
- Create: `apps/people/__init__.py`
|
||
- Create: `apps/people/apps.py`
|
||
- Create: `apps/prompts/__init__.py`
|
||
- Create: `apps/prompts/apps.py`
|
||
- Create: `apps/audit/__init__.py`
|
||
- Create: `apps/audit/apps.py`
|
||
- Create: `apps/drafts/__init__.py`
|
||
- Create: `apps/drafts/apps.py`
|
||
- Create: `apps/tasks/__init__.py`
|
||
- Create: `apps/tasks/apps.py`
|
||
- Create: `apps/reminders/__init__.py`
|
||
- Create: `apps/reminders/apps.py`
|
||
- Create: `apps/notifications/__init__.py`
|
||
- Create: `apps/notifications/apps.py`
|
||
- Create: `apps/feedbacks/__init__.py`
|
||
- Create: `apps/feedbacks/apps.py`
|
||
- Create: `apps/feishu/__init__.py`
|
||
- Create: `apps/feishu/apps.py`
|
||
|
||
- [ ] **Step 1: 写依赖文件**
|
||
|
||
`requirements.txt` 第一版固定包含:
|
||
|
||
```txt
|
||
Django==5.2.15
|
||
djangorestframework==3.17.1
|
||
psycopg[binary]
|
||
asgiref==3.11.1
|
||
sqlparse==0.5.5
|
||
tzdata==2026.2
|
||
python-dotenv==1.2.2
|
||
requests==2.34.2
|
||
httpx==0.28.1
|
||
APScheduler==3.11.2
|
||
django-apscheduler==0.7.0
|
||
dashscope==1.25.23
|
||
alibabacloud-bailian20231229==2.13.1
|
||
lark-oapi==1.6.8
|
||
PyJWT==2.13.0
|
||
cryptography==49.0.0
|
||
gunicorn==26.0.0
|
||
```
|
||
|
||
- [ ] **Step 2: 创建 Django 项目骨架和 app 空壳**
|
||
|
||
使用 `config` 作为项目配置包,`apps` 作为业务 app 根目录。Task 1 必须先创建所有业务 app 的 `__init__.py` 和 `apps.py`,保证后续加入 `INSTALLED_APPS` 时可导入。
|
||
|
||
- [ ] **Step 3: 配置 settings**
|
||
|
||
`config/settings.py` 必须包含:
|
||
|
||
1. `INSTALLED_APPS` 加入 Django contrib app、DRF,以及已创建且可导入的业务 app 空壳。
|
||
2. Task 1 暂不设置 `AUTH_USER_MODEL`;Task 2 实现 `apps.accounts.models.User` 后、首次 `makemigrations` / `migrate` 前再设置 `AUTH_USER_MODEL = "accounts.User"`。
|
||
3. 数据库配置读取环境变量。
|
||
4. 飞书和百炼密钥只读取环境变量。
|
||
5. 日志配置避免输出密钥。
|
||
|
||
- [ ] **Step 4: 运行 Django 检查**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
python manage.py check
|
||
```
|
||
|
||
Expected: `System check identified no issues`。
|
||
|
||
---
|
||
|
||
### Task 2: 账号、人员映射、Prompt、AI 记忆和审计基础模型
|
||
|
||
**Files:**
|
||
- Modify: `config/settings.py`
|
||
- Create: `apps/accounts/models.py`
|
||
- Create: `apps/people/models.py`
|
||
- Create: `apps/prompts/models.py`
|
||
- Create: `apps/audit/models.py`
|
||
- Create: `apps/drafts/models.py`
|
||
- Create: `apps/accounts/admin.py`
|
||
- Create: `apps/people/admin.py`
|
||
- Create: `apps/prompts/admin.py`
|
||
- Create: `apps/audit/admin.py`
|
||
- Test: `apps/accounts/tests/test_permissions.py`
|
||
- Test: `apps/audit/tests/test_sensitive_logging.py`
|
||
|
||
- [ ] **Step 1: 实现自定义 User**
|
||
|
||
字段必须覆盖 `docs/contracts/数据对象约定.md` 中的 `users`。实现后立刻在 `config/settings.py` 设置 `AUTH_USER_MODEL = "accounts.User"`,且必须发生在第一次迁移之前。
|
||
|
||
- [ ] **Step 2: 实现 PersonMapping**
|
||
|
||
字段必须覆盖 `person_mappings`,并支持别名 JSON、`user_id` 和 `manager_user_id`。`users` 负责登录和权限,`person_mappings` 负责称呼、飞书身份和第一批试用人员映射。
|
||
|
||
- [ ] **Step 3: 实现 PromptContext**
|
||
|
||
支持 `company_background_summary`、`boss_communication_style`、`ai_secretary_rules`、`role_and_alias_rules` 四类上下文,只允许同类一个 `active` 版本。
|
||
|
||
- [ ] **Step 4: 实现 AI 对话记忆基础表**
|
||
|
||
实现 `secretary_conversations`、`secretary_messages`、`bot_contexts`。`secretary_messages` 只追加,不修改;`bot_contexts` 保存当前待确认草稿、30 分钟过期时间、`follow_up_count` 和 `extracted_facts`。JSON 弹性字段使用 PostgreSQL `jsonb`,不得用内存隐藏保存可确认状态。
|
||
|
||
- [ ] **Step 5: 实现 FailureRecord、OperationLog、ModelCallLog**
|
||
|
||
失败类型和状态必须来自 `docs/contracts/状态流转约定.md`。
|
||
|
||
- [ ] **Step 6: 写权限、AI 记忆和脱敏测试**
|
||
|
||
测试必须覆盖:
|
||
|
||
1. 普通员工不能访问失败记录列表。
|
||
2. 普通日志工具不会输出完整手机号。
|
||
3. 普通日志工具不会输出完整邮箱。
|
||
4. 日志元数据不会保存 API Key、App Secret 或飞书 token。
|
||
5. `secretary_messages` 幂等键 `source + message_id` 不重复写入。
|
||
6. PostgreSQL AI 记忆读写失败时返回 `memory_store_failed`,不继续依赖内存确认草稿。
|
||
|
||
- [ ] **Step 7: 生成并运行迁移**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
python manage.py makemigrations
|
||
python manage.py migrate
|
||
python manage.py test apps.accounts apps.audit apps.drafts
|
||
```
|
||
|
||
Expected: migrations 成功,权限、审计和 AI 记忆测试通过。
|
||
|
||
---
|
||
|
||
### Task 3: AiSecretaryAgent、AI 输出校验和统一消息入口
|
||
|
||
**Files:**
|
||
- Modify: `apps/drafts/models.py`
|
||
- Create: `apps/drafts/serializers.py`
|
||
- Create: `apps/drafts/ai_client.py`
|
||
- Create: `apps/drafts/services.py`
|
||
- Create: `apps/drafts/views.py`
|
||
- Create: `apps/drafts/urls.py`
|
||
- Test: `apps/drafts/tests/test_ai_output_validator.py`
|
||
- Test: `apps/drafts/tests/test_parse_service.py`
|
||
|
||
- [ ] **Step 1: 实现 AiDraft 模型和 AiSecretaryResponse 结构**
|
||
|
||
字段必须覆盖 `ai_drafts`,状态必须来自 `状态流转约定.md`。`qa/realtime_qa/note/need_more_info/unknown/unsupported/context_summary` 不进入事项、提醒或通知闭环,只写 `secretary_messages`、`model_call_logs`、必要 `operation_logs`,或按 contract 写最小留痕草稿。
|
||
|
||
- [ ] **Step 2: 实现 AI 输出 validator**
|
||
|
||
validator 必须校验:
|
||
|
||
1. JSON 可解析。
|
||
2. `intent` 只能是 `task/reminder/qa/realtime_qa/note/need_more_info/unknown/unsupported`。
|
||
3. `task` / `reminder` 才允许 `should_create_draft = true`,`draft_type` 必须对应为 `task` 或 `reminder`。
|
||
4. `qa/realtime_qa/note/need_more_info/unknown/unsupported` 必须 `should_create_draft=false`、`draft_type=none`。
|
||
5. `need_more_info` 时 `questions` 至少 1 个、最多 3 个;其他 intent 时 `questions` 为空数组。
|
||
6. `task` 时 `route_type` 只能是 `direct_after_boss_confirm` 或 `manager_confirm_required`,其他 intent 为 `none`。
|
||
7. `answer` 不得出现“已通知、已创建、已发送”等执行语义。
|
||
8. 结构化字段不得包含明显游戏化表达,也不得编造老板没说过的业务结论。
|
||
|
||
- [ ] **Step 3: 实现可 mock 的 ai_client**
|
||
|
||
`ai_client` 只封装阿里百炼调用,不修改业务表。测试中必须使用 mock,不访问真实网络。
|
||
|
||
- [ ] **Step 4: 实现 AiSecretaryAgent service**
|
||
|
||
service 流程:
|
||
|
||
```text
|
||
记录原始消息
|
||
-> 按 source + message_id 做幂等检查
|
||
-> 校验老板角色
|
||
-> 读取 BotContext
|
||
-> 判断 follow_up / new_request / qa / realtime_qa / note / unknown / unsupported / command
|
||
-> 组装 PromptContext
|
||
-> 调用 ai_client
|
||
-> 写 model_call_logs
|
||
-> 校验 AiSecretaryResponse JSON
|
||
-> 生成草稿 / 追问 / 直接回复
|
||
-> 写 secretary_messages、operation_logs 和必要 failure_records
|
||
```
|
||
|
||
- [ ] **Step 5: 实现 API**
|
||
|
||
实现:
|
||
|
||
1. `POST /api/secretary/handle-message`
|
||
2. `GET /api/ai-drafts`
|
||
3. `GET /api/ai-drafts/{id}`
|
||
4. `PATCH /api/ai-drafts/{id}`
|
||
5. `POST /api/ai-drafts/{id}/cancel`
|
||
6. `POST /api/ai-drafts/{id}/follow-up`
|
||
|
||
兼容接口 `/api/ai-drafts/parse`、`/api/demo/boss-message` 可以保留,但内部必须转发到 `/api/secretary/handle-message`。
|
||
|
||
- [ ] **Step 6: 跑测试**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
python manage.py test apps.drafts
|
||
```
|
||
|
||
Expected: AI 输出校验、解析失败、实时问答、补充/重说测试全部通过。
|
||
|
||
---
|
||
|
||
### Task 4: 事项、提醒、通知和反馈模型与服务
|
||
|
||
**Files:**
|
||
- Create: `apps/tasks/models.py`
|
||
- Create: `apps/tasks/services.py`
|
||
- Create: `apps/tasks/views.py`
|
||
- Create: `apps/reminders/models.py`
|
||
- Create: `apps/reminders/services.py`
|
||
- Create: `apps/reminders/views.py`
|
||
- Create: `apps/notifications/models.py`
|
||
- Create: `apps/notifications/services.py`
|
||
- Create: `apps/feedbacks/models.py`
|
||
- Create: `apps/feedbacks/services.py`
|
||
- Test: `apps/tasks/tests/test_task_permissions.py`
|
||
- Test: `apps/reminders/tests/test_reminder_permissions.py`
|
||
- Test: `apps/feedbacks/tests/test_feedback_rules.py`
|
||
|
||
- [ ] **Step 1: 实现模型**
|
||
|
||
字段必须覆盖 `tasks`、`reminders`、`notifications`、`feedbacks`。`notifications` 必须包含 `target_type=ai_draft`、`purpose`、`trigger_time`、`idempotency_key`、`action_token_hash`、`expires_at`、`invalidated_at` 等字段。
|
||
|
||
- [ ] **Step 2: 实现事项 service**
|
||
|
||
必须支持:
|
||
|
||
1. 老板和程经理创建事项。
|
||
2. 普通员工不能给别人创建事项。
|
||
3. 程经理确认复杂事项。
|
||
4. 通知失败保留失败状态。
|
||
5. 有问题反馈必须填写原因。
|
||
|
||
- [ ] **Step 3: 实现提醒 service**
|
||
|
||
必须支持:
|
||
|
||
1. 所有人创建自己的提醒。
|
||
2. 老板和程经理给别人创建提醒。
|
||
3. 普通员工不能给别人创建提醒。
|
||
4. 一次性、每天、每周、每月重复规则。
|
||
5. 暂停、恢复、取消。
|
||
|
||
- [ ] **Step 4: 实现通知和反馈 service**
|
||
|
||
必须支持:
|
||
|
||
1. 生成飞书通知记录。
|
||
2. 使用幂等键避免重复通知。
|
||
3. 接收人反馈。
|
||
4. 非接收人反馈返回 `permission_denied`,并写 `FailureRecord(permission_error)`。
|
||
|
||
- [ ] **Step 5: 实现 API**
|
||
|
||
按 `docs/contracts/API接口约定.md` 实现 tasks、reminders、notifications、feedbacks 相关接口。
|
||
|
||
- [ ] **Step 6: 跑测试**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
python manage.py test apps.tasks apps.reminders apps.notifications apps.feedbacks
|
||
```
|
||
|
||
Expected: 权限、状态、反馈原因和通知失败测试通过。
|
||
|
||
---
|
||
|
||
### Task 5: 飞书登录、机器人事件和卡片回调
|
||
|
||
**Files:**
|
||
- Create: `apps/feishu/models.py`
|
||
- Create: `apps/feishu/client.py`
|
||
- Create: `apps/feishu/signature.py`
|
||
- Create: `apps/feishu/services.py`
|
||
- Create: `apps/feishu/views.py`
|
||
- Create: `apps/feishu/urls.py`
|
||
- Test: `apps/feishu/tests/test_signature.py`
|
||
- Test: `apps/feishu/tests/test_event_idempotency.py`
|
||
- Test: `apps/feishu/tests/test_bot_access.py`
|
||
- Test: `apps/feishu/tests/test_card_callback.py`
|
||
|
||
- [ ] **Step 1: 实现 FeishuEvent 和 FeishuAuthSession**
|
||
|
||
字段必须覆盖 `feishu_events` 和 `feishu_auth_sessions`。
|
||
|
||
本任务所有测试必须 mock 飞书 SDK / HTTP client,不依赖真实飞书应用、公网回调或个人消息权限。
|
||
|
||
- [ ] **Step 2: 实现验签**
|
||
|
||
验签失败返回 `feishu_signature_invalid`,不得执行业务动作。
|
||
|
||
- [ ] **Step 3: 实现事件幂等**
|
||
|
||
同一 `event_id` 重放时只返回已有处理结果,不重复创建草稿、事项、提醒或反馈。没有稳定 `event_id` 的卡片回调必须使用 `idempotency_key`。
|
||
|
||
- [ ] **Step 4: 实现老板机器人入口**
|
||
|
||
非老板私聊机器人时:
|
||
|
||
```text
|
||
不调用 AI
|
||
不生成草稿
|
||
回复当前入口仅对老板开放
|
||
写 bot_unauthorized 失败记录
|
||
```
|
||
|
||
- [ ] **Step 5: 实现卡片回调**
|
||
|
||
支持:
|
||
|
||
1. 老板确认草稿。
|
||
2. 老板补充/重说。
|
||
3. 老板取消草稿。
|
||
4. 接收人反馈事项或提醒。
|
||
5. 程经理待确认提醒只跳转平台。
|
||
6. 旧卡片、失效卡片、已替代草稿和已过期通知只记录 `feishu_events`,不写业务对象。
|
||
|
||
- [ ] **Step 6: 跑测试**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
python manage.py test apps.feishu
|
||
```
|
||
|
||
Expected: 验签、幂等、非老板访问、卡片反馈测试通过。
|
||
|
||
---
|
||
|
||
### Task 6: 草稿转换、事项通知和提醒调度闭环
|
||
|
||
**Files:**
|
||
- Modify: `apps/drafts/services.py`
|
||
- Modify: `apps/tasks/services.py`
|
||
- Modify: `apps/reminders/services.py`
|
||
- Modify: `apps/notifications/services.py`
|
||
- Create: `apps/reminders/management/commands/run_reminder_scheduler.py`
|
||
- Test: `apps/drafts/tests/test_convert_draft.py`
|
||
- Test: `apps/reminders/tests/test_scheduler.py`
|
||
- Test: `apps/notifications/tests/test_notification_retry.py`
|
||
|
||
- [ ] **Step 1: 实现草稿确认和转换**
|
||
|
||
`confirmed -> converted` 只允许执行一次。`task` 草稿转换为事项,`reminder` 草稿转换为提醒。转换失败时不回滚老板确认,写 `FailureRecord(draft_convert_failed)`。
|
||
|
||
- [ ] **Step 2: 实现复杂事项转程经理确认**
|
||
|
||
`route_type = manager_confirm_required` 时,老板确认后草稿进入 `confirmed`,转换时先创建 `tasks.status=pending_manager_confirm` 的事项壳,并生成给程经理的飞书提醒;事项壳创建成功后草稿进入 `converted`。程经理确认事项壳后补齐接收人和内容,再进入通知流程。
|
||
|
||
- [ ] **Step 3: 实现 scheduler command**
|
||
|
||
命令名:
|
||
|
||
```bash
|
||
python manage.py run_reminder_scheduler
|
||
```
|
||
|
||
scheduler 只扫描 `active` 且 `next_trigger_at <= now` 的提醒。一次性提醒成功触发后走 `active -> triggered`;每天、每周、每月提醒成功触发后保持 `active`,只更新 `last_triggered_at` 和下一次 `next_trigger_at`。
|
||
|
||
同一环境同一应用库只允许一个 scheduler 进程运行;测试中要用幂等键验证重复扫描不会重复创建通知。
|
||
|
||
- [ ] **Step 4: 实现提醒触发幂等**
|
||
|
||
幂等键:
|
||
|
||
```text
|
||
reminder_id + trigger_time + receiver_id + notification_channel
|
||
```
|
||
|
||
- [ ] **Step 5: 实现通知补发**
|
||
|
||
补发必须保留原失败记录,并写新的通知发送结果。
|
||
|
||
- [ ] **Step 6: 跑测试**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
python manage.py test apps.drafts apps.reminders apps.notifications
|
||
```
|
||
|
||
Expected: 草稿不重复转换、提醒不重复触发、通知补发测试通过。
|
||
|
||
---
|
||
|
||
### Task 7: Admin、路由汇总、最小验收脚本
|
||
|
||
**Files:**
|
||
- Modify: `config/urls.py`
|
||
- Modify: `apps/*/admin.py`
|
||
- Create: `tests/test_minimal_closure.py`
|
||
- Modify: `README.md`
|
||
|
||
- [ ] **Step 1: 汇总 API 路由**
|
||
|
||
`config/urls.py` 挂载:
|
||
|
||
1. `/api/secretary/`
|
||
2. `/api/ai-drafts/`
|
||
3. `/api/tasks/`
|
||
4. `/api/reminders/`
|
||
5. `/api/notifications/`
|
||
6. `/api/feedbacks/`
|
||
7. `/api/failure-records/`
|
||
8. `/api/feishu/`
|
||
9. `/api/auth/feishu/`
|
||
|
||
- [ ] **Step 2: 注册 Admin**
|
||
|
||
Admin 至少可查看和维护:
|
||
|
||
1. 用户。
|
||
2. 人员映射。
|
||
3. Prompt 上下文。
|
||
4. AI 草稿。
|
||
5. 事项。
|
||
6. 提醒。
|
||
7. 通知。
|
||
8. 反馈。
|
||
9. 失败记录。
|
||
10. 操作日志。
|
||
11. 模型调用日志。
|
||
12. 飞书事件。
|
||
|
||
- [ ] **Step 3: 写最小闭环测试**
|
||
|
||
测试覆盖:
|
||
|
||
```text
|
||
boss 用户提交一句话
|
||
-> mock AI 返回 task 草稿
|
||
-> boss 确认
|
||
-> 创建事项
|
||
-> mock 飞书通知成功
|
||
-> 接收人反馈 completed
|
||
-> 事项状态 completed
|
||
-> 有操作日志和通知记录
|
||
```
|
||
|
||
- [ ] **Step 4: 更新 README 本地启动**
|
||
|
||
补充:
|
||
|
||
1. 安装依赖。
|
||
2. 环境变量。
|
||
3. 迁移。
|
||
4. 创建测试用户。
|
||
5. 启动 Web。
|
||
6. 启动 scheduler。
|
||
7. 运行测试。
|
||
|
||
- [ ] **Step 5: 跑完整测试**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
python manage.py test
|
||
python manage.py check
|
||
```
|
||
|
||
Expected: 全部测试通过,Django check 无错误。
|
||
|
||
---
|
||
|
||
## 完成标准
|
||
|
||
1. 所有模型字段与 `docs/contracts/数据对象约定.md` 一致。
|
||
2. 所有状态与 `docs/contracts/状态流转约定.md` 一致。
|
||
3. 所有接口路径与 `docs/contracts/API接口约定.md` 一致。
|
||
4. AI 只生成草稿,人工确认后才创建事项或提醒。
|
||
5. 普通员工不能给别人创建事项或提醒。
|
||
6. 飞书回调验签和幂等有测试。
|
||
7. 定时提醒重复触发防护有测试。
|
||
8. 通知失败、AI 解析失败、回调失败有失败记录。
|
||
9. 普通日志不包含密钥、token、完整手机号或完整邮箱。
|
||
10. OAuth code/state、回调验签密钥、一次性操作 token 明文不进入普通日志或业务表。
|
||
11. 每个任务完成前说明新增或修改了哪些 tests、覆盖哪些 spec / contract 约定和如何运行。
|
||
12. `python manage.py test` 和 `python manage.py check` 通过。
|
||
|
||
## 执行备注
|
||
|
||
如果执行中发现本计划与 spec 或 contracts 冲突,以 contracts 为准,并先提出计划变更建议;不要偷偷修改业务边界。
|