chore(docs): 提交项目级 AGENTS.md 与既有验收记录 (cashflow-structure 部署前置)
This commit is contained in:
@@ -0,0 +1,49 @@
|
|||||||
|
# CMA 管理会计OS — 项目级 AGENTS.md
|
||||||
|
|
||||||
|
> 本文件是给 AI 编程代理(Claude Code)的项目级指令。修改代码前必读。
|
||||||
|
|
||||||
|
## 项目总览
|
||||||
|
- **产品**:管理会计OS(CMA),面向中小企业的管理会计 SaaS
|
||||||
|
- **访问**:cma.sxbh.ltd(生产)/ learn.sxbh.ltd(学习站)
|
||||||
|
- **仓库**:Gitea git.sxbh.ltd/sxbh_admin/(CI/CD: Woodpecker 自动构建部署)
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
- **后端**:FastAPI + SQLAlchemy + MySQL(生产) + Redis(token/缓存)
|
||||||
|
- systemd 服务 `cma-backend`,端口 8010,WorkingDirectory=/root/cma-management
|
||||||
|
- nginx root=/var/www/cma(前端静态)
|
||||||
|
- **前端**:Vue3 + TypeScript + Element Plus + Vite + pnpm
|
||||||
|
- **AI**:DeepSeek(deepseek-chat),LangChain 为备选集成方案
|
||||||
|
|
||||||
|
## 多租户铁律(最重要)
|
||||||
|
- **entity_id 是租户隔离核心**:所有业务表必须有 entity_id 字段,查询必须按当前租户过滤
|
||||||
|
- 登录前选公司,token 绑定 entity_id(Redis 存 JSON `{user_id, entity_id}`)
|
||||||
|
- `deps.get_entity_id` 解析链:token优先(query/header不一致→403) → Bot白名单 → entity_id=1
|
||||||
|
- **写代码时永远不要忽略 entity_id**——漏了就是跨租户数据泄漏(P0 安全bug)
|
||||||
|
|
||||||
|
## 编码规范
|
||||||
|
- Python:FastAPI 依赖注入用 `deps` 模块;Pydantic 校验输入
|
||||||
|
- SQLAlchemy 模型 NOT NULL 字段必须给默认值或明确插入(缺了 500: IntegrityError 1048)
|
||||||
|
- 例:Excel导入建KPI须补 entity_id=1, formula="-", data_source="Excel导入", data_owner="财务部", unit="元"
|
||||||
|
- 前端:表单负责部门/负责人字段**必须**下拉框动态加载(禁手输)
|
||||||
|
- 提交前:跑 pytest + 冒烟(health/bot/schema/login/kpis,登录须 entity_id=1)
|
||||||
|
|
||||||
|
## 修改边界
|
||||||
|
- 只改任务指明的文件;表结构迁移须先备份(backups/)
|
||||||
|
- 不破坏:`deploy.sh` 提交纪律、冒烟检查、`/api/cma/bot/*` 的 X-BOT-KEY 机制
|
||||||
|
- **安全敏感改动**(权限/支付/删除/核心表)完成后必须自审,标注风险
|
||||||
|
|
||||||
|
## 验证标准(怎么算完成)
|
||||||
|
1. 改完能跑:pytest 通过或冒烟脚本通过
|
||||||
|
2. 数据变化可回查(DESC 表/查库确认)
|
||||||
|
3. 生产部署走 deploy.sh(含备份+回滚预案)
|
||||||
|
4. 不允许"看起来对了"——必须有实际执行输出证明
|
||||||
|
|
||||||
|
## 常用命令
|
||||||
|
```bash
|
||||||
|
# 后端冒烟
|
||||||
|
cd /root/cma-management && bash deploy.sh smoke # 或 deploy.sh 完整部署
|
||||||
|
# 登录拿token(entity_id=1)
|
||||||
|
curl -s -X POST http://127.0.0.1:8010/api/login -H 'Content-Type: application/json' -d '{"username":"...","password":"..."}'
|
||||||
|
# 查服务
|
||||||
|
systemctl status cma-backend
|
||||||
|
```
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# 验收记录:年度分解400错误提示优化(budget-decompose-400-hint)
|
||||||
|
|
||||||
|
- **任务**: budget-decompose-400-hint-20260831.md
|
||||||
|
- **执行人**: wecom-fullstack(全栈Bot)
|
||||||
|
- **完成时间**: 2026-08-31 20:0x CST(本会话补齐验收)
|
||||||
|
- **Commit**: 9cccaa6cfc6ad309c11c4f7f68009b2a43c92800(fix(budget): 年度分解400提示优化——含可用年份+双路径引导)
|
||||||
|
- **状态**: ✅ 通过(代码修改由 18:28 会话提交推送,本会话完成独立验收)
|
||||||
|
|
||||||
|
## 输出物证据
|
||||||
|
|
||||||
|
### 输出物1:budget.py 400提示优化(可用年份+双路径)
|
||||||
|
grep 命中:
|
||||||
|
- 行225: `avail_years = [r[0] for r in db.query(distinct(BudgetPlan.budget_year)).filter(...)`(entity_id + period LIKE %-00 + status active)
|
||||||
|
- 行231-232: `if avail_years:` → `hint += f";现有年度数据年份:{', '.join(...)}"`
|
||||||
|
- 行233: `hint += "。请先在预算录入中填写该年度预算总额,或改用战略预算编制按地图录入;如需按已有月度数据反向生成请咨询管理员。"`
|
||||||
|
|
||||||
|
### 输出物2:单KPI缺参400提示
|
||||||
|
- 行307: `raise HTTPException(400, "缺少必要参数: annual_budget(单KPI分解需传年度预算值)")`
|
||||||
|
|
||||||
|
### 输出物3:后端重启
|
||||||
|
- systemd cma-backend ActiveState=active,ActiveEnterTimestamp=2026-08-31 18:28:25(commit 9cccaa6 提交 18:28:11 后由 CI deploy hook 自动重启)
|
||||||
|
- `GET http://127.0.0.1:8010/health` → `{"status":"ok","version":"1.0.0"}` (200)
|
||||||
|
|
||||||
|
### 输出物4:实测提示(API 真实调用)
|
||||||
|
- entity_id=1 + year=2025 → 400:
|
||||||
|
`该年度(2025)没有年度预算总额(period=YYYY-00);现有年度数据年份:2026。请先在预算录入中填写该年度预算总额,或改用战略预算编制按地图录入;如需按已有月度数据反向生成请咨询管理员。`
|
||||||
|
✅ 含可用年份(2026) + 双路径引导
|
||||||
|
- entity_id=2(陕西博海)+ year=2026 → 400:
|
||||||
|
`该年度(2026)没有年度预算总额(period=YYYY-00)。请先在预算录入中填写该年度预算总额,或改用战略预算编制按地图录入;如需按已有月度数据反向生成请咨询管理员。`
|
||||||
|
✅ 含双路径引导(博海无年度行,avail_years 为空 → 无年份列表,符合预期)
|
||||||
|
- entity_id=1 + year=2026 → 200:`批量分解完成:4个KPI`(成功路径未受影响)
|
||||||
|
- 单KPI缺参(kpi_id=5 不传 annual_budget)→ 400:`缺少必要参数: annual_budget(单KPI分解需传年度预算值)` ✅
|
||||||
|
|
||||||
|
### 输出物5:pytest 全量回归
|
||||||
|
- `venv/bin/python3 -m pytest tests/ -q` → **711 passed, 1 xfailed**(基线 711 passed / 1 xfailed,全绿)
|
||||||
|
|
||||||
|
### 输出物6(可选):前端错误提示样式
|
||||||
|
- 本期未做(任务建议本期只做后端提示,前端 doDecompose catch 已显示 e.detail 自动受益)
|
||||||
|
|
||||||
|
## 风险点核对
|
||||||
|
- 成功路径(200)未改动:entity_id=1 year=2026 实测 200 正常 ✓
|
||||||
|
- git commit 只含本次文件:9cccaa6 仅改 backend/app/api/budget.py(13 insertions, 2 deletions)✓
|
||||||
|
- HEAD == origin/main,无未推送提交 ✓
|
||||||
Reference in New Issue
Block a user