Commit Graph
27 Commits
Author SHA1 Message Date
Hermes CI Fix cfd6a13ca4 fix(budget): 年度行(budget_month=0)不回落 1 月 + 同族 R1/R2/R3
ci/woodpecker/push/main Pipeline failed
- R-A2 sync-cash-plans: 年度行形态判定(_is_annual_budget_row)跳过 + skipped_annual 披露
- R2 POST /plans 期间形态校验(YYYY-MM / YYYY-00 显式接受)
- R3 budget_roll_forward 排除年度行
- R1 cash_classify 归类路径年度行判据 + 披露
- 新增 2 个回归件(14+10 例)

仅含本族 hunk(禁整文件提交): 开发区其余 14 hunk 属他会话在途件,未纳入。
2026-10-13 03:41:39 +08:00
Hermes CI Fix 1da0a74568 fix(h2-forecast): 预估区残余读路径 P2 收口(3 类 6 处)
任总 2026-10-02 11:35 直令「对外 /api/cma/** 读 KPIValue 默认只取实测区」同族残余
(ac4bbc6 范围外的 3 类 6 处)。6 处一律引 app.utils.kpi_value_scope.actual_only_clause(),
零新写字面量口径:
- customer_dashboard.py:76    年视图汇总(预估禁与实测相加)
- budget.py:260               按去年实绩加权派生基数(批量 auto-decompose)
- budget.py:333               同上(单 KPI auto-decompose)
- cash_forecast_engine.py:204 get_entity_kpi_history 历史/趋势序列
- cash_forecast_engine.py:259 get_current_cash_balance 最新值
- cash_forecast_engine.py:471 calculate_accuracy 实际值序列(预测输入)

证据:同脚本双树 A/B 15/15(改前 5/15,真库 kpi-forecast history 去掉 2026-H2、
next_target 336.32→250.99);分类计数 33/41/9/3 → 39 covered/38 period_guarded/9 write/0 unguarded;
pytest 3 failed/1529 passed,失败集与基线逐条同 ID。不 push / 不部署 / 不重启 / 不写库。
Task: project-20261002-h2-forecast-residual-reads-p2-fullstack
2026-10-02 23:41:17 +08:00
Hermes CI Fix ac4bbc6891 fix(h2-forecast): 对外 KPIValue 残余读路径统一实测区口径(7 处)
任总 2026-10-02 11:35 直令「对外 /api/cma/** 读 KPIValue 默认只取实测区;
预估禁进趋势序列 / 禁作预警与预算依据」的同族残余读路径收口。

7 处逐处改(均引 app/utils/kpi_value_scope.actual_only_clause,不新写字面量口径):
- kpis.py:604            GET /kpis/{id} 详情历史值(预估禁进趋势序列)
- ai_analysis.py:363     GET /ai/kpi-analysis/{id} 趋势序列/LLM 上下文
- thresholds.py:132      GET /thresholds/suggest/{id} 阈值推荐依据
- budget_generate.py:94  GET /budget/kpi-budget-candidates 预算候选最新值
- budget.py:1380         POST /budget/apply-method 派生基数(预算依据)
- maps.py:657            GET /maps/{id}/review 地图节点最新值
- data_quality.py:363    GET /data-quality/stats 缺失判定(仅预估行不算有实际值)

证据:同脚本双树 A/B 11/11(改前 3/11 FAIL)+ pytest 3 failed/1529 passed 与基线逐条同 ID。
不 push / 不部署 / 不重启 / 不写库。
2026-10-02 21:01:25 +08:00
wecom-fullstack 467472311d feat(cma): audit write-side entity closure + entity-dimension data dictionary
task dama-entity-isolation-sweep-20260923 (sections 2-2 4/5, merged by projectBot 2026-09-23 18:2x)

4) operation_logs write side: every audit write carries the account (no DDL, no column added)

   - new app/utils/oplog.py::log_op() single wrapper: sets detail.entity_id; scope=global for

     by-design non-entity writes (platform dict / role-level); scope=batch + OPLOG_BATCH_NO_ENTITY

     sentinel for cross-account batches; no context -> OPLOG_NO_ENTITY sentinel (never guess)

   - 16 remaining construction points converted (data/alert_rules/bi_reports/kpi_causality/

     bot_bridge x2/budget_generate/driver_budget/kpis _log x3/templates _log x2/erp_sync);

     pre-4 state had 20 sites without entity_id, now 0 outside the wrapper

   - read side untouched (knowledge_service still user_id fallback); history not backfilled

5) docs/entity-dimension-data-dictionary.md: 8-table three-state registry

   (kpi_templates/driver_factor_templates/scenario_suggestions/bot_bridge_config = non-entity;

    kpi_subject_map = inherited via kpi_id; analysis_results/subjects = account dimension,

    legacy rows still NULL -> other task; operation_logs = non-entity column + detail.entity_id)

Evidence: RED 2 failed/7 passed (reverted call sites) -> GREEN full 1428 passed; 9 new tests

including two read-back rows; app md5 restore verified identical; no cross-account writes

LOCAL commit only - push is gated (ahead contains the P1 entity-dim batch commit fb4609b)
2026-09-23 23:08:26 +08:00
wecom-fullstack 477515c453 fix(cma): 隔离扫尾 — kpi_alert_higher_better 拆账套 + tenant/switch 审计收口
ci/woodpecker/push/main Pipeline was canceled
任务 dama-entity-isolation-sweep-20260923(DAMA 独立回查漏项 / 任总 2026-09-23「按照建议执行」)

① 补漏同源全局键 kpi_alert_higher_better(system_configs,零 DDL)
   - deviation_engine: 新增 higher_better_key(entity_id);get_higher_better_codes(db, entity_id)
     改为只读本账套键、不回退旧全局键;未配置 → DEFAULT_HIGHER_BETTER(兜底,与原行为逐字一致)
   - budget.py: GET/PUT /alert-direction 挂 get_entity_id,只读写会话账套键;body entity_id 不信
   - scripts/migrate_higher_better_key_entity_20260923.py: --check/--apply/--down + 库名保护 + 幂等
   - 生产实况:库内该键 0 行 ⇒ 无原值可搬运(--apply 走 skip 零写入),e1 行为不变

② kpi_visibility 口径裁定:角色级天然全局 = 非账套维度,不拆(关闭本项)
   - auth_middleware 注释 + docstring 登记「有意不做账套后缀」;口径字典
     docs/global-config-keys-caliber-20260923.md(含 budget_mode/budget_driver_mode 评估结论)

③ tenant/switch 审计收口
   - detail 显式 from_entity_id → to_entity_id + source + operator{id,username,name,role}
   - 审计失败不静默:同事务回滚 + AUDIT_WRITE_FAILED ERROR + HTTP 500(不留「改了但没审计」)
   - GET /current 无写路径不落审计;历史缺口不补写

证据:新增/改写用例 17 条;全量 1397 passed(去新增文件 1380 + 17);RED 态 8 failed
2026-09-23 18:29:52 +08:00
Hermes CI Fix 42ff836309 fix(cma): entity isolation batch5 (budget writes, kpi objectives scope, quality logs join, growth-quality db source, expenses scope)
ci/woodpecker/push/main Pipeline failed
2026-09-21 10:36:02 +08:00
Hermes CI Fix a0762b367f fix(cma): entity isolation batch4 (cash plan writes, budget ownership, read leaks, okr template)
P0-A cash.py: scope api_update_plan / api_delete_plan / api_complete_plan /
api_register_payment to session entity (cross-entity id -> 404, aligning with
the file's existing get_entity_id endpoints).
P0-B budget.py: write entity_id on BudgetPlan creation + require the KPI to
belong to the session entity; scope /comparison, /comparison/kpi/{id} and
/deviation-report reads to the session entity.
P1 notifications.py: explicit field whitelist (name/config/enabled) on
update_channel to close mass-assignment.
P1 read leaks scoped to session entity: bot_kpis list, data_quality check/stats
(KPI calibre only; quality-log table has no entity_id column), kpis causality
chain + associate-map (KPI and map ownership), dashboard my-kpis,
customer_dashboard list, kpi_governance audit, budget_generate candidates,
driver_budget history (+ entity_id on its write path), expenses stats
(+ entity_id on its write path).
P2 okr_templates.py: write entity_id on the StrategicMap created by apply.

tests: tests/test_cross_entity_isolation_batch4_20260921.py (30 cases;
RED before fix = 22 failed, GREEN after = 30 passed; full suite 1302 passed /
1 xfailed / 0 failed).
2026-09-21 09:37:38 +08:00
Hermes CI Fix ad953ac759 fix(cma): entity isolation batch2 (roll-forward/check-timeout/by-id/cost-abc)
ci/woodpecker/push/main Pipeline failed
Scope: backend/app/api/{alerts,action_plans,budget,cost}.py + tests

Task: 0-P1-project-20260918-entity-isolation-batch2
2026-09-18 18:15:22 +08:00
Hermes CI Fix ec58efa20b fix(budget): 偏差检查同 KPI 多计划去重(deviation-check 补 db.flush)
autoflush=False 下,check_budget_deviation 循环内 existing_alert 去重查询
查不到本次刚 add 未 flush 的行 → 同期间同 KPI 多 active 预算计划会重复告警。
add 后补 db.flush() 使其对下一次循环可见。附回归测试。

Ref: yanxue-20260914-budget-p13p14-activation 遗留②试跑发现的缺陷
2026-09-14 17:56:26 +08:00
Hermes CI Fix b01a108874 fix(budget): 版本管理UI字段/状态机对齐 active→draft映射+plan_count/last_updated别名
- list_budget_versions 输出 approval_status(active映射draft)+plan_count+last_updated
- 保留 status/kpi_count/updated_at 原字段兼容(下拉'当前'标记/测试契约)
- 前端提交审批按钮兜底 active(双端保险)
- 修复: 版本行仅复选框无按钮/状态恒草稿/条目数空白/最后更新空白
2026-09-07 11:01:56 +08:00
Hermes CI Fix 9cccaa6cfc fix(budget): 年度分解400提示优化——含可用年份+双路径引导 (budget-decompose-400-hint) 2026-08-31 18:28:11 +08:00
Hermes CI Fix 74dc9baff5 fix(security): 多租户隔离全量修复 security-fix multi-tenant (OpenCode审查P0)
- bot_bridge 18数据端点全部 entity_id 隔离(Depends(get_entity_id)/body),/ping /risk-levels 豁免
- alert_rules 11端点 entity_id 隔离 + KPIAlert/DynamicThresholdCache 写入 entity_id
- reports 17端点隔离 + generate_report 写 ReportHistory.entity_id + history 按 entity 过滤
- ai_analysis 移除硬编码默认key,改 _require_deepseek_key() 强制 env 缺失 503
- budget auto-decompose 硬编码 entity_id==1 改请求 entity
- kpis update_kpi 加 UPDATE_KPI_WHITELIST 白名单(status/important_flag 不可越权改)
- data_quality 收敛:删 MySQL JSON 版 _run_rule_checks,check-governance 复用 _run_governance_checks(SQLite 兼容)
- _eval_threshold invert 参数修复(>=↔< 等取反),red 分支不传 invert 保持行为
- 新增 test_security_multitenant.py 13条(bot_bridge/alert_rules/reports 隔离 + invert + SQLite governance)
- models 6表加 entity_id 列;生产库已 ALTER + 按真实归属回填(kpi_alerts 472行中216行属entity≠1)
2026-08-31 10:14:22 +08:00
Hermes CI Fix 5b920df8a0 fix: 预算年度分解幂等加固+数据质量七规则测试
- auto-decompose批量聚合只取年度行(period=YYYY-00)排除月度行,修复重复点击执行分解年底预算滚雪球
- 同一KPI多个version年度行时只取一行(优先请求version),避免多版本叠加总额虚高
- 新增tests/test_data_quality.py: 财务七规则(governance-check)3用例全过
2026-08-30 10:27:01 +08:00
Hermes CI Fix 94aeb14e95 feat: 预算系统6项技术改进(告警归因/实际值自动归集/真零基/派生规则/告警路径统一/现金流分类)
P1-③ 告警归因: budget_deviation_alerts+alert_type/attribution/scenario_id, 归因引擎alert_attribution.py(子KPI/科目/量价差/趋势), deviation-check统一写归因+场景, GET /deviation-alerts/{id}/attribution详情(旧告警现场组装)
P1-④ 实际值自动归集: kpi_value_sources/kpi_value_collect_logs表+CRUD+试跑+覆盖率, 采集器kpi_value_collector.py(voucher_details/进销存/cash_plans按entity+period汇总, 幂等upsert不覆盖人工), crontab每日06:30
P2-① 真零基: budget_zero_based_items逐项论证表+generate, method-comparison有论证项逐项求和is_demo=false否则fallback
P2-② 派生规则: budget_derivation_rules配置表, apply-method优先读规则rule_source=configured
P2-⑤ 告警双路径合并: deviation_engine.build_deviation_alert统一函数, 方向列表配置化kpi_alert_higher_better+alert-direction接口
P2-⑥ 现金流分类: cash_plan_classify_rules规则表+cash_plan_unclassified待分类队列, sync-cash-plans未命中进队列不静默跳过
新增: GET /kpis/{kpi_id}/values + 前端kpiApi.values(归集标签页数据源), scenario_suggestions幂等seed(init_db)
测试: test_budget_tech_improve.py 15用例, 预算相关96 passed, 全量646 passed
2026-08-28 18:03:47 +08:00
Hermes CI Fix fd814462a2 feat: 预算按战略地图隔离(map_id) — 切换地图数据区分
问题: 预算数据无map_id, 两地图共用KPI时预算无法区分(切地图数据均显示)
修复:
- budget_plans 加 map_id 字段+索引
- list 支持 map_id 过滤(含NULL历史预算兼容迁移)
- create 收 map_id + 去重键含map_id(同KPI不同地图可各自预算)
- 前端: loadBudget/loadStrategyBudget 传 map_id, 保存带 map_id
- 端到端验证: 地图51 F_REVENUE 300(map_id=51) 地图51显示/地图32不显示 ✓
pytest 35+11 passed, 部署
2026-08-27 17:33:57 +08:00
Hermes CI Fix 3c64dc767e feat: 战略目标vs预算差异可见化 — 目标与预算允许不同但差异可解释
需求: 战略目标(管理团队愿景) vs 预算(财务按实际分析) 允许不同
增强:
- 后端 deviation-report 返回 strategic_target/target_gap_pct/target_gap_level
- 预算执行表加'战略目标'+'目标差异'列(±10%黄/±20%红⚠️提示'需说明原因')
- 战略预算编制KPI树加'战略目标'列(编制时可见对比)
- 实测: F_REVENUE 战略1200 vs 预算173.86 差异-85.5%(high) 红提示

口径说明: 差异基于当前target_monthly/预算值, 目标口径校准另行处理
2026-08-27 17:26:38 +08:00
Hermes CI Fix e82a6af59c fix: 预算流程断点修复 — 现金流联动+行动方案补齐
断点#1: 预算↔现金流打通
- cash_plans 加 related_kpi_id/budget_plan_id 字段
- POST /budget/sync-cash-plans: 按预算KPI生成收付款计划(收入类→receive/成本类→pay, upsert)
- 前端预算执行页加'⇄同步现金流计划'按钮
- 实测: 新建108条(receive 75/pay 33, 6个KPI)

断点#2: 5个预算KPI补行动方案(净利/新客/厂补/供应链/数据自动化, 各1条含负责人)

断点#3: 悬空预算(2KPI)因已补行动方案, 性质从'无来源'→'有行动缺实际数据源', 标注保留

pytest 56 passed(budget+cash), 构建部署
2026-08-27 16:54:07 +08:00
Hermes CI Fix 95b73c9b90 feat(P1-2): 预算三法并存落地 — 增量/零基/弹性均可应用
按任总观点: 三个方法都体现功能, 具体用哪个取决于用户场景
- 后端: POST /budget/apply-method 把所选方法结果写入预算计划(version标注方法)
  增量95.5万(上月×1.05) / 零基71.4万(成本砍半压缩) / 弹性58.7万(收入联动)
- 前端: 确认选择改为真正调用apply-method(原来只弹提示不落地)
- 场景提示: 增量=稳定快速编 / 零基=成本优化 / 弹性=收入波动大
2026-08-26 22:43:46 +08:00
Hermes CI Fix dbfa6ba0a2 fix: 预算录入搜索不过滤 — plans API补keyword参数(KPI名称模糊搜索) 2026-08-25 17:53:47 +08:00
Hermes CI Fix 4d2fba67f7 fix: 预算录入维度无标签 — plans API补dimension/unit字段 2026-08-25 17:47:15 +08:00
Hermes CI Fix a1d014258f fix: 执行分解400错误 — auto-decompose支持批量模式(不传kpi_id分解该年所有预算KPI)
- 原API只支持单KPI(kpi_id+annual_budget),前端UI按整体分解调用 → 400
- 新增批量模式:聚合该年所有KPI年度预算,逐KPI均分/按历史权重分解12个月
- 验证:批量分解4个KPI(收入536万/净利-48万等),v1.0月度48条落库
2026-08-25 17:42:40 +08:00
Hermes CI Fix b6613bbde2 fix: 预算执行KPI名称/维度为空 — deviation-report补kpi_name/dimension/unit字段 2026-08-25 17:28:14 +08:00
Hermes CI Fix 835ac10e95 feat: 预算版本管理API — 修复前端'加载版本失败'(budgetApi.versions未定义+后端无端点)
- 后端: GET /budget/versions(版本列表) POST /versions/submit /versions/approve /versions/diff
- 前端: budgetApi.versions/versionSubmit/versionApprove/versionDiff
- 数据: budget_plans已有v2.0 active 24条
- 验证: 版本列表200(v2.0 24KPI 预算730万) 版本对比200
2026-08-25 17:11:03 +08:00
Hermes CI Fix fb9eba38a8 feat: 多租户隔离P2批2 — 预算/成本/费用/预警规则/BI报表加entity_id
- 12表加entity_id列(预算/偏差/规则/成本4表/费用2表/BI2表/驱动预算)
- 模型: BudgetPlan/StandardCost/ActualCost/AbcActivity/AbcAllocation/DriverFactorBudget/BiReport/Template/BudgetDeviationAlert/ExpenseRule/Reimbursement/AlertRule
- API隔离: budget plans / cost standard+actual / expenses rules+reimb / bi_reports list / alert_rules list 按token企业过滤
- 回填: kpi_id关联按KPI归属, 无关联默认酣客(entity=1); 当前数据全归酣客
- 验证: import+全端点200+pytest 451 passed
2026-08-23 18:20:29 +08:00
Hermes CI Fix 66554fb7fa feat: 持续规划 — 滚动预算+自动延展+对比线+偏差告警 2026-07-22 12:31:25 +08:00
Hermes CI Fix 9eded3e4fe feat: CMA P1+P2 Round2 — 风险矩阵+COSO+预算方法 2026-07-16 17:09:32 +08:00
Hermes CI Fix 3dddd36866 init: 管理会计OS初始代码
包含前后端完整代码:
- 前端:Vue3+Vite+ElementPlus
- 后端:FastAPI+SQLAlchemy
- 模块:驾驶舱/KPI/战略地图/预警/预算/成本/预测/改善行动
- 当前版本:v1.0.0
2026-05-28 17:32:22 +08:00