Files
X-Financial/document/development/2026-07-16/feature/savings-ledger-and-cfo-value/TODO.md
caoxiaozhu 787bc3a481 feat(platform): close AI expense value loop
Add tenant-safe value, telemetry, connector, commercial, and production-readiness foundations.
2026-07-17 14:14:08 +08:00

17 KiB
Raw Blame History

节省事实账本与 CFO 经营价值看板 开发 TODO

更新时间2026-07-17

使用规则

  • 每条 TODO 必须回链 CONCEPT.md 的章节或语义段落。
  • 只有代码、接口或容器验证提供真实证据后才能勾选 [x]
  • 现金节省、工时价值、风险暴露和预计机会始终分开,不以演示数据代替缺失事实。
  • 实施顺序为:安全前置 → 账本 → 首条闭环 → 基线/分析 → CFO 前端 → PostgreSQL/E2E → 文档收口。

1. 调研与边界

  • [CONCEPT: 背景与问题] 盘点财务看板、预算、Claim、Expense Case、Business Event、风险、审批、付款和标准重算事实源。 证据:finance_dashboard.pyfinance_dashboard_snapshot.pyfinancial_record.pyexpense_cases.pyexpense_claim_standard_adjustment.pyexpense_claim_approval_flow.py 的只读审计。
  • [CONCEPT: 目标与非目标] 确认风险金额、未用预算、预计机会和未确认结果不得进入已确认节省。 证据CONCEPT「目标与非目标」「算法与公式」。
  • [CONCEPT: 用户与场景] 选择住宿职级标准重算作为首条纵向闭环,不选择证据不足的重复支付或供应商议价。 证据:现有标准重算和付款业务事件可形成最短可信证据链;AccountsPayableRecord 已有租户字段,但仍缺合同价、数量、单位价格和外部付款事实。
  • [CONCEPT: 风险与开放问题] 识别旧财务聚合全表读取、快照键缺租户、接口缺角色限制和标准重算信任客户端原金额问题。 证据:FinanceDashboardMetricMixin._fetch_claims()_fetch_budget_allocations()FinanceDashboardSnapshotService._cache_key()accept_standard_adjustment()

2. 契约与设计

  • [CONCEPT: 数据与契约] 定义 baseline、opportunity、realization、evidence 和 append-only event 的职责与关键字段。 证据CONCEPT「数据与契约」。
  • [CONCEPT: 算法与规则] 定义 identified → accepted → in_progress → realized → verified → reversed 状态和 rejected/expired 终态。 证据CONCEPT「状态转换」。
  • [CONCEPT: 算法与规则] 定义 benefit key、canonical realization、归因比例和追加冲回规则。 证据CONCEPT「收益去重」。
  • [CONCEPT: 权限] 定义租户、finance/executive、预算范围、管理员只读、自证禁止和数据范围。 证据CONCEPT「权限」。
  • [CONCEPT: 算法与公式] 定义 3 个主 KPI、驱动指标、风险护栏和缺数据边界。 证据CONCEPT「算法与公式」。

3. 安全前置

  • [CONCEPT: 后端] 让旧财务看板显式接收可信租户与数据范围Claim/预算查询不得全表混算。 证据:finance_dashboard_access_policy.pyfinance_dashboard_scope.pyfinance_dashboard_budget.pyfinance_dashboard.pyClaim 直接按结构化 ExpenseClaim.tenant_id 首层过滤,预算历史兼容仅限 default 租户。
  • [CONCEPT: 后端] 给财务快照缓存键和后台任务加入租户/数据范围,禁止跨租户复用。 证据:finance_dashboard_snapshot.pyfinance_dashboard_scheduler.py;快照键包含 tenant 与 scope fingerprint调度入口必须显式携带租户。
  • [CONCEPT: 权限] 给财务与 CFO 分析接口增加后端角色和范围校验,管理员身份不自动获得业务确认权。 证据:finance_dashboard_access_policy.pysavings_access_policy.pyagent_run_access_policy.pyGET /api/v1/analytics/cfo-value;容器租户/缓存/角色回归 17 项通过。
  • [CONCEPT: 第一条可信机会] 标准重算只使用锁定数据库明细原金额,客户端原金额不能影响结果和节省。 证据:expense_claim_standard_adjustment.py;原金额只读锁定 ExpenseClaimItem.item_amount,政策结果只由服务端重算,陈旧版本使用内容指纹并降低基线质量等级。
  • [CONCEPT: 后端] 将标准重算、审计和账本写入收口到同一事务边界。 证据:expense_claim_standard_adjustment.pycommit=False 写审计,同一 API 事务写 Claim、Baseline、Opportunity、Evidence、SavingsEvent 和 BusinessEvent事务失败整体回滚。

