Files
cmautobuy/admin/AGENTS.md
T
chengmaandClaude Opus 5 90379347b4 docs: 建立 Admin 子项目的文档基线
仓库从单子项目变成两个:client(Python + PyQt5 桌面端)和
admin(Go + Gin + HTML 模板 Web 管理端)。两者技术栈完全不同,
规则各自独立,只通过三个 HTTP 接口交互。

新增 admin/AGENTS.md 和 docs/admin/ 共 9 份文档,结构与 docs/client/ 对齐。

关键设计决策(均已与用户确认)
- 四模块:蝦皮数据 / 顺运宝数据 / 采购任务 / 客户端列表,
  统一三段式布局(工具条 / 带勾选的表格 / 状态条)
- 蝦皮数据拆成商品表 + SKU 表:报表本身就是两层结构,
  且 PDD 链接是商品级的,放 SKU 级会重复维护
- pdd_data 存商品级,一个 PDD 商品采一次,所有订单共用
- SKU 映射独立成表且可复用,同一蝦皮 SKU 只需人工匹配一次
- PDD 链接人工填写,采集按钮就放在填链接的编辑弹窗里
- 任务分配给指定客户端;不加心跳,注册在领取时完成,
  在线状态由 last_seen_at 派生
- SQLite 驱动固定 modernc.org/sqlite(纯 Go 免 cgo,go build 直接出 exe)
- 不引入前端框架和 npm 构建,只允许原生 JS 或 htmx

基于样本文件 raw_data/蝦皮数据样本.xlsx 实测得出的约束
- 11287 行 = 5195 商品汇总行 + 6092 SKU 行,导入必须分开处理
- 商品規格ID 零重复,是天然主键
- 规格原文两种格式各占 53.4% / 46.6%,只解析【】会漏掉一半
- 平均每商品仅 1.17 个 SKU,报表不是全量目录,
  因此必须支持手动新增,且货运单外键不能加硬约束

同步更新
- 根 AGENTS.md 开头的指针改为两个子项目对照表
- docs/README.md 重构为双子项目索引
- .gitignore 加 admin/data/、admin.exe、Excel 锁文件

说明:Gitea 尚未配置,本次无对应工单号。
raw_data/ 未提交,含台币销售额等商业数据,待用户决定。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 15:49:04 +08:00

