Files
jiu/CLAUDE.md
T
wangjia 480ce836bb
Deploy / build-linux-web (push) Successful in 53s
Deploy / build-windows (push) Successful in 1m48s
Deploy / build-macos (push) Successful in 1m17s
Deploy / build-android (push) Successful in 4m13s
Deploy / build-ios (push) Successful in 9s
Deploy / release-deploy (push) Successful in 1m37s
chore: release v1.0.18
移动端响应式适配(抽屉导航/列表卡片/弹窗自适应)、Android 正式签名与 APK 发布、
iOS(TestFlight) 工程与 CI、多平台构建流水线、相关文档同步。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 07:55:33 +08:00

319 lines
11 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.
# 酒库管理系统 — 项目规则与 Orchestrator
## 必读
**开始任何任务前,先读 `docs/context/project.md`** 了解项目全貌。
---
## Orchestrator:如何自动选择 Agent
根据用户请求的关键词和意图,按以下规则判断调用哪些 Agent:
### 新功能开发(完整流水线)
触发词:「新增」「开发」「实现」「做一个」+ 功能描述
```
串行:requirements-analyst → architect
并行:api-designer + db-designer(同时进行,都依赖架构但互不依赖)
→ ui-designer 判断复杂度:
简单变更:直接输出规范 → 继续下一步
复杂设计:输出 Figma 需求文档 → 暂停等用户确认设计稿
并行:backend-coder + flutter-coder(都依赖 API 设计,互不依赖)
串行:test-engineer → linter → code-reviewer → security-auditor
```
### 仅后端修改
触发词:「修复后端」「后端接口」「API」+ 具体描述
```
backend-coder → test-engineer → linter → code-reviewer
```
### 仅前端修改
触发词:「UI」「界面」「Flutter」「页面」
```
flutter-coder → linter
```
### Bug 修复
触发词:「bug」「报错」「修复」「问题」
```
1. 先判断 bug 来源(后端/前端/数据库)
2. 调用对应的 coder agent 修复
3. test-engineer 验证修复
```
### 安全/代码质量检查
触发词:「安全」「漏洞」「review」「审查」「代码质量」
```
并行:security-auditor + code-reviewer + linter
```
### 线上问题
触发词:「线上」「故障」「宕机」「慢」「报错」
```
sre(优先级最高,立即响应)
→ 根据 sre 诊断结果,再决定是否调用 backend-coder 修复
```
### 文档需求
触发词:「文档」「说明」「手册」「README」
```
doc-writer
```
---
## Agent 边界规则(强制执行)
| Agent | 可以写 | 不可以写 |
|-------|--------|----------|
| requirements-analyst | docs/requirements/ | 任何代码 |
| architect | docs/architecture/ | 任何代码 |
| api-designer | docs/api/ | 任何代码 |
| db-designer | backend/schema/ | 业务代码、测试代码 |
| backend-coder | backend/internal/, backend/main.go | *_test.go, schema/ |
| ui-designer | docs/design/ | 任何代码 |
| flutter-coder | client/ | backend/ |
| test-engineer | *_test.go, docs/review/*-bugs.md | 业务代码 |
| linter | 格式自动修复(gofmt/dart format),docs/review/lint-report.md | 逻辑代码 |
| code-reviewer | docs/review/*-review.md | 任何代码 |
| security-auditor | docs/security/ | 任何代码 |
| devops | deploy/, .gitea/workflows/, scripts/ci/ | 业务代码 |
| sre | docs/runbooks/ | 任何代码 |
| doc-writer | docs/(除 context/ 外) | 任何代码 |
---
## Agent 间通信协议
**文件传递**(主要方式):
- 每个 Agent 完成后将结果写入约定文件
- 下游 Agent 开始前读取上游产出文件
- 文件格式:混合模式(中文叙述 + YAML/代码块)
**短链式调用**(反馈循环):
- test-engineer 发现 bug → 直接将错误信息和 `docs/review/{功能}-bugs.md` 路径传给 backend-coder
- security-auditor 发现 Critical 问题 → 直接告知 backend-coder 修复,不等下次迭代
---
## 并行 Agent 调度规则
当多个 Agent 可以并行时,在同一条消息中发起多个 Agent 调用:
```
# 可以并行的情况(互不依赖):
- api-designer + db-designer
- backend-coder + flutter-coder
- security-auditor + code-reviewer + linter
# 必须串行的情况(有依赖):
- requirements-analyst 完成后 → architect 才能开始
- architect 完成后 → api-designer 和 db-designer 才能并行开始
- backend-coder 完成后 → test-engineer 才能开始
```
---
## Git 提交规范
每个 Agent 完成工作后提交,commit message 格式:
```
{类型}({模块}): {简短说明}
类型:feat | fix | test | docs | chore | security | refactor
模块:backend | client | db | deploy | docs
示例:
feat(backend): 新增财务报表接口
test(backend): 财务报表模块测试用例
docs(api): 财务报表 API 接口文档
security: 修复入库单多租户隔离漏洞
```
---
## 开发完成标准(Definition of Done
**任何功能或修复,必须满足以下全部条件才算完成:**
### 后端变更
```bash
# 1. 编译通过
export PATH="/opt/homebrew/bin:$PATH"
cd backend && go build ./...
# 2. 所有测试通过(不得有 FAIL)
cd backend && go test ./...
# 3. 无编译警告(vet 检查)
cd backend && go vet ./...
```
### 前端变更
```bash
# 1. 静态分析无 errorwarning/info 允许存在)
cd client && flutter analyze --no-fatal-infos --no-fatal-warnings
# 2. 所有测试通过
cd client && flutter test
```
### 通用要求
- [ ] 代码已按 Git 提交规范提交(feat/fix/test/...
- [ ] 涉及新接口:已在对应测试文件中覆盖核心路径
- [ ] 涉及数据库变更:schema.sql 和 model 同步更新
- [ ] 多租户隔离未被破坏(所有查询含 shop_id 条件)
**测试未通过前,禁止提交代码、禁止打 tag 发版。**
---
## 代码质量门禁
以下情况**不得提交**
- `go build ./...` 失败
- `go test ./...` 有失败用例
- 存在 security-auditor 标记的 Critical 级别问题
- 存在 code-reviewer 标记的 blocking 级别问题
---
## 项目强制规则
### 多租户隔离
- `shop_id` **永远**从 JWT token 中提取,使用 `middleware.GetShopID(c)`
- **绝不**从请求参数、URL 或请求体中读取 `shop_id`
- 所有数据库查询必须带 `WHERE shop_id = ?` 条件
### 库存变更
- 入库/出库审核通过时,必须在同一事务中同时完成:
1. 更新 `inventories` 表数量
2. 写入 `inventory_logs` 流水记录
- 出库前必须校验库存充足,不足时返回错误并回滚
### Schema 管理
- 表结构变更:修改 `backend/schema/schema.sql` + `backend/internal/model/` 对应 model
- 启动时自动 AutoMigrate,无单独迁移文件
- **禁止**为每个新业务字段修改表结构,使用 `custom_fields JSON` 动态扩展
### 种子数据
- 测试数据以 SQL 文件形式维护:`backend/seeds/<shop_code>.sql`
- 通过 `sh scripts/dev.sh seed <shop_code>` 执行(内部用 `docker exec` 注入 MySQL 容器)
- 每个门店一个文件,SQL 文件顶部包含 TRUNCATE,每次执行完整重建
### Go 命令
- 所有 Go 命令前须确保 PATH`export PATH="/opt/homebrew/bin:$PATH"`
- 或直接使用 `sh scripts/dev.sh` 脚本(已内置 PATH
### 前端 URL 配置
- 所有后端 URL 必须通过 `AppConfig` 读取(`client/lib/core/config/app_config.dart`
- **禁止**在任何 provider / repository / widget 中硬编码 `localhost:8080` 或任何 IP/域名
- 使用:`AppConfig.apiBaseUrl``AppConfig.healthUrl``AppConfig.versionUrl`
### 前端平台判断
- 使用 `dart:io``Platform` 类前,必须先检查 `kIsWeb``import 'package:flutter/foundation.dart'`
- Web 平台不支持 `dart:io`,直接使用会在 Web 构建时崩溃
### 表格列头筛选
- 可筛选列使用 `FilterableColumnHeader`(来自 `widgets/multi_select_dropdown.dart`
- 不要在 toolbar 放独立的筛选按钮,筛选入口应内嵌在列头
- 列定义使用 `ColDef`,可隐藏列用 `ColumnToggleButton` 控制
### 响应式 / 移动端适配
- 断点判定统一用 `context.isMobile``client/lib/core/responsive/responsive.dart`,宽度 < 600 为窄屏/手机),**禁止**在各处散落 `MediaQuery.width < 600` 这类魔法数
- **列表屏**:用 `DataTableCard` 时必须同时传 `mobileCards`(窄屏渲染卡片流),卡片复用 `MobileListCard` / `MobileCardField``widgets/mobile_list_card.dart`);宽屏仍走原表格,行为不变
- **弹窗固定宽度**:一律用 `context.dialogWidth(X)`(≤ 屏宽 92%),**禁止**裸写 `width: <固定值>` 导致窄屏溢出
- **导航**:窄屏(手机)用 Drawer 抽屉(`app_shell.dart`),宽屏保持侧边栏;新增页面无需单独处理,挂在 shell 下即可
- 平台判断仍遵守上面「前端平台判断」规则(`kIsWeb` 先于 `dart:io`
### 权限中间件(已全局挂载)
- `middleware.ReadOnly()`:已挂载到主 `api` 路由组,只读用户(role=readonly)所有写操作自动返回 403
- `middleware.AdminOnly()`:挂载在 `/users` 路由组,仅管理员可管理用户
- **新增写操作路由**时,默认受 `ReadOnly()` 保护;若仅管理员可用,需加入 `AdminOnly()` 子组
### 并发安全(数据库操作)
- 在同一事务内读后写的操作,必须用 `FOR UPDATE` 锁行:
```go
tx.Set("gorm:query_option", "FOR UPDATE").Where(...).First(&model)
```
- 适用场景:单号生成(`number_rules`)、库存扣减(`inventories`)、任何 check-then-act 模式
### 发版流程
使用 `/release <version>` slash command
```
/release 1.0.2
```
执行顺序:本地 build → test → 更新 CHANGELOG.md → git commit → tag → push main+tag。
CI/CDForgejo`.gitea/workflows/deploy.yml`)收到 tag 后自动:编译 → 测试 → 创建 Release → 部署 EC2 → Telegram 通知。
**多平台构建矩阵**(脚本在 `scripts/ci/`):
- mac runner(容量 1)串行链:`build-linux-web`(后端+Web+官网)→ `build-macos` → `build-android` → `build-ios` → `release-deploy`
- windows runner 并行:`build-windows`Inno Setup 打包 setup.exe
- 分发:桌面(Win/macOS) 发布到下载页 `/downloads/` + 应用内更新;**Android** APK 同样挂 `/downloads/`,需 `ANDROID_*` 签名 secrets(见 `docs/android-signing.md`);**iOS** 走 TestFlight,需 `IOS_*` / `APPSTORE_*` secrets(见 `docs/ios-signing.md`
- Android/iOS 的 job 在对应 secrets 未配置时**优雅跳过**(exit 0,不阻塞发版);本地无 `client/android/key.properties` 时 APK 自动回退 debug 签名
**CHANGELOG 格式**Keep a Changelog):
```markdown
## [1.0.2] - YYYY-MM-DD
### 新功能
- ...
### 改进
- ...
### 修复
- ...
```
只保留有内容的分类。`/release` 会检查 CHANGELOG 是否已有该版本节,没有则从 git log 自动生成。
### 异常上报
客户端异常已在两处统一捕获,**无需**在每个业务层重复处理:
- `main.dart``FlutterError.onError` + `runZonedGuarded` 捕获所有未处理异常
- `api_client.dart`:Dio 拦截器自动上报所有 HTTP 5xx 错误
需要**手动调用** `reportError(e, st)` 的场景:
- 技术性异常(JSON 解析失败、第三方 SDK 崩溃等)
- **不需要**上报:`AppException` 及其子类(已知业务错误)
```dart
} catch (e, st) {
reportError(e, st); // 一行,fire-and-forget
rethrow;
}
```
### 搜索实现(拼音)
商品名搜索同时支持汉字、全拼、首字母:
- `products` 表有 `name_pinyin`(全拼)和 `name_initials`(首字母)两列
- Create / Update / FindOrCreate 写入时自动调用 `util.ToPinyin()` 生成,**无需手动维护**
- 启动时对 `name_pinyin = ''` 的存量数据自动回填(`backfillPinyin`
- 库存搜索 SQL 同时 LIKE 匹配 name、code、name_pinyin、name_initials
- 新增其他需要拼音搜索的实体时,复用 `backend/internal/util/pinyin.go` 的 `ToPinyin()`