4. Savings Ledger 后端

  • [CONCEPT: 数据与契约] 新增 profile_baseline_snapshotssavings_opportunitiessavings_realizationssavings_evidence_linkssavings_events 模型。 证据:savings.py(模型)及 test_savings_models.py;五类事实分离保存基线、机会、结果、证据和不可变操作。
  • [CONCEPT: 数据与契约] 新增 Alembic 0015、迁移所有权、复合租户外键、唯一键、检查约束、索引和 append-only 触发器。 证据:20260716_0015_savings_value_ledger.pymigration_preflight.pyschema_ownership.py;一次性 PostgreSQL 17 空库完整迁移循环通过。
  • [CONCEPT: 后端] 实现 discovery、action、realization、query、access policy 和 response builder 独立服务。 证据:savings_discovery.pysavings_actions.pysavings_realization.pysavings_query.pysavings_access_policy.pysavings_read_projection.pysavings_protocol.py
  • [CONCEPT: 后端] 实现分页、筛选、排序、详情、可用动作、证据和事件 DTO。 证据:GET /api/v1/savings/opportunitiesGET /api/v1/savings/opportunities/{id}savings.pyschema/APItest_savings_endpoints.py
  • [CONCEPT: 算法与规则] 实现版本锁、请求指纹、不可变响应重放、收益去重和归因比例约束。 证据:SavingsRequestProtocol、数据库唯一/检查约束与 test_savings_concurrency_postgres.py;同 request 并发仅一次写入,同 benefit 双确认仅一个 canonical winner。
  • [CONCEPT: 状态转换] 实现 accept/start/record/verify/reject/expire/reverse 合法与非法转换。 证据:savings_actions.pysavings_realization.pytest_savings_ledger_services.py;负向 reversal 只追加,不改写原已确认金额。
  • [CONCEPT: 证据与审计] 把 Savings 关键动作写入同 Case 的 BusinessEvent 并保留 correlation/causation。 证据:ExpenseCaseService 资源链接与 savings_* 服务;端到端测试核验 opportunity/payment/action/confirm/reverse 事件同 Case 可回放。
  • [CONCEPT: 后端] 新增历史标准重算机会 dry-run/apply 回填脚本;缺 Case/租户/政策证据只输出数据质量报告。 证据:savings_standard_adjustment_backfill.pybackfill_standard_adjustment_savings.py;显式租户/目标库、指纹重算、批次锁、稳定键重放,容器直接测试 8 项通过。

5. 首条真实纵向闭环

  • [CONCEPT: 第一条可信机会] 接受住宿标准重算时冻结服务端原金额、政策输入/版本、目标金额、差额、维度和证据。 证据:SavingsDiscoveryService冻结 ProfileBaselineSnapshot 与内容指纹,政式发布版本为 complete内容指纹版本显式标记 partial。
  • [CONCEPT: 第一条可信机会] 同事务以稳定 opportunity key 创建或重放机会,并进入 in_progress。 证据:稳定键由 tenant + claim + item + policy version + calculation fingerprint 生成;重试返回原机会。
  • [CONCEPT: 后端] 付款业务事件后同事务创建 actual realization重复付款事件不重复计入。 证据:expense_claim_approval_flow.py调用 realize_paid_claim()PostgreSQL 同付款事件并发结果为 [0, 1],仅一条 realization 和一条完成事件。
  • [CONCEPT: 财务确认] 实现独立财务 verify/reject未确认实际结果不得进入主 KPI。 证据:所有人工实际结果必须至少一条可追溯证据;独立确认人会固化证据复核人/时间pending 结果在 CFO 口径中为 0。
  • [CONCEPT: 冲回能力] 实现补付/申诉/归因修正的负向 reversal原确认不可删除。 证据:原 actual 保留 finance_confirmed,新增负向 canonical reversalas_of 可回放冲回前结果。
  • [CONCEPT: 权限] 验证申请人、机会负责人、结果填报人、纯管理员和跨租户用户不能自证或越权。 证据:SavingsAccessPolicy与 PostgreSQL 并发安全测试owner/recorder/admin-only 自证拒绝,独立 finance 可确认,跨租户无副作用。