100 lines
5.3 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.
# Admin 子项目规则
本文件适用于 `admin/` 下的全部代码、模板和测试,并继承仓库根目录 `AGENTS.md` 的
**红线**、工作流、Git、安全、文档和初级程序员维护规则。
## 开始工作前
- 从仓库根目录执行 Admin 任务时,也必须先读取本文件。
- 第一次接手,先看这两份:
- 环境和运行:[00 上手指南](../docs/admin/00-getting-started.md)
- 看不懂的词:[00 术语表](../docs/admin/00-glossary.md)
- 只读取与当前任务有关的长期基线,不必每次加载全部文档:
- 需求边界:[01 产品需求基线](../docs/admin/01-requirements.md)
- 分层和目录:[02 系统架构](../docs/admin/02-architecture.md)
- 数据库表:[03 数据模型](../docs/admin/03-data-model.md)
- 给 Client 的接口:[04 Client 接口实现](../docs/admin/04-client-api.md)
- 页面和交互:[05 界面规范](../docs/admin/05-ui-specification.md)
- 测试和安全:[06 质量与安全](../docs/admin/06-quality-security.md)
- Admin 提供的接口必须满足 Client 侧契约
[docs/client/04-admin-api-contract.md](../docs/client/04-admin-api-contract.md),
两边不一致时以 Client 契约为准,要改先走工单。
## 技术栈
- 固定使用 **Go + Gin + Go 标准库 `html/template`**。
- 数据库固定 **SQLite**,驱动固定 `modernc.org/sqlite`。
**不得改用 `mattn/go-sqlite3`** —— 那个要 cgo,Windows 上得装 gcc,
交叉编译和打包 exe 都会变得很麻烦。
- Excel 读取固定 `github.com/xuri/excelize/v2`。
- Go 版本固定 **1.23.0**,依赖版本以 `admin/go.mod` / `go.sum` 为准。
- 新增或升级依赖前先过工单;确认后把 `go.mod` 和 `go.sum` 一起提交。
### 前端约束
- **不得引入 React、Vue、Angular 等前端框架,不得引入 npm 构建流程。**
页面一律服务端渲染。
- 搜索、删除、导入这类操作用普通表单提交,**零 JavaScript**。
- 勾选、弹窗、导入进度确实需要 JS,只允许两种做法:
- 原生 JavaScript,直接写在模板里或放 `static/js/` 下的独立文件;
- htmx(单个 js 文件,无构建步骤)。
- **不得引入打包器**(webpack/vite/esbuild)。CSS 手写,放 `static/css/`。
## 代码分层
- `handler` 只负责解析请求、调用 service、渲染模板或返回 JSON,**不写业务逻辑,不拼 SQL**。
- `service` 放业务逻辑(导入解析、创建任务、匹配复用),不认识 Gin 的 `*gin.Context`。
- `repository` 封装 SQLite,**只有这一层能写 SQL**。
- `model` 只放数据结构,不导入 Gin 和数据库驱动。
- 给 Client 的接口和给浏览器的页面**分开放**(`handler/api/` 和 `handler/web/`),
两者的错误格式、认证方式都不一样,混在一起迟早出事。
## 数据与接口
- 表结构以 [03 数据模型](../docs/admin/03-data-model.md) 为准。
- 给 Client 的接口以 [docs/client/04-admin-api-contract.md](../docs/client/04-admin-api-contract.md) 为准。
- `[必须]` **金额一律用整数存**,人民币用分、台币用分,字段名带单位后缀(`_cent`)。
**禁止用 float 存金额。**
- `[必须]` 时间一律带时区 ISO 8601,库里存 UTC,页面上转本地时区显示。
- `[必须]` Excel 导入只做 **upsert(更新或新增)**,
**绝不允许先清空再导入** —— 会把人工填的 PDD 链接全洗掉。
- `[必须]` 蝦皮规格原文(`spec_raw`)永远保留,解析不出来就留空,不要瞎猜。
- `[必须]` Client 提交结果时,**不管任务是否已取消、是否已重派,一律接受**,
理由见 Client 契约 §6.1。这条最容易被顺手违反。
## 界面规则
- 四个模块统一使用三段式布局:**顶部工具条 / 中间带勾选的表格 / 底部状态条**。
第一个页面写完,其余三个照抄结构改字段,不要给某个模块搞特殊。
- 表格行的身份用业务主键,**不得用行号**。
- 批量删除必须二次确认,并显示"将删除 N 条"。
- 破坏性操作(删除、导入覆盖)用 POST,**不得用 GET**。
- 页面必须能在 1366×768 上正常使用,表格横向滚动而不是压缩列宽。
## 安全
- 根目录 `AGENTS.md` 的五条红线同样适用。
- `[必须]` 所有写操作(新增/编辑/删除/导入/建任务)加 CSRF 防护。
- `[必须]` SQL 一律用参数化查询,**禁止字符串拼接 SQL**。
- `[必须]` 模板输出走 `html/template` 的自动转义,
**禁止用 `template.HTML` 包裹用户可控内容**。
- `[必须]` 上传的 Excel 限制大小和扩展名,解析失败要有明确报错,不能让整个进程崩掉。
- `[必须]` 日志、页面、导出里不得出现 token、密码、Cookie。
## 验证
全部命令从 `admin/` 目录执行。
```powershell
go vet ./...
go build ./...
go test ./...
go run .
```
- `go run .` 启动后访问 `http://localhost:8080`,**不会连手机、不会下单**,可随时运行。
- 修改数据库时测试首次建库和从上一版本迁移。
- 修改给 Client 的接口时,跑契约测试,确认仍满足 Client 侧 §6.1 的无条件接受。
- 修改 Excel 导入时用 `raw_data/` 下的样本跑一遍,核对导入条数。
- 交付时说明已运行的命令、结果和未验证的部分。