Files
docs/财务管理/F1人工财务契约审查与门禁.md
T
2026-08-11 11:41:44 +08:00

8.2 KiB
Raw Blame History

F1 人工财务契约审查与门禁

审查日期:2026-08-11
审查范围:Finance Java、Finance 建库 SQL、统一增量 SQL、Admin/Client Finance API、openapi/finance-f1-manual-v1.yaml
结论:F0/F1 基础代码已经实现,当前处于专项修复与契约收敛阶段;不是整体未开发。修复项完成前尚未达到完整联调验收/测试放行。

1. 已确认且已对齐

范围 目标 当前结论
产品边界 人工账单、人工收款、人工成本,不做汇率、月结和自动认款 对齐
币种 只支持 CNY Controller 校验、OpenAPI 枚举和 SQL CHECK 均为 CNY
客户账期 每客户配置,默认 30 个自然日 Finance 已有 GET/PUT;未配置返回 30;范围 0-3650 天
到期日 billDate + creditDays Finance 创建/修改草稿时已计算
出账冻结 只有 DRAFT 可直接修改,出账后走调整 Finance 更新 SQL 限制 status='DRAFT',已对齐基本门禁
收款分配 一笔 300 元可分配 3 张各 100 元账单 已校验分配合计、客户归属、状态和未收余额,并在同一事务更新三张账单
客户权限 客户只读且只能看本客户 Client Controller 从认证上下文取客户范围,无客户写接口
成本类型 单票、整柜公共成本 Java/OpenAPI/Admin 均统一为 SINGLE_ORDER/CONTAINER_SHARED
权限码 平台 12 个按钮权限,客户 2 个按钮权限 Controller、OpenAPI 和统一 SQL 权限种子已对齐
表结构 账单、修订、收款分配、成本及成本分摊 Finance SQL 与统一增量 SQL 均存在对应表

当前实现包括 Finance Controller/Service、独立财务表、统一 SQL 权限种子、Admin 人工财务页面和 Client 只读账单页面。本文中的 D1-D10 是对现有实现的修复门禁,不是从零建设清单。

2. 接口与权限基线

接口 权限 当前状态
GET /api/platform/finance/v1/bills?customerId= platform:finance:bill:view 已实现;返回非分页数组
POST /api/platform/finance/v1/bills platform:finance:bill:create 已实现
GET/PUT /api/platform/finance/v1/bills/{billId} bill:view/update 已实现;Admin 尚未接详情/修改
`POST .../{billId}/issue adjust void`
GET/POST /api/platform/finance/v1/receipts receipt:view/create 已实现
GET/POST /api/platform/finance/v1/cost-entries cost:view/create 登记已实现;整柜分摊未实现
GET/PUT /api/platform/finance/v1/customers/{tenantId}/terms customer-terms:view/update Java 已实现;Admin 尚未接入
GET /api/client/finance/v1/bills merchant:finance:statement:list 已实现
GET /api/client/finance/v1/bills/{billId} merchant:finance:statement:view 已实现
GET /api/client/finance/v1/receipts merchant:finance:statement:view 已实现

tenantId 只保留为后端兼容路径字段,产品语义统一为客户 ID,不增加用户可见的“租户”层级。

3. 开发门禁阻断项

以下项目未完成前,可以继续编码,但不能宣称 F1 已具备完整业务闭环。

编号 阻断项 当前事实 完成标准
D1 稳定响应 DTO Finance 直接返回 JDBC Map/List<Map>,字段为 snake_case 按 OpenAPI 1.1.0 输出账单、收款、成本、账期固定 camelCase DTO;所有成功/失败响应带 requestId/traceId/timestamp
D2 列表形态统一 Java 为非分页数组;Admin/Client 已做本地分页适配,但仍发送分页/筛选参数 首期明确维持非分页并清理无效参数,或后端真正实现统一分页;两端测试与 OpenAPI 同步
D3 调整记录可查询 Java 调整前写 fin_bill_revision,再更新当前账单及替换明细,具备数据库快照;但无修订查询接口,产品无法查看调整前后 明确“同账单版本修订”即首期方案,并提供调整记录查询/展示;不得无痕覆盖
D4 幂等语义 重复幂等键目前直接返回冲突,request_hash 只哈希键本身 同键同参成功后返回原资源;异参返回 FIN-IDEMPOTENCY-CONFLICT;PROCESSING 返回 409 + Retry-After 并由超时恢复任务核对
D5 财务凭证链路 Admin 已主动阻止空凭证保存;Finance 未校验 File,File 也没有财务专用公开上传/内部关联接口 实现 OpenAPI 中临时上传、批量校验、幂等关联;严格校验客户、用途、状态、类型和大小,关联失败由 Finance Outbox 补偿
D6 整柜体积分摊 有 fin_cost_allocation 表,但 createCost 只写 fin_cost,未计算或落分摊 同客户有效票按体积、6 位 HALF_UP 分摊,最后一票承接尾差;总体积为零才允许人工分摊且合计严格相等
D7 成本归属校验 Java 仅校验成本类型和金额,未强制单票 orderId/整柜 containerId 两种类型分别强制唯一归属,且校验对象存在、属于对应客户
D8 Admin 成本字段映射 后端列为 fee_item_name/cost_amount,Admin 读取 expense_name/amount,列表费用名和金额会为空/0 Admin 适配真实线协议并增加回归测试
D9 Admin 完整操作 已有创建、列表和出账;缺账单详情/草稿修改/调整/作废、客户账期维护 接齐接口、权限按钮、版本冲突和错误态;调整原因、作废原因必填
D10 业务错误码 文档定义 FIN-AR-*/FIN-COST-*;Java 当前主要返回通用 BAD_REQUEST/CONFLICT + 中文消息 后端建立稳定业务码并由 Admin/Client 按码处理,不依赖消息文本
D11 客户状态可见性 Client Controller 当前按客户隔离,但账单列表/详情未过滤状态 客户只可见 ISSUED/PARTIALLY_PAID/PAID;草稿、作废、跨客户和不存在详情统一按不存在处理

4. 非阻断但需锁定的契约说明

  • UpdateBillRequest 与当前 Java 一致,包含 customerId、billDate、lines、expectedVersion。
  • 平台账单列表的 customerId 必填;收款、成本列表可不传客户,供平台总览。
  • 收款分配字段在请求中为 allocations[].amount;数据库返回联表字段为 applied_amount。对外 DTO 应统一一个命名,建议请求继续用 amount,响应用 allocatedAmount。
  • 已收账单不得作废;当前 Java 只允许 DRAFT/ISSUED 且 received_amount=0 作废,符合首期简化原则。
  • 调整后总额不得低于已收金额;这条现有服务端约束应保留。
  • 客户停用才影响客户账单访问;客户子用户停用只影响该用户登录,不改变账单的客户主体归属。

5. 可测试门禁

进入前后端联调前至少满足:

  1. D1、D3、D5、D6、D7、D8、D9、D10、D11 已完成并有直接测试。
  2. D2 选定“首期非分页”或“服务端分页”之一,OpenAPI、Admin、Client 三方一致。
  3. D4 至少完成账单创建、出账和收款登记的同键重放测试。
  4. Finance 集成测试覆盖:默认 30 天、CNY 拒绝、出账冻结、300 分 3 单、超额/跨客户/草稿拒绝、部分收款到收清、调整修订、已收不可作废。
  5. 成本测试覆盖:单票归属、整柜按体积分摊、零体积人工处理、舍入尾差、跨客户对象拒绝。
  6. 权限测试覆盖平台 12 个权限码和客户 2 个权限码,并验证客户无法写入及无法跨客户查询。
  7. 客户查询测试证明列表、详情和收款均不会暴露 DRAFT/VOIDED、平台凭证 fileId 或内部备注。

6. 放行结论

  • 当前阶段:专项修复中。 Finance、SQL、Admin 和 Client 均已有实现,不再按“未开发”管理。
  • 可继续开发:是。 路径、权限、固定 DTO、凭证、分摊、幂等和客户可见性已经冻结,不再需要新增产品决策。
  • 可进行接口冒烟:有条件。 可验证现有路径、鉴权和基础创建/查询,但结果不代表业务验收通过。
  • 可进入完整联调验收:否。 主要阻断为整柜成本分摊、凭证服务端校验、Admin 完整操作、稳定 DTO/错误码和幂等重放。

本次审查只修订文档与 OpenAPI,未修改 Java、前端或 SQL。