6. 费用基线与经营分析

  • [CONCEPT: 基线快照] 按员工、部门、费用类型、城市、项目和流程从租户安全真实数据生成基线窗口、样本量和版本。 证据:savings_fact_scope.pysavings_baseline_generation.pysavings_insights.py;金额五维使用已归档明细中位数,流程维度只使用同租户报销提交时间与首个 payment_completed 业务事件,冻结 elapsed minutes、窗口、样本量、算法版本、查询指纹、质量、证据和审计事件source_workflow_cycle_count 明确披露覆盖,活跃工时保持 unavailable。
  • [CONCEPT: 基线快照] 供应商数据缺少租户/合同事实时显示 coverage gap不从应付模拟种子生成可信基线。 证据:基线和洞察 API 均返回 supplier_dimension_unavailable / supplier_price_drift_unavailable,要求核验供应商、数量和单位价格;不会读取 AccountsPayableRecord 模拟事实或创建货币化机会。
  • [CONCEPT: 算法与规则] 实现预算预测、描述性异常归因、重复小额浪费、历史偏离和只读政策模拟准备项;证据不足时不自动货币化。 证据:savings_insight_budget.py 复用预算配置/核销事实并以 min(as_of, window_end) 截止;savings_insight_analysis.pysavings_insight_attribution.py 输出历史偏离、部门/费用类型/城市/项目异常集中和版本化政策模拟必需输入。所有缺少正式反事实的候选 estimated_savings=Nonecreated_opportunity_ids=[],稳定重放不写 SavingsOpportunity
  • [CONCEPT: 后端] 实现 GET /analytics/cfo-value,统一时间、维度、币种、状态和 as_of 口径。 证据:cfo_value.pyAPI/schemacfo_value_analytics.py;租户、角色、预算范围、时间和维度过滤均在服务端执行。
  • [CONCEPT: 算法与公式] 实现确认现金、工时待采集、安全直通率资格、漏斗、兑现周期、逾期、来源和护栏聚合。 证据:确认现金只求和 finance_confirmed + canonical + cash工时和安全直通率显式返回 collecting漏斗、趋势、驱动、逾期、冲回和数据质量不与主 KPI 混算。
  • [CONCEPT: 降级策略] 多币种、工时、外部付款和审计结果缺失时返回明确数据质量状态,不伪造 0。 证据:多币种按原币分组;无人工活跃时间/审计事实时返回 collecting/unavailable 和 coverage gap不使用 mock 回退。

7. CFO 前端

  • [CONCEPT: 前端] 在分析看板新增 value 入口,并把 dashboard 状态同步 URL。 证据:useTopBarOverviewRange.jsAppShellRouteView.vueOverviewView.vuedashboard=value 与价值筛选/页码写入 query刷新和返回可恢复。
  • [CONCEPT: 前端] 新增独立 CFO 组件、composable、API service 和展示模型,不继续扩大 useOverviewView.js。 证据:CfoValueDashboard.vueCfoValueTrendChart.vueCfoValueOpportunityDrawer.vueCfoValueActionDialog.vueuseCfoValueDashboard.jsanalyticsValue.jscfoValueDashboardModel.js;业务组件和状态职责已拆分,核心文件均低于 800 行。
  • [CONCEPT: CFO 看板] 实现主 KPI、护栏、价值漏斗、趋势、来源/组织驱动、机会表和数据质量。 证据:CfoValueDashboard.vuecfo-value-dashboard.css;现金、工时和直通率分卡,趋势按币种切换,预计/实际/确认/冲回不混算,缺数据显式展示。
  • [CONCEPT: 前端] 实现时间、部门、费用类型、价值类型筛选和项目/供应商/城市/负责人高级筛选。 证据:顶部时间窗口与价值 query 联动,createEmptyValueFiltersreadValueFiltersFromQuerywriteValueFiltersToQuery 和 API query 白名单覆盖全部筛选字段。
  • [CONCEPT: 前端] 实现基线、建议、执行、实际、确认、去重和证据详情。 证据:CfoValueOpportunityDrawer.vue 展示冻结基线、机会状态、实际净值、记录人、canonical 去重、财务确认人/时间/说明、证据索引和不可变事件;无可追溯凭证时不开放手工实际结果登记。
  • [CONCEPT: 前端] 实现单据、风险、预算、维度下钻与返回状态恢复。 证据:cfoValueSourceLinks.js 统一构造来源路由Claim 进入 app-document-detail,风险携带最小 focus/观察/决策参数和现有锚点,预算进入 app-budget 配置视图并应用部门/费用类型焦点,维度返回 app-overview?dashboard=value 相应筛选。useCfoValueDashboard.jsvalue_opportunity 恢复抽屉,并在非法 ID、403/404、跨租户不可见或不符合当前筛选/时间窗口时安全清除;useAppShell.js 从单据详情恢复 CFO 查询。限制:预算中心仍是演示配置视图,页面明确金额不是当前机会的真实预算事实;未覆盖费用科目显示未配置而不是零预算。
  • [CONCEPT: 降级策略] 区分零、无数据、基线不足、无权限、失败、部分数据和快照过期;删除 CFO 演示回退。 证据:classifyCfoDashboardStatebuildValueKpis 与页面状态区;接口失败不读取 data/metrics.js 或 demo/fallback 数字。
  • [CONCEPT: 前端] 完成移动端、键盘、焦点、44px 触控和无障碍状态提示。 证据CFO 样式移动断点、44px 按钮、语义化 label/role=alert/aria-live、抽屉关闭标签及趋势表格降级;生产构建通过。

