Files
Neo-ZQYY/CLAUDE.md
2026-04-10 06:24:13 +08:00

215 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.
# CLAUDE.md
本文件为 Claude Code (claude.ai/code) 在本仓库工作时的指导规范。
## 语言(强制)
始终使用中文,覆盖所有场景:
- 对话回复、解释、提问、状态更新 → 中文
- 代码注释 → 中文
- Git commit message → 中文描述 + 英文 Co-Authored-By 签名行
- PR 标题与正文 → 中文
- 审计记录、文档、变更说明 → 中文
- 错误提示、日志说明 → 中文
- 变量名/函数名/类名 → 保持英文(编程惯例)
- 第三方 API 字段名、CLI 命令 → 保持原文
禁止在回复中使用英文段落或英文标题(技术术语、代码片段、专有名词内嵌除外)。
## 项目概览
NeoZQYY Monorepo — 面向台球门店业务的全栈数据平台。多门店隔离(`site_id` + RLS领域语言中文货币 CNY金额 `numeric(2)`
### 子系统
| 目录 | 说明 |
|------|------|
| `apps/etl/connectors/feiqiu/` | 飞球 ConnectorAPI → ODS → DWD → DWS |
| `apps/backend/` | FastAPI 后端JWT 双认证、WebSocket、AI 集成) |
| `apps/miniprogram/` | 微信小程序C 端Donut + TDesign |
| `apps/admin-web/` | 系统管理后台React+Vite+AntD— 开发/运维视角,操作 ETL 库 |
| `apps/tenant-admin/` | 租户管理后台React+Vite+AntD— 门店管理员视角,操作业务库 |
| `apps/mcp-server/` | MCP ServerPostgreSQL 只读AI 工具集成) |
| `packages/shared/` | 跨项目共享包enums, money, datetime_utils |
| `apps/demo-miniprogram/` | MOCK 小程序(假数据驱动,页面样式/展示格式标杆校对) |
| `db/` | 权威 DDL`schemas/`/ 迁移归档 / FDW 配置 |
| `tools/` | 通用工具db/reporting/health/h5-to-mp-checker |
| `scripts/ops/` | 日常运维脚本ETL 监控、数据回填、导出等) |
### 两个管理后台的区别
- `admin-web`:开发/运维用ETL 配置、数据质量、系统监控,全局视角
- `tenant-admin`:门店管理员用(`site_admin`/`tenant_admin`),用户审核/管理、Excel 上传、维客线索,门店隔离视角
## 技术栈
- Python 3.10+uv workspace4 成员etl/connectors/feiqiu、backend、mcp-server、shared
- 前端React + Vite + Ant Design各应用独立 pnpm
- PostgreSQL 四库:`etl_feiqiu` / `test_etl_feiqiu`ETL六层 Schema`zqyy_app` / `test_zqyy_app`(业务)
- DSN`PG_DSN`ETL`APP_DB_DSN`(业务),根 `.env` 定义
- 配置分层:`.env` < `.env.local` < 环境变量 < CLI 参数
## 常用命令
```bash
# 依赖安装
uv sync # Python 全量安装
cd apps/admin-web && pnpm install # 前端admin-web / tenant-admin 各自独立)
# 开发服务器
cd apps/backend && uvicorn app.main:app --host 127.0.0.1 --port 8000 --reload
cd apps/admin-web && pnpm dev # port 5173
cd apps/tenant-admin && pnpm dev
# ETL
cd apps/etl/connectors/feiqiu
python -m cli.main --dry-run --tasks DWD_LOAD_FROM_ODS
python -m cli.main --pg-dsn "$PG_DSN" --store-id "$STORE_ID" --api-token "$API_TOKEN"
# 测试
cd apps/etl/connectors/feiqiu && pytest tests/unit # ETL 单元测试
cd apps/etl/connectors/feiqiu && pytest tests/integration --with-db # ETL 集成测试
cd apps/backend && pytest tests/ # 后端测试
cd /c/NeoZQYY && pytest tests/ -v # Monorepo 属性测试hypothesis
cd apps/admin-web && pnpm test # 前端 Vitest
cd apps/admin-web && pnpm e2e # Playwright e2e
cd apps/admin-web && pnpm lint # TypeScript 检查
cd apps/miniprogram && npm test # 小程序 Jest
```
## 架构模式
### 数据库
- 六层 Schema`meta``ods`(原始)→ `dwd`(规范化)→ `core`(聚合)→ `dws`(业务汇总)→ `app`RLS 视图)
- 跨库访问:`zqyy_app` 通过 FDW 只读映射 `etl_feiqiu.app` schema
- 多门店隔离:`site_id` + RLS`app` schema 视图层通过 `app.current_site_id` 会话变量过滤
### RLS 视图双 Schema 规则(踩坑 2026-03-29
新建 DWS/DWD 表的 RLS 视图必须同时在原 schema`dws`)和 `app` schema 创建。后端通过 `app.v_*` 访问。只在 `dws` 创建会导致后端查询失败。迁移模板:先 `CREATE VIEW dws.v_xxx`,再 `CREATE VIEW app.v_xxx`WHERE 条件相同。回滚需逆序 DROP。
### ETL
> 完整规则见 `apps/etl/connectors/feiqiu/CLAUDE.md`
- 任务模式:继承 `BaseTask`Extract → Transform → Load`orchestration/task_registry.py` 注册
- 加载器模式:每张目标表一个 Loader`upsert()` + 冲突处理
- SCD2 处理:`scd/` 模块
- Flow`--pipeline` 参数指定(如 `api_full`
### 后端
> 完整规则见 `apps/backend/CLAUDE.md`
- 全局响应包装:`ResponseWrapperMiddleware``{ "code": 0, "data": <payload> }`
- JWT 双认证admin用户名密码+ miniapp微信 code+ tenant-admin用户名密码
- AI 集成8 个千问应用DashScope SDK带熔断、限流、预算追踪
- 后台服务TaskQueue + Scheduler + 4 个触发器
## 文件归属规则
| 判断标准 | 放置位置 |
|----------|----------|
| 只有本模块开发者需要看的文档 | 模块内 `docs/` |
| 跨模块对照或全局视角的文档 | 根 `docs/` |
| 只验证本模块逻辑的测试 | 模块内 `tests/` |
| 守护 monorepo 结构/约定的测试 | 根 `tests/` |
| 只操作本模块数据的脚本 | 模块内 `scripts/` |
| 日常运维脚本(回填/导出/种子/初始化) | `scripts/ops/` |
| 可复用通用工具(健康检查/数据库/报表/分析) | `tools/`(按类型分子目录) |
| 审计记录(任何模块的变更) | 根 `docs/audit/` — 禁止写入子模块 |
| 数据库文档(全局 schema 视角) | 根 `docs/database/` |
| 归档/待删除内容 | `_DEL/`(保持原路径结构,用户定期手动清理) |
审计产物路径:
- 变更记录:`docs/audit/changes/<YYYY-MM-DD>__<slug>.md`
- 审计一览表:`docs/audit/audit_dashboard.md``scripts/audit/gen_audit_dashboard.py` 自动生成,勿手动编辑)
## 飞球数据规范
> 完整规则见 `apps/etl/connectors/feiqiu/CLAUDE.md`(进入 ETL 目录时自动加载)。
**核心速查**
- `consume_money` 禁止直接计算 → 用 `items_sum` 拆分字段
- 取数优先级DWS > DWD > 禁止 ODS
- 参考优先级DWD-DOC > DWS 权威规范 > BD 手册 > ETL 任务文档 > DDL 注释
- 所有 `_archived/` 目录禁止读取或参考
## 编码前需求审问(强制)
新建功能/模块/页面/接口、重构、多模块联动、需求存在模糊或隐含假设时:
1. 不立即动手,先提问循环(每轮 3-5 个问题)
2. 必问维度:用户角色、核心操作、完成后果、数据写入/展示/来源、错误/成功反馈、认证权限、存储(哪个库/新表?)、终端适配、边界条件(并发/幂等/超时)
3. 输出「需求确认摘要」,用户确认后才进入实施
例外:用户说"直接改/跳过审问/不用问了"、Bug 修复(有明确复现步骤)、纯格式/文档调整、已有完整 spec
## 逻辑改动前置调研(强制)
任何逻辑改动ETL/业务规则/API/数据模型/前端交互),写代码前必须完成调研:
1. 用 Explore 子代理调研:目标模块文件、`docs/audit/changes/` 历史审计、相关 README/PRD/BD 手册、要修改的文件及其调用方/被调用方、数据流向(上游→当前→下游)、影响范围
2. 输出「改动前上下文摘要」(模块职责、历史变更、影响范围、风险点),用户确认后开始实施
流程:需求审问 → 用户确认 → 前置调研 → 用户确认 → 编码实施
例外:纯格式调整、注释/文档纯文字修改、用户说"直接改/跳过调研"、新建文件且不涉及已有逻辑
## 改动后验证(强制)
逻辑改动完成后,必须执行以下验证步骤:
1. 运行相关测试(单元/集成/lint如无法运行需说明原因
2. 输出 diff 摘要(改了哪些文件、每个文件改动要点)
3. 列出未覆盖的风险点(未测试的路径、可能的副作用、需要人工验证的场景)
例外:纯格式/文档/注释调整、用户说"跳过验证"
## 数据库 Schema 变更规则
修改任何影响 PostgreSQL schema 的内容(迁移/DDL/表定义/ORM 模型)时,必须同步更新 `docs/database/`
- 变更说明:新增/修改/删除的表、字段、约束、索引
- 兼容性:对 ETL、后端 API、小程序字段映射的影响
- 回滚策略:如何撤销
- 验证步骤:至少 3 条校验 SQL
## 测试与验证环境规范
1. 必须 `load_dotenv` 加载根 `.env`;必需变量缺失时立即报错,禁止静默回退空字符串
2. cwd 与正式一致ETL → `apps/etl/connectors/feiqiu/`;后端 → `apps/backend/`
3. 配置走 `AppConfig.load()` 正常流程,不得为测试单独构造简化配置
4. 数据库使用测试库(`TEST_DB_DSN`),禁止连正式库
5. 属性测试分组执行:每次单个测试函数或 `-k` 筛选禁止一次性跑全部hypothesis 默认 `max_examples=100`
例外:用户指定简化环境、纯单元测试用 FakeDB/FakeAPI、`--dry-run` CLI 验证
## 脚本规范
- 复杂操作优先写 Python 脚本,避免复杂 shell 逻辑
- 一次性运维脚本 → `scripts/ops/`;模块专属 → 模块内 `scripts/`
- `scripts/ops/` 中的脚本不在 uv workspace 内,导入 ETL 纯函数需用 `importlib.util` + stub 方式(参考 `scripts/ops/backfill_finance_area_daily.py``tests/conftest.py`
## 子代理使用原则
- 委托子代理批量文件读取≥3 个)、大范围搜索、不熟悉的模块探索、多步骤 shell 操作
- 主流程直接处理:单个已知文件、简单单条命令、小范围精确搜索
## 审计
任何逻辑改动必须可追溯、可验证、可回滚。
完成一轮改动后,使用 `/audit` 命令执行审计。流程:
1. 运行 `python scripts/audit/prescan.py` 预扫描(自动识别变更文件、分类风险、合规检查,零 token
2. 补充语义上下文(从对话记忆中提取每个变更的原因和思路)
3. 委托子代理写审计记录到 `docs/audit/changes/`
4. 补齐缺失的文档同步
5. 运行 `python scripts/audit/gen_audit_dashboard.py` 刷新审计一览表
预扫描脚本支持 `--files` 参数:当 git status 包含大量历史未提交变更时,可只传入本次会话涉及的文件列表。
已废弃(不再使用):
- Prompt-ID 溯源、`docs/audit/prompt_logs/` — Claude Code 原生 session 日志已覆盖
- AI_CHANGELOG 文件内标记 — git blame 替代
- CHANGE 块级代码标记 — git blame 替代
- Session 日志 (`docs/audit/session_logs/`) — Claude Code 原生 session 存储已覆盖