Files
shop_helm/docs/05-coding-rules.md

177 lines
9.9 KiB
Markdown
Raw Permalink 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.
# 编码规则(Coding Rules)
> 每次改代码前完整读取。本文件是实现硬约束;产品范围以 [`02-requirements.md`](02-requirements.md) 为准,模块事实以 [`04-architecture.md`](04-architecture.md) 和 [`api.md`](api.md) 为准。
## 0. 黄金法则
1. **不臆造**:字段、平台规则、路径、依赖和接口必须查仓库事实。
2. **一次一事**:只实现当前 `DOING` 任务,不夹带 Backlog 和无关重构。
3. **依赖向内**:UI 和基础设施依赖 application/domain,domain 不依赖框架。
4. **先验证风险**:Gio 组件、Chrome profile 和图片合成闸门未通过前,不大规模铺业务页面。
5. **副作用可控**:进程、文件、数据库、剪贴板和恢复操作必须可观察、可失败、可追踪。
6. **完成有证据**:没有测试、构建和任务要求的 smoke,不得标记 `DONE`。
## 1. 动手前
- 按 `vision -> requirements -> tech-stack -> architecture -> api/routes -> tasks -> current-state` 建立上下文。
- 找到任务对应的需求 ID、服务合约和页面。
- 检查是否已有可复用 package、component、repository 和测试夹具。
- 运行标准基线并记录当前失败;基线坏时先处理基线。
- 查看工作区已有改动,保留不属于本任务的用户修改。
- 若任务会改变第三方平台数据、删除用户文件、保存秘密或扩大自动化范围,先停止并要求产品决策。
## 2. Go 规则
- package 名短小、全小写、单数优先,不使用 `utils`、`common`、`helpers` 作为无边界杂物包。
- 公开标识符只在跨包合约需要时导出;先使用小接口,接口由消费者定义。
- 所有 I/O 方法接收 `context.Context`,不把 context 存在 struct 中。
- 错误必须包装上下文并保留 `errors.Is/As` 可判定性,不比较底层错误字符串。
- 不使用 `panic` 处理可预期业务错误;启动期不可恢复错误可以返回到 `main` 后记录并退出。
- 不忽略返回值,不用空 `recover`,不在 library code 中 `os.Exit`。
- 时间通过注入的 Clock 获取,测试不依赖真实等待。
- 金额不用 `float64` 持久化;用最小货币单位整数,比例/汇率用可精确解析表示。
- 路径用 `filepath`,URL 用 `net/url`,CSV/XLSX 用结构化解析器,不手工拆字符串。
- 代码必须通过 `gofmt`;注释解释边界和原因,不复述代码。
## 3. 分层规则
- `internal/domain`:纯规则、实体和值对象,不导入 Gio、driver、Windows API。
- `internal/application`:用例编排和稳定错误码,不写 SQL、不布局 UI。
- `internal/infrastructure/sqlite`:repository 和 migration,不出现 UI 文案。
- `internal/platform`:进程、路径、剪贴板和文件副作用,不决定业务优先级。
- `internal/ui`:页面状态和展示,不直接打开数据库或启动进程。
- 不通过全局变量跨层共享数据库、页面状态或 process registry。
- 新增跨层调用前先更新 `api.md`;不得为绕过接口而从 UI 直接引用 concrete repository。
## 4. Gio 规则
- widget、clickable、editor、list、drag 和页面状态必须跨 frame 持久存在。
- layout 函数不得执行 SQL、文件读写、大图解码、网络请求、`Process.Wait` 或阻塞 channel receive。
- 用户动作只提交 intent;异步结果通过 event channel 返回并调用 window invalidate。
- 每个异步操作有 busy、success、error 和必要的 cancel 状态。
- 同一按钮请求进行中防重复提交。
- 页面切换保留列表筛选和滚动状态;销毁页面时取消所属 context。
- 固定画布、表格、工具栏和图标按钮设置稳定约束,动态文字不得挤压相邻控件。
- 关键状态不能只用颜色;图标按钮必须有 tooltip/可访问名称。
- 项目内组件只在存在真实复用时抽取,不创建通用 UI DSL。
- UI 自动测试不稳定时可以保留手工 smoke,但 domain/application 行为必须有自动测试。
## 5. SQLite 规则
- schema 只通过按序 migration 变化,已经提交或发布的 migration 不修改。
- 每个连接启用外键和 busy timeout。
- 多表写入、导入提交和计数更新使用事务。
- repository 查询显式列名,不使用 `SELECT *`。
- nullable 数据使用明确类型,不用魔法空字符串混淆“未填写”和有效值,除非 schema 已定义为空字符串语义。
- 列表查询有稳定排序、分页边界和必要索引。
- 唯一约束、外键约束和 busy 错误映射到稳定应用错误码。
- 测试使用临时目录的真实 SQLite,不共享开发数据库。
- 不把密码、Cookie、token、代理秘密或图片二进制写进数据库。
- 备份恢复前后执行完整性检查;失败必须保留可回滚旧库。
## 6. Chrome 与进程规则
- 只能用 `exec.CommandContext` 或经审查的等价 API 和独立参数启动,不使用 `cmd /c`、PowerShell 字符串或 shell 拼接。
- Chrome executable、profile 目录和目标 URL 分别校验。
- profile 必须是绝对规范路径;managed path 必须位于配置根目录内。
- 不使用默认用户 Chrome profile 作为 ShopHelm managed profile。
- 同一 profile 占用时返回 `profile_in_use`,不尝试强制解锁或删除 lock 文件。
- 不在命令行传密码、Cookie 或代理认证信息。
- 不默认加 `--remote-debugging-port`、规避检测或安全降级参数。
- 进程退出必须释放 registry;应用重启后不得相信陈旧 PID。
- 应用退出默认不杀用户打开的 Chrome;需要关闭能力时必须单独立项和确认。
- 测试参数生成时用 fake runner,真实 Chrome smoke 只能使用测试 profile 和非生产账号。
## 7. 文件、导入和图片规则
- 任何用户路径先做存在性、文件类型、权限和规范化检查。
- 读取外部文件不修改源文件。
- 写入先落同目录临时文件,成功 close/sync 后原子改名。
- 默认 `overwrite=false`;即使允许覆盖,也绝不能覆盖底图或叠加图。
- 图片解码设置尺寸和内存上限,防止异常大文件耗尽内存。
- 预览和导出共用 `CompositionPlanner`,不得复制位置/缩放公式。
- Gio framebuffer 截图不能作为正式图片输出。
- PNG alpha 和 JPG 背景有固定测试。
- CSV/XLSX 先 preview 后 commit;文件 fingerprint 改变时拒绝提交。
- 导入错误包含行号、字段和原因;不静默修复未知值。
- 删除数据库素材关联默认不删除物理文件。
## 8. 安全、隐私与合规
- 真实账号、密码、token、Cookie、买家隐私、私有 URL 不进入代码、文档、日志、截图或测试数据。
- 账号标识只用于人类识别;日志中仍应最小化或脱敏。
- 不实现绕验证码、绕风控、反指纹、刷单、刷评、批量抓取和未经确认的批量消息。
- 不把 `user-data-dir` 描述成防关联功能。
- 平台规则变化必须以官方来源为准,记录链接、访问日期和影响。
- 未来自动化默认具备 dry-run、明确预览、人工确认、速率边界、审计和取消。
- 操作日志记录 action、entity、result、error code,不记录完整话术、买家详情或命令秘密。
## 9. 依赖规则
- 新依赖前检查标准库和已引入依赖能否满足。
- 在 `03-tech-stack.md` 记录用途、版本策略和引入任务。
- 运行 `go mod tidy` 后审查直接和间接依赖变化。
- 不引入 ORM、Web 框架、嵌入浏览器、依赖注入框架或第二套图片库,除非新任务明确批准。
- `gioui.org/x/component` 只有 T-101 通过后才允许保留。
- 依赖升级单独提交,不与业务功能混在同一任务。
## 10. 测试规则
最低自动验证:
```powershell
go test ./...
go vet ./...
go build -o build/shophelm.exe ./cmd/shophelm
```
按改动增加:
- 并发和共享状态:`go test -race ./...`,若目标工具链不支持则记录真实原因。
- migration/repository:临时数据库从空库迁移,运行 CRUD、约束和重开测试。
- Chrome:参数单测、fake process 生命周期、Windows 真实 Chrome smoke。
- 图片:固定夹具 pixel/golden 测试、原图校验和、格式和失败清理。
- 导入:CSV/XLSX round-trip、错误行、fingerprint 和事务测试。
- 备份:完整性、恢复成功、损坏备份、替换失败回滚测试。
- Gio:对应页面手工 smoke,记录窗口尺寸、动作和观察结果。
测试禁止:
- 为绿灯删除断言、降低验收或跳过失败用例。
- 使用真实用户数据库、真实 Chrome profile 或真实店铺凭证。
- 依赖测试执行顺序或固定本机绝对路径。
## 11. 文档与提交
- 需求变化先改 `02-requirements.md`,再改代码。
- schema 或 service 合约变化同步 `04-architecture.md` 和 `api.md`。
- 页面变化同步 `routes.md`。
- 版本、依赖和命令变化同步 `03-tech-stack.md`、`00-ai-start-here.md`、`current-state.md` 和 `init.*`。
- 每轮实际命令和结果只追加到 `progress.md`。
- 提交只包含当前任务相关文件;不重写或撤销用户无关改动。
- 提交信息建议:`T-XXX: imperative summary`。
## 12. 完成定义
任务标记 `DONE` 前逐项确认:
- [ ] 需求 ID 和任务验收全部满足。
- [ ] 代码遵守模块和副作用边界。
- [ ] 自动测试、vet、build 通过。
- [ ] 任务要求的手工 smoke 已执行并记录环境。
- [ ] 没有真实秘密、隐私或生产路径进入变更。
- [ ] 没有无关重构或 Backlog 功能。
- [ ] 相关文档、任务状态和 current state 已同步。
- [ ] `progress.md` 有真实验证证据。
- [ ] `clean-state-checklist.md` 已通过。
## 13. 绝不
- 绝不明文保存密码。
- 绝不删除或强制解锁 Chrome profile。
- 绝不覆盖原始图片作为默认行为。
- 绝不在 Gio frame 中等待 I/O。
- 绝不把数据库 `running` 字段当真实进程状态。
- 绝不静默吞掉导入、恢复或导出中的部分失败。
- 绝不因为任务困难就跳过高风险闸门。