8. 测试与验证

  • [CONCEPT: 测试方案] 后端状态、金额、权限、租户、幂等、证据、去重、冲回和看板聚合单测通过。 证据:容器组合回归 84 项通过;本轮 Savings/CFO 基线、洞察、端点、账本、回填与 E2E 组合 34 passed, 6 skipped6 项为未配置 PostgreSQL 专用 URL 的预期跳过。
  • [CONCEPT: 测试方案] 标准重算客户端金额伪造、政策失败、Case 缺失和事务回滚测试通过。 证据:test_expense_claim_service.py -k standard_adjustment 8 项加付款集成 1 项通过HTTP 标准重算 1 项通过。
  • [CONCEPT: 测试方案] 前端数据归一化、状态、筛选、URL、证据动作和响应式测试通过。 证据:容器内 cfo-value-dashboard.test.mjs 14 项通过,新增机会 URL 恢复/清理、筛选上下文、风险/单据/预算/维度链接和预算非事实口径断言;与 App Shell 返回链、路由加载和筛选样式组合回归 37 项通过;带凭证序列化和无证据入口 fail-closed 均有断言。
  • [CONCEPT: 测试方案] 一次性 PostgreSQL 空库迁移、重复升级、约束、append-only、无损降级和并发测试通过。 证据:一次性 PostgreSQL 17 迁移循环通过;test_savings_concurrency_postgres.py 6 项通过覆盖重放、canonical 竞态、跨租户、独立确认、付款单事实和 append-only DB 触发器。
  • [CONCEPT: 集成] 住宿标准重算 → 机会 → 审批 → 付款 → 实际 → 财务确认 → CFO 看板 E2E 通过。 证据:test_savings_value_e2e.py 从服务端政策差额、付款动作、待确认排除、独立财务确认到 CFO 金额对账单项通过。
  • [CONCEPT: 集成] 确认后负向冲回和报告 as_of 回放 E2E 通过。 证据:test_savings_value_e2e.pytest_cfo_value_analytics.py同时验证当前净值归零和冲回前历史金额回放。
  • [CONCEPT: 容器验证] 相关 pytest、Ruff、前端测试和生产构建均在 local-x-financial-linux 内通过。 证据Savings/CFO 相关切片与端到端均通过fresh PostgreSQL 总探针 87 passed / 0 skipped / 0 failed,其中 Savings 并发 6 项Web 全量 815 passed / 0 failed 与 Vite build 通过;新增 Python 文件 Ruff 和 git diff --check 通过。

9. 文档收尾

  • [CONCEPT: 指标与验收] 逐项核对 A1-A8并把文件、接口、迁移、测试和运行结果写回证据。 证据A1 纵向闭环由 test_savings_value_e2e.pyA2-A4/A4.1 由 Savings schema、cfo_value_analytics.py、基线/分析测试A5-A6 由 CFO 组件、来源下钻和前端状态测试A7 由 0015 迁移与 PostgreSQL 并发A8 由本节最终容器汇总证明。
  • [CONCEPT: 风险与开放问题] 记录付款证据等级、汇率、双人复核、工时口径和试点目标的最终边界。 证据:
  • [CONCEPT: 本轮实现记录] 同步更新上位 ai-expense-closed-loop-and-value-proof 文档,不删除历史证据。 证据:上位 TODO 已回填 Savings Ledger、状态机、CFO 看板、下钻、证据详情和 E2E历史证据原样保留。