2026-07-01 17:42:10 +08:00
|
|
|
|
# 执行进度记录
|
|
|
|
|
|
|
|
|
|
|
|
> 本文件是只追加的历史流水,用来记录任务执行过程、验证命令、阻塞点和关键决策。
|
|
|
|
|
|
> 当前目录、当前命令、下一个可领取任务等可覆盖快照,写入 [`docs/current-state.md`](docs/current-state.md)。
|
|
|
|
|
|
|
|
|
|
|
|
## 职责边界
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/06-tasks.md`:任务看板,维护任务状态、依赖和验收要点。
|
|
|
|
|
|
- `progress.md`:历史流水,只追加记录每轮执行发生了什么。
|
|
|
|
|
|
- `docs/current-state.md`:当前快照,可覆盖更新仓库现实、可运行命令和下一步。
|
|
|
|
|
|
|
|
|
|
|
|
不要在本文重复维护当前目录结构、当前运行命令或下一个任务;这些信息以 `docs/current-state.md` 为准。
|
|
|
|
|
|
|
|
|
|
|
|
## 记录格式
|
|
|
|
|
|
|
|
|
|
|
|
每完成或中断一轮任务,在文件末尾追加一条记录:
|
|
|
|
|
|
|
|
|
|
|
|
```markdown
|
|
|
|
|
|
## 【YYYY-MM-DD】T-【编号】 【任务名】
|
|
|
|
|
|
|
|
|
|
|
|
- 状态:【DONE / BLOCKED / PARTIAL】
|
|
|
|
|
|
- 变更:【修改了哪些文件或模块】
|
|
|
|
|
|
- 验证:【运行的真实命令和结果】
|
|
|
|
|
|
- 阻塞:【如有,写明原因和需要谁决策】
|
|
|
|
|
|
- 决策:【如有,记录本轮确定的关键取舍】
|
|
|
|
|
|
- 下一步:【建议下一个任务 ID 或待确认事项】
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 执行记录
|
|
|
|
|
|
|
|
|
|
|
|
## 2026-06-29 文档初始化(非任务)
|
|
|
|
|
|
|
|
|
|
|
|
- 状态:DONE
|
|
|
|
|
|
- 变更:基于 `D:\github\harness_coding_docs` 模板,结合需求讨论生成 `cmhub` 全套 harness 文档(AGENTS/CLAUDE、docs/00–06、api、routes、current-state、README、progress、init 脚本);通用流程文档(adoption/clean-state/method-map/evaluator/quality)从模板复制。
|
|
|
|
|
|
- 验证:仅文档,无代码可跑。
|
|
|
|
|
|
- 决策:技术栈 Django+DRF+django-admin;预付费点数模型(充值按汇率转点存本地,调用扣本地点数,不实时查支付系统);生成接口同步返回;充值由支付系统服务端回调入账(验签+幂等)。
|
|
|
|
|
|
- 下一步:领取 T-001 初始化 Django + DRF 骨架。支付系统接口文档待提供(T-304 前需要)。
|
|
|
|
|
|
|
|
|
|
|
|
## 2026-06-29 设计优化:可插拔供应商(别名 + 适配器)(非任务)
|
|
|
|
|
|
|
|
|
|
|
|
- 状态:DONE
|
|
|
|
|
|
- 变更:把「两个接口 + 后台配模型」的设计从简化版抬到可治理版,更新到多个文档:
|
|
|
|
|
|
- `04-architecture.md`:AI 调用层改为 Provider 适配器架构;新增 ModelAlias 表与 AiModel 的 capabilities/加密 key;PricingRule 改为按别名定价;CallRecord 增 alias + model_used;计费时序加入别名解析与能力校验;难点表补充抽象泄漏/供应商耦合/配置热生效/审计;项目结构加 `apps/ai/providers/`。
|
|
|
|
|
|
- `api.md`:对外 `model` 字段明确为能力别名;新增 `parameters` 透传;响应加 `model_used`;图片默认返回 URL;AI 模块合约改为别名解析 + Provider 适配器接口。
|
|
|
|
|
|
- `03-tech-stack.md` / `02-requirements.md` / `05-coding-rules.md` / `routes.md` / `06-tasks.md`:同步别名机制、密钥加密、配置审计、对象存储等决策与任务。
|
|
|
|
|
|
- 验证:仅文档;自检文档间链接与任务依赖一致(T-302 依赖更新为 T-104)。
|
|
|
|
|
|
- 决策:① 对外绑能力别名而非具体模型 SKU;② `api_type` 升级为显式 Provider 适配器层 + capabilities 声明 + parameters 透传;③ 供应商密钥加密存储 + 配置热生效 + 后台变更审计。按账号授权别名、按比例分流/故障转移列入 Backlog(接口预留,MVP 不实现)。
|
|
|
|
|
|
- 下一步:领取 T-001 初始化 Django + DRF 骨架(Phase 1 任务已重排为 T-101 适配器层 / T-102 别名解析 / T-103 审计 / T-104 跑通)。
|
|
|
|
|
|
|
|
|
|
|
|
## 2026-07-01 设计决策:桌面端全同步接入 + V2 异步预研(非任务)
|
|
|
|
|
|
|
|
|
|
|
|
- 状态:DONE
|
|
|
|
|
|
- 变更:把「桌面端不改、全同步接入 cmhub」的可用性结论与前提写入两个每轮必读文档:
|
|
|
|
|
|
- `03-tech-stack.md` 第二节「同步生成而非任务队列」决策下补:桌面端可不改交互骨架、只换 service 层 URL/密钥即可接入;同步可用的三前提;何时转 V2 异步的触发信号。
|
|
|
|
|
|
- `04-architecture.md` 第五节新增 `5.1 同步方案可用性结论`:超时链路层层放大对齐(点名 `timeout_seconds:0`、Gunicorn 30s、Nginx 60s 三个默认值雷,建议统一 300s)、worker 数按峰值总并发预留、适用边界与 V2 触发条件。
|
|
|
|
|
|
- 验证:仅文档;`ai_models.json` 现存 `timeout_seconds: 0`,迁入服务端时须改有限值(关联约束已写入 04 第五节)。
|
|
|
|
|
|
- 决策:① MVP 桌面端不改、`桌面端 → cmhub → 中转站` 全同步,多一跳不影响可用性,点数一致性更简单(一次请求闭环:预扣→同步调→成功/失败退点);② 同步可用的硬前提是「超时链路 + worker 容量」配对,否则「小量正常、上量假死」;③ 适用边界为单接入方小并发批量,V2 异步(队列)延后,但适配器接口与 `call_record` 三态需为异步预留口子。
|
|
|
|
|
|
- 安全提醒:`ai_models.json` 内三把 `sk-` 为明文真实密钥,视为已泄露,迁入时须加密存储(Fernet/KMS)并轮换;密钥不进桌面端。
|
|
|
|
|
|
- 下一步:不改变任务看板顺序,仍从 T-001 起步;V2 异步化触发条件见 03/04,暂不排期。
|
|
|
|
|
|
|
|
|
|
|
|
## 2026-07-01 设计决策:版本锁定 + 数据库选型(MySQL 8.4 独立实例)(非任务)
|
|
|
|
|
|
|
|
|
|
|
|
- 状态:DONE
|
|
|
|
|
|
- 变更:结合实际部署环境(一台 VPS,实测 15G 内存 / available 7.4G / 无 swap,已装 MySQL 5.7 供其他服务用),定稿版本与数据库选型,更新 `03-tech-stack.md`(技术栈表语言/框架/数据库三行 + 决策记录三条)、`04-architecture.md`(数据库条目 + 第五节并发扣点难点补 CHECK 版本注意)、`README.md` 技术栈行。
|
|
|
|
|
|
- 验证:仅文档。
|
|
|
|
|
|
- 决策:
|
|
|
|
|
|
- ① 框架/语言锁定 **Django 5.2 LTS + Python 3.12**(`requires-python ">=3.12,<3.14"`);禁用已 EOL 的 Django 4.0/4.1;理由是安全/维护窗口,非性能(性能瓶颈在等上游+worker,见 5.1)。
|
|
|
|
|
|
- ② 数据库定 **MySQL 8.4 LTS,cmhub 专用独立实例**。放弃复用 VPS 已有的 MySQL 5.7:5.7 跑不了 Django 5.2(需 ≥8.0.11)、已 EOL、不支持 CHECK 约束;曾评估「坚持 5.7」会连锁把 Django 拖回 4.0(EOL)+Python≤3.10+cmbot 兼容风险,被否。内存宽裕(7.4G),单开独立实例与已有 5.7 隔离、互不影响。
|
|
|
|
|
|
- ③ 硬性约束:InnoDB + utf8mb4;CHECK 需 MySQL ≥8.0.16 才生效,扣点主防线是 `select_for_update` / `UPDATE ... WHERE balance>=N`,不能只靠 CHECK;MySQL 默认隔离级别 REPEATABLE READ,计费按此语义验证;开发亦用 MySQL,不用 SQLite(会忽略 FOR UPDATE,测不出并发扣点)。
|
|
|
|
|
|
- 待办提醒:T-001 骨架落地时须选 MySQL 驱动(`mysqlclient` 或 `PyMySQL`)、`DATABASES` 配 `charset=utf8mb4`、连接指向独立实例端口;机器建议补 2–4G swap;`03` 部署维度仍为「待定」,部署基线待后续定稿。
|
|
|
|
|
|
- 下一步:不改变任务看板顺序,仍从 T-001 起步(Django+DRF 骨架,按上述版本/数据库落地)。
|
|
|
|
|
|
|
|
|
|
|
|
## 2026-07-01 定位扩展:新增自助用户端(B2B → B2B+B2C)(非任务)
|
|
|
|
|
|
|
|
|
|
|
|
- 状态:DONE
|
|
|
|
|
|
- 变更:按用户新增需求(终端用户自助注册/扫码充值/API Key 管理/查记录),把项目从纯 B2B API 网关扩展为「自助用户端 + 计费 API + 运营后台」三合一,系统性更新文档:
|
|
|
|
|
|
- 定位/需求:`01-vision`、`00-ai-start-here`、`02-requirements`、`project-brief`、`project-onepager`(用户角色加注册用户;MVP 加用户端;移除"自助注册"非目标;注册不送点数)。
|
|
|
|
|
|
- 架构:`04-architecture`(系统结构加用户端;数据模型 Account→`User`+`UserWallet`+`ApiKey`;两套认证;4.2 加自助扫码下单时序;难点加 API Key 哈希/注册滥用/Web-API worker 隔离/充错账户;项目结构 apps;架构纪律)。
|
|
|
|
|
|
- 合约/路由/规则:`api.md`(认证主体 User、`recharge/create` 转正扫码、API 只认 Key)、`routes.md`(用户端页面路由、admin 改 User/Wallet/ApiKey)、`03-tech-stack`(用户端形态 Django SSR+Bootstrap+allauth、鉴权、部署 worker 隔离)、`05-coding-rules`(范围、API Key 哈希、API 只认 Key、锁 wallet)。
|
|
|
|
|
|
- 任务:`06-tasks`(T-002 首迁移前定自定义 User;T-201 改 User/Wallet/ApiKey;T-203 锁 wallet;T-305 扫码下单;新增 Phase 4 用户端 T-501~504;里程碑加 M4 用户端)。
|
|
|
|
|
|
- `README`、`current-state` 同步。
|
|
|
|
|
|
- 验证:仅文档。
|
|
|
|
|
|
- 决策:
|
|
|
|
|
|
- ① 前端形态选 **Django 模板 SSR 单体**(+Bootstrap/allauth/crispy),不引前后端分离框架。
|
|
|
|
|
|
- ② 用户模型:`User`(auth 登录态) / `UserWallet`(点数余额,扣点锁 wallet、与 auth 解耦) / `ApiKey`(User 1:N,sha256 哈希存储、明文只显示一次)。
|
|
|
|
|
|
- ③ 认证分两套认同一 User:用户端 session+CSRF,对外 API 只挂 API Key(不挂 Session,防绕过计费)。
|
|
|
|
|
|
- ④ 充值:`recharge/create` 转正,用户端自助扫码下单 + 回调入账,订单绑定 user 防充错账户,金额 Decimal 向下取整。
|
|
|
|
|
|
- ⑤ **注册不送免费点数**(必须充值才有点数,降低薅羊毛);注册须邮箱验证、生成接口须限流。
|
|
|
|
|
|
- ⑥ 单体部署按路径把图片 API 与用户端页面分流到不同 worker 池。
|
|
|
|
|
|
- 待办提醒:**支付系统扫码下单 + 回调接口文档仍未提供**,是 T-304/T-305 充值的硬阻塞;自定义 User 必须在首次 migrate 前定义(Django 硬约束)。
|
|
|
|
|
|
- 下一步:任务仍从 T-001 起步;用户端任务见 Phase 4(T-501~504)。
|
|
|
|
|
|
|
|
|
|
|
|
## 2026-07-01 补全支付协议(参考同系统 PHP 实现,解除充值 blocker)(非任务)
|
|
|
|
|
|
|
|
|
|
|
|
- 状态:DONE
|
|
|
|
|
|
- 变更:从 Obsidian 笔记(虎观虾皮一键采购 `扫码支付购买流程-技术文档` + `扫码支付迁移到Django-实施指南`)提取同一支付系统的扫码支付协议,补进当前 Django 仓库文档:
|
|
|
|
|
|
- `api.md`:充值段重写为微信 V3 native + 支付宝当面付双回调(`/recharge/callback/wechat`、`/alipay`)+ `create`(pay_method、code_url/qr_code)+ `status` 轮询;金额单位、验签、幂等、应答格式明确。
|
|
|
|
|
|
- `04-architecture.md` 4.2:补通道协议、库、金额单位、回调应答、`@csrf_exempt`、主动查单兜底。
|
|
|
|
|
|
- `03-tech-stack.md`:充值对接行加库 `wechatpayv3`/`python-alipay-sdk`。
|
|
|
|
|
|
- `routes.md`:拆微信/支付宝回调端点 + status。
|
|
|
|
|
|
- `06-tasks.md`:T-304 拆双回调+主动查单,T-305 加 weixin/alipay+轮询。
|
|
|
|
|
|
- `05-coding-rules.md`:回调 `@csrf_exempt` + 主动查单兜底。
|
|
|
|
|
|
- `current-state.md`:blocker 降级。
|
|
|
|
|
|
- 验证:仅文档。
|
|
|
|
|
|
- 决策:
|
|
|
|
|
|
- ① 路线确认:**继续当前 Django 仓库**,Obsidian 的 Go(Gin+GoAdmin) cmhub 方案仅作支付逻辑参考(用户拍板)。
|
|
|
|
|
|
- ② 支付通道:微信 V3 native(`wechatpayv3`,金额**分**,回调 SDK 验签解密、`TRANSACTION.SUCCESS`、应答 `{code:SUCCESS}`);支付宝当面付 `trade.precreate`(`python-alipay-sdk`,金额**元**,`verify`、`TRADE_SUCCESS/FINISHED`、应答 `success`)。
|
|
|
|
|
|
- ③ 二维码不含业务数据,靠 `out_trade_no`(=order_no) 在回调关联;回调 `@csrf_exempt`;幂等 `select_for_update`+`status!=pending`;须主动查单兜底。
|
|
|
|
|
|
- ④ 只取支付层,不引入 Obsidian 源里的套餐/会员有效期/邀请返佣业务(那是虎观助手专有);充值入账走本项目 `UserWallet`+`points_ledger`+`ExchangeRate`。
|
|
|
|
|
|
- 待办提醒:**blocker 从「协议缺失」降级为「仅缺商户密钥/证书真实值」**,不阻塞开发,可先 mock。原 PHP 遗留坑(测试后门号、H5 金额写死、支付宝 debug 沙箱、明文密钥)不迁入。
|
|
|
|
|
|
- 下一步:任务仍从 T-001 起步;充值见 T-304/T-305(可 mock 先行)。
|
|
|
|
|
|
|
|
|
|
|
|
## 2026-07-01 吸收 AI 模型调用机制(来自 Go 方案 §16.6)(非任务)
|
|
|
|
|
|
|
|
|
|
|
|
- 状态:DONE
|
|
|
|
|
|
- 变更:从 Obsidian `Golang-Gin-GoAdmin-技术方案` §16.6 提取三个上游模型的真实调用机制(业务规则/上游契约,非技术栈),补进 `04-architecture.md`(3.1 + AI 层职责)、`api.md`(待确认 + image 改图必传)、`03-tech-stack.md`、`06-tasks.md`(T-101 验收)。
|
|
|
|
|
|
- 验证:仅文档。
|
|
|
|
|
|
- 决策:
|
|
|
|
|
|
- ① GPT-5.5(`chat`)标准 chat/completions;Nano Banana 2(`api_type=auto`)走 chat/completions 多模态返图、需自定义解析、可文/图生图;GPT Image 2(`images_edits`)走 images/edits 改图、原图必传。
|
|
|
|
|
|
- ② 两个图片模型**非标准** `images/generations`,每模型独立 url+key;图片返回结构(URL/base64/位置)**首次对接抓真实响应再定解析**。
|
|
|
|
|
|
- ③ 只吸收 AI 模型机制,**不吸收** Go 方案的会员套餐/续期/折扣/邀请返佣/多端 JWT(属虎观采购业务或 Go 栈,非 cmhub 定位);鉴权继续用 API Key(比桌面端 JWT 更安全,不在桌面端存密码)。
|
|
|
|
|
|
- 下一步:T-101/T-102 实现适配器时按此机制,首次对接 `api.vectorengine.ai` 抓真实响应确认图片返回结构。
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 后续从这里向下继续追加记录。 -->
|
|
|
|
|
|
|
|
|
|
|
|
## 2026-07-01 文档优化:定位一致性 + 充值 schema + 调用状态 + 环境配置(非任务)
|
|
|
|
|
|
|
|
|
|
|
|
- 状态:DONE
|
|
|
|
|
|
- 变更:按全栈落地前优先级修正文档:
|
|
|
|
|
|
- `docs/README.md` / `project-brief.md` / `project-onepager.md`:定位同步为「自助用户端 + 计费型 AI 能力网关 + 运营后台」三合一,并加入 `env.md` 导航。
|
|
|
|
|
|
- `docs/04-architecture.md` / `docs/api.md` / `docs/06-tasks.md`:充值订单改为下单时锁定 `exchange_rate` 与 `points_granted`,回调入账使用订单值并校验金额;`call_record.status` 明确为 `pending -> success / failed`,失败退点通过 `points_ledger(refund, ref_call_id)` 关联。
|
|
|
|
|
|
- `docs/env.md`:新增环境变量与配置清单,覆盖 Django、MySQL、AI 密钥加密、微信/支付宝、对象存储与上线检查。
|
|
|
|
|
|
- `docs/03-tech-stack.md` / `docs/current-state.md` / `docs/00-ai-start-here.md` / `docs/02-requirements.md` / 汇报文档:同步环境配置入口、当前快照与支付 blocker 降级口径。
|
|
|
|
|
|
- 验证:文档修改;用 `rg` 定位相关段落,未运行代码测试(仓库当前尚无代码)。
|
|
|
|
|
|
- 阻塞:无。
|
|
|
|
|
|
- 决策:充值汇率采用「下单锁定」而非「回调时读取当前汇率」,便于页面展示预计到账点数,也避免用户扫码后后台改价导致入账变化;调用记录不增加 `refunded` 状态,账务冲正由点数流水表达。
|
|
|
|
|
|
- 下一步:仍从 T-001 初始化 Django + DRF 骨架开始。
|
|
|
|
|
|
|
|
|
|
|
|
## 2026-07-01 文档优化:里程碑口径同步(非任务)
|
|
|
|
|
|
|
|
|
|
|
|
- 状态:DONE
|
|
|
|
|
|
- 变更:同步汇报文档里程碑到 `06-tasks.md` 的 M1-M5 口径:`project-brief.md` 增加 M4 用户端可用、M5 验收上线;`project-onepager.md` 进度行同步 M4/M5。
|
|
|
|
|
|
- 验证:文档修改;用 `rg` 定位里程碑旧口径。
|
|
|
|
|
|
- 阻塞:无。
|
|
|
|
|
|
- 决策:以 `06-tasks.md` 的里程碑为权威,汇报文档只做同口径摘要。
|
|
|
|
|
|
- 下一步:仍从 T-001 初始化 Django + DRF 骨架开始。
|
|
|
|
|
|
|
|
|
|
|
|
## 2026-07-01 文档优化:Phase 顺序口径同步(非任务)
|
|
|
|
|
|
|
|
|
|
|
|
- 状态:DONE
|
|
|
|
|
|
- 变更:更新 `docs/00-ai-start-here.md` 的优先路径,Phase 3/4/5 与 `docs/06-tasks.md` 对齐:Phase 3 为对外 API 与充值,Phase 4 为用户端,Phase 5 为后台与发布。
|
|
|
|
|
|
- 验证:文档修改;用 `rg` 对照 `00-ai-start-here.md` 与 `06-tasks.md` 的 Phase 标题。
|
|
|
|
|
|
- 阻塞:无。
|
|
|
|
|
|
- 决策:任务阶段顺序以 `06-tasks.md` 为权威,入口文档只做一致的导航摘要。
|
|
|
|
|
|
- 下一步:仍从 T-001 初始化 Django + DRF 骨架开始。
|
2026-07-01 18:01:23 +08:00
|
|
|
|
|
|
|
|
|
|
## 2026-07-01 T-001 初始化 Django + DRF 项目骨架
|
|
|
|
|
|
|
|
|
|
|
|
- 状态:DONE
|
|
|
|
|
|
- 变更:
|
|
|
|
|
|
- 新增 `manage.py`、`config/` Django 工程骨架。
|
|
|
|
|
|
- 新增 `requirements.txt`,锁定 Django 5.2 系列与 DRF 3.16 系列。
|
|
|
|
|
|
- `config/settings.py` 加入 `rest_framework`,`SECRET_KEY` / `DEBUG` / `ALLOWED_HOSTS` 支持环境变量,默认仅用于本地开发。
|
|
|
|
|
|
- `init.ps1` / `init.sh` 替换为真实命令;按用户要求使用系统 Python 3.12,不使用虚拟环境。Windows 用 `py -3.12`,Unix/WSL 用 `python3.12`。
|
|
|
|
|
|
- 同步 `docs/00-ai-start-here.md`、`docs/03-tech-stack.md`、`docs/current-state.md`、`docs/06-tasks.md`、`README.md`。
|
|
|
|
|
|
- 验证:
|
|
|
|
|
|
- `py -3.12 -m pip install -r requirements.txt`:Django 5.2.15 / DRF 3.16.1 已安装。
|
|
|
|
|
|
- `py -3.12 manage.py check`:通过,0 issues。
|
|
|
|
|
|
- `py -3.12 manage.py test`:通过,当前 0 tests。
|
|
|
|
|
|
- `./init.ps1`:通过,完成依赖检查、`manage.py check`,打印启动命令。
|
|
|
|
|
|
- `C:\Python312\python.exe manage.py runserver 127.0.0.1:8765 --noreload`:端口 smoke 通过(TCP 8765 可连接),随后已停止进程。
|
|
|
|
|
|
- `bash -n init.sh`:当前机器无可用 bash/WSL,无法本机验证 Unix 脚本。
|
|
|
|
|
|
- 阻塞:无。
|
|
|
|
|
|
- 决策:T-001 不接入 MySQL、不创建自定义 User、不创建 apps 目录;这些按任务边界留给 T-002。T-001 阶段暂保留 Django 默认 SQLite 配置用于框架启动检查,T-002 必须在首次迁移前改为自定义 User + MySQL 8.4 配置。
|
|
|
|
|
|
- 下一步:领取 T-002 建立 apps 目录、自定义 User 与配置。
|