Files
Neo-ZQYY/CLAUDE.md
Neo 95a4500c75 chore(ops): reload 卡死三层预防 + F1-5a 完整走查报告
reload 卡死三层预防(走查中遭遇 uvicorn graceful shutdown 死等触发):
- Layer 1 (apps/backend/start_uvicorn.py 新): 把 reload-excludes
  封装在 Python 字符串内,ps1 命令行只有字面路径,根治 PowerShell
  PSNativeCommandArgumentPassing 在不同 profile 下 wildcard 展开
  行为差异(数组 splatting 和 --% 都不稳)。同时显式设
  timeout-graceful-shutdown=5,5 秒强杀防死等
- Layer 2 (scripts/ops/backend-watchdog.ps1 新): 自主 socket 探针
  (TcpClient + 手写 HTTP/1.1 GET,Connection: close)规避 .NET
  HttpClient pool 复用 + 系统代理误报;3s × 3 = 9s 触发重启;
  进程链 kill 至 pwsh 后端窗口(关闭原窗口);3 次/小时上限自停
- Layer 3 (scripts/ops/start-admin.ps1): 启动时拉起 watchdog,
  菜单 [4] 仅重启后端选项,主菜单退出时一并 kill 看门狗

CLAUDE.md: 新增"后端 reload 卡死预防(强制)"章节,
分级文件风险表 + SOP + 启动菜单速查

走查报告(应查尽查严肃版):
- 后端 6 个改造点 PASS(P1-P4 + GUC + ai_run_logs runtime 字段)
- admin-web 7 页 Playwright 实地走查 → 5 项 UI 不完整登记 F1-5b
- 小程序看板 tab 7 页 weixin-devtools-mcp 实地 + DB 数据核对 →
  board-finance 5/6 项上界裁剪吻合;board-customer 业务日生效;
  board-coach 月度聚合表设计盲区;5 项 sandbox 覆盖盲区登记 F1-5b
- 8 张走查截图归档 docs/audit/changes/screenshots/2026-05-05_f1_5a_walkthrough/

audit_dashboard 刷新到 153 条审计

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 11:53:08 +08:00

239 lines
14 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 命令 → 保持原文
禁止在回复中使用英文段落或英文标题(技术术语、代码片段、专有名词内嵌除外)。
## CLI / Shell 中文与编码(强制)
- Python`encoding="utf-8"`;必要时设 `PYTHONUTF8=1`
- CSV 给 Excel 打开时用 `utf-8-sig`(带 BOM
- PowerShell / Node / Shell不依赖系统默认 ANSI 编码;输出中文时优先 UTF-8。
- 终端中文乱码时**不要把乱码当作事实**:先调编码重跑,或明确说明"终端编码异常,结果需复核",转述可确认的信息。
- Shell 路径含中文/空格/特殊字符必须正确加引号。
- 复杂中文输出走脚本或结构化 APIJSON避免手写脆弱 shell 转义。
- PowerShell 不支持 Bash 风格 heredoc复杂中文片段用 here-string 管道传给 Python。
- Python 文档模板里的 Windows 路径(`C:\Users\...`)注意反斜杠转义,避免 Unicode 转义错误。
## 项目概览
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/` | 系统管理后台(开发/运维视角,操作 ETL 库ETL 配置 / 数据质量 / 系统监控) |
| `apps/tenant-admin/` | 租户管理后台(门店管理员 `site_admin`/`tenant_admin`;用户审核 / Excel 上传 / 维客线索,门店隔离视角) |
| `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 监控、数据回填、导出等) |
## 技术栈
- 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 参数
## 架构模式(顶层)
- **数据库六层 Schema**`meta``ods``dwd``core``dws``app`RLS 视图);`zqyy_app` 通过 FDW 只读映射 `etl_feiqiu.app`;多门店通过 `site_id` + `app.current_site_id` 会话变量过滤
- **RLS 双 Schema 强制规则(踩坑 2026-03-29**:新建 DWS/DWD 表的 RLS 视图必须**同时**在原 schema`dws`)和 `app` schema 创建。后端走 `app.v_*`。只在 `dws` 创建会让后端查询失败;回滚需逆序 DROP
- 详细子模块架构响应包装、JWT、AI 集成、ETL Loader/SCD2/Flow、DDL见对应 `CLAUDE.md`(自动加载):
- `apps/backend/CLAUDE.md` — FastAPI 后端
- `apps/etl/connectors/feiqiu/CLAUDE.md` — 飞球 ETL含 12 条 DWD 强制规则)
- `db/CLAUDE.md` — DDL / 迁移 / RLS 双 schema 模板
## 文件归属规则
| 判断标准 | 放置位置 |
|----------|----------|
| 只有本模块开发者需要看的文档 | 模块内 `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. 列出未覆盖的风险点(未测试的路径、可能的副作用、需要人工验证的场景)
例外:纯格式/文档/注释调整、用户说"跳过验证"
## 后端 reload 卡死预防(强制)
**机制**`uvicorn --reload` 检测到 .py 修改 → 等 lifespan shutdown → 等 WebSocket / asyncio task / DB 连接释放 → 等不到就死等。已在 `start-admin.ps1` + `backend-watchdog.ps1` 做了三层保护,但写代码时仍需配合。
**改 Python 文件按风险分级**
| 风险 | 文件位置示例 | 操作 |
|---|---|---|
| 极低 | `app/ai/prompts/*.py` `app/schemas/*.py` 工具/helper | 直接改reload 自动应用 |
| 中 | `app/services/*` `app/ai/*`(非 dispatcher) `app/routers/*` | 改前关浏览器(切 WS),改后看终端 "Application startup complete" |
| 高 | `app/main.py`(lifespan) `app/services/scheduler.py` `task_queue.py` `app/ai/dispatcher.py` 全局单例(`_admin_svc` 等) | 用启动菜单 [4] 仅重启后端,或 taskkill + 双击 bat |
**测试 SOP**
1. 改 Python 前先 `curl http://127.0.0.1:8000/health` 确认健康
2. 改完文件等 30 秒,再 `curl /health` 二次确认;若仍 timeout → 选启动菜单 [4]
3. 看门狗(`backend-watchdog.ps1`)会在连续 30 秒不响应时自动 kill+重启,不需要手动操作
**启动菜单(双击 `start-admin.bat`**
- [1] 终止所有服务(含看门狗)
- [2] 重启所有服务(含看门狗)
- [3] 退出
- [4] 仅重启后端(保留前端,推荐:测试时 reload 卡死 / Python 改动)
**禁止**
- 改 lifespan / dispatcher / 全局单例时不要靠 reload**手动停后端再启动**
- 不要在 reload 没完成时连续改 .py 文件(前一次没收完后一次又触发,必卡)
## 数据库 Schema 变更规则
修改 PostgreSQL schema迁移/DDL/表/ORM时**必须**同步 `docs/database/`:变更说明 + 兼容性影响ETL/后端/小程序)+ 回滚策略 + ≥3 条校验 SQL。详细模板见 `db/CLAUDE.md`
## 测试与验证环境规范
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 包含大量历史未提交变更时,可只传入本次会话涉及的文件列表。
## Claude Code 资产入口
| 资产 | 位置 |
|------|------|
| 项目 slash 命令 | `.claude/commands/*.md`5 个:`/audit` `/db-docs` `/doc-sync` `/pre-change` `/spec-close` |
| 项目 hooks | `.claude/hooks/*.py` + `.claude/settings.json` |
| 项目设置 | `.claude/settings.json` / `.claude/settings.local.json`PATH/虚拟环境) |
| 项目 MCP | `.mcp.json`**单一权威源** |
| 用户级 subagents8 个) | `~/.claude/agents/`planner / architect / code-reviewer / security-reviewer / database-reviewer / python-reviewer / tdd-guide / refactor-cleaner |
| 用户级 skills | `~/.claude/skills/<name>/SKILL.md` |
| 用户级 rules自动加载 | `~/.claude/rules/{python,typescript,web,zh}/` |
| 自动记忆 | `~/.claude/projects/c--Project-NeoZQYY/memory/` |
### 子模块 CLAUDE.md按需自动加载避免在根级重复
| 子模块 | CLAUDE.md 内容 |
|------|------|
| `apps/backend/` | FastAPI 全局响应包装、CamelModel、JWT 三类 aud、AI 集成、TaskQueue/Scheduler、FDW 访问 |
| `apps/etl/connectors/feiqiu/` | DWD-DOC 标杆、12 条 DWD 强制规则、DWS 权威规范(幂等/课程定价/绩效/会员分层/调度窗口/指数参数/台桌分类) |
| `apps/demo-miniprogram/` | MOCK 标杆禁改、UI 校对基准、与 `apps/miniprogram/` 关系 |
| `db/` | Schema 变更模板、RLS 双 schema 模板、目录结构、DDL 刷新、测试规范 |
## Hook 与权限
项目已注册的 hooks`.claude/settings.json`
| 时机 | Hook | 行为 |
|------|------|------|
| SessionStart | `session_start_context.py` | 注入项目状态摘要 |
| PreToolUse (Read/Edit/Write/Glob) | `pre_read_archived_block.py` | 强阻断 `_archived/` 目录读取 |
| PreToolUse (Bash/Edit/Write) | `pre_demo_protect.py` | 提醒 `demo-miniprogram` 保护 |
| PostToolUse (Edit/Write) | `post_edit_audit_reminder.py` | 提醒审计 |
| PostToolUse (Edit/Write) | `post_edit_db_doc_sync.py` | 提醒 DB 文档同步 |
| PostToolUse (Edit/Write) | `post_edit_rls_dual_schema.py` | RLS 双 schema 检查 |
| Stop | `stop_audit_check.py` / `stop_verify_check.py` | 收尾审计/验证检查 |
## 不破坏原则
- 不回滚用户已有改动,不使用破坏性 git 命令(`reset --hard` / `push --force` / `checkout .`),除非用户明确要求
- 不修改 `apps/demo-miniprogram/`MOCK 标杆,禁改)
- 不写入 `_archived/` 目录
- 不在测试库以外执行 DDL / TRUNCATE / DELETE
## 历史追溯
- 日常追溯先查精简索引:`docs/ai-env-history/README.md``docs/audit/changes/``docs/audit/audit_dashboard.md`
- 历史摘要只解释来龙去脉,编码前以**当前文件、当前 diff、当前测试**为准
- 原始 JSONL 可追查细节,但**不要把密钥、DSN、token 原文写入仓库文档**
- 迁移路径:旧服务器 → 本机 → Claude Code → Codex → Cursor → **Claude Code当前**;详见 `docs/claude_code_migration.md`