2026-08-11 11:41:44 +08:00
|
|
|
|
# F1 人工财务契约审查与门禁
|
|
|
|
|
|
|
|
|
|
|
|
> 审查日期:2026-08-11
|
2026-08-11 13:55:19 +08:00
|
|
|
|
> 审查范围:Finance Java、Finance 建库 SQL、统一增量 SQL、Admin/Client Finance API、File Java/测试、`openapi/finance-f1-manual-v1.yaml`
|
2026-08-11 11:41:44 +08:00
|
|
|
|
> 结论:F0/F1 基础代码已经实现,当前处于专项修复与契约收敛阶段;不是整体未开发。修复项完成前尚未达到完整联调验收/测试放行。
|
|
|
|
|
|
|
2026-08-11 18:06:30 +08:00
|
|
|
|
> 范围重定:领导验收改为《财务一期五页产品与接口验收契约》中的 5 页。本文 D1-D11 继续作为既有人工接口专项门禁,并新增来源链路和五页门禁。
|
|
|
|
|
|
|
2026-08-11 11:41:44 +08:00
|
|
|
|
## 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 均存在对应表 |
|
|
|
|
|
|
|
2026-08-11 13:55:19 +08:00
|
|
|
|
当前实现包括 Finance Controller/Service、独立财务表、统一 SQL 权限种子、Admin 人工财务页面和 Client 只读账单页面。本文中的 D1-D11 是对现有实现的修复门禁,不是从零建设清单。
|
|
|
|
|
|
|
2026-08-11 18:06:30 +08:00
|
|
|
|
### 1.1 后端最终实现复验记录(2026-08-11,基线 `7c2274b`)
|
2026-08-11 13:55:19 +08:00
|
|
|
|
|
|
|
|
|
|
| 验证对象 | 命令/范围 | 结果 | 结论 |
|
|
|
|
|
|
|---|---|---|---|
|
2026-08-11 18:06:30 +08:00
|
|
|
|
| Finance | 后端历史基线复验 | 12 个测试通过 | 历史基线记录;固定 DTO、来源消费和完整幂等已由下方最新 35/35 结果覆盖 |
|
|
|
|
|
|
| Firstleg | 后端全量复验 | 527 个测试通过 | 真实柜次体积快照、客户过滤和无有效体积拒绝有直接证据 |
|
|
|
|
|
|
| File | 后端全量复验 | 114 个测试通过 | 原 JUnit 测试发现故障已解决,不再作为阻断 |
|
|
|
|
|
|
| Gateway | 后端全量复验 | 26 个测试通过 | 本次相关网关回归通过 |
|
|
|
|
|
|
| IAM | 后端全量复验 | 163 个测试通过 | 本次相关权限回归通过 |
|
2026-08-11 13:55:19 +08:00
|
|
|
|
| Admin Finance API | `pnpm test -- src/modules/finance/api/finance.test.ts` | 通过;1 个测试文件、7 个测试通过 | D8 字段适配与账单动作封装有直接证据 |
|
|
|
|
|
|
|
2026-08-11 18:06:30 +08:00
|
|
|
|
以上计数来自总控最终后端复验。尚未提供测试环境中 Finance → Firstleg/File 的真实 HTTP 联调报告,因此跨服务部署连通性仍需在联调阶段验证,但不再视为代码实现阻断。
|
|
|
|
|
|
|
|
|
|
|
|
### 1.2 五页与费用来源主链增量复验(2026-08-11)
|
|
|
|
|
|
|
|
|
|
|
|
| 验证对象 | 当前 Surefire 证据 | 结果 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| Finance 全模块 | 10 个测试类:费用来源消费、内部 Controller、五页 DTO、Client 脱敏、异常码、File fail-closed、SQL 契约等 | **35/35,BUILD SUCCESS** |
|
|
|
|
|
|
| Finance 来源消费 | `FinanceFeeSourceEventServiceTest`、`InternalFinanceFeeSourceControllerTest` | **10/10 + 2/2 通过**;覆盖入库/柜子来源写入、调整替代、作废保留、同参重放、异参冲突、跨客户、未发布、零金额和负金额拒绝 |
|
|
|
|
|
|
| Firstleg | 全量复验 549 项(2 skip);其中事件客户端、Outbox relay、快照、柜子费用、迁移契约等 7 个测试类 17 项 | **549/549 通过,2 skip;来源定向 17/17 通过** |
|
|
|
|
|
|
| 其他直接消费者与 SQL 契约 | File、Gateway、IAM、Phase3/PDA SQL、Order SQL | **114/114、26/26、163/163、12/12、3/3,均 BUILD SUCCESS** |
|
|
|
|
|
|
| 五页固定 DTO 与脱敏 | `FinanceReadApiBehaviorTest`、`FinanceFeePoolDirectionBehaviorTest`、`FinanceExceptionHandlerTest` | **3/3 + 2/2 + 2/2 通过** |
|
|
|
|
|
|
|
|
|
|
|
|
本轮文档任务未重新执行 Maven;以上结果直接读取当前工作树已有 Surefire 报告,不把“测试源码存在”替代为“测试通过”。
|
2026-08-11 11:41:44 +08:00
|
|
|
|
|
|
|
|
|
|
## 2. 接口与权限基线
|
|
|
|
|
|
|
|
|
|
|
|
| 接口 | 权限 | 当前状态 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| `GET /api/platform/finance/v1/bills?customerId=` | `platform:finance:bill:view` | 已实现;返回非分页数组 |
|
2026-08-11 18:06:30 +08:00
|
|
|
|
| `POST /internal/finance/v1/fee-source-events` | `X-Internal-Service-Token` | 已实现并验证;Inbox 幂等消费后写入/替代/作废 `fin_fee_source`,Finance 消费/Controller 12 项定向测试通过 |
|
|
|
|
|
|
| `GET /api/platform/finance/v1/customer-accounts/{customerId}` | `platform:finance:bill:view` | 已实现固定 `CustomerAccount` DTO;Finance DTO 行为测试通过 |
|
|
|
|
|
|
| `GET /api/platform/finance/v1/fee-pool?customerId=&direction=` | `platform:finance:bill:view` | 已实现固定 `FeePoolItem` DTO;方向和客户范围测试通过 |
|
|
|
|
|
|
| `GET /api/platform/finance/v1/statements?customerId=` | `platform:finance:bill:view` | 已实现固定 `Statement` DTO;生成/审核操作未实现 |
|
|
|
|
|
|
| `GET /api/platform/finance/v1/receivable-settlements?customerId=` | `platform:finance:bill:view` | 已实现固定 `ReceivableSettlement` DTO;生成操作未实现 |
|
|
|
|
|
|
| `GET /api/platform/finance/v1/payable-settlements?customerId=` | `platform:finance:cost:view` | 已实现固定 `PayableSettlement` DTO;审核/付款操作未实现 |
|
2026-08-11 11:41:44 +08:00
|
|
|
|
| `POST /api/platform/finance/v1/bills` | `platform:finance:bill:create` | 已实现 |
|
2026-08-11 13:55:19 +08:00
|
|
|
|
| `GET/PUT /api/platform/finance/v1/bills/{billId}` | `bill:view/update` | Java 和 Admin 均已接入;缺修订历史查询 |
|
|
|
|
|
|
| `POST .../{billId}/issue|adjust|void` | `bill:issue/adjust/void` | Java 和 Admin 均已接入;端到端闭环未放行 |
|
2026-08-11 18:06:30 +08:00
|
|
|
|
| `GET/POST /api/platform/finance/v1/receipts` | `receipt:view/create` | 已实现平台 `PlatformReceipt` 查询 DTO、多账单分配和凭证 fail-closed;Finance 测试通过 |
|
|
|
|
|
|
| `GET/POST /api/platform/finance/v1/cost-entries` | `cost:view/create` | 已实现;整柜由 Finance 调 Firstleg 真实快照,成本凭证和归属均校验 |
|
2026-08-11 11:41:44 +08:00
|
|
|
|
| `GET/PUT /api/platform/finance/v1/customers/{tenantId}/terms` | `customer-terms:view/update` | Java 已实现;Admin 尚未接入 |
|
2026-08-11 18:06:30 +08:00
|
|
|
|
| `GET /api/platform/finance/v1/bills/{billId}/revisions?customerId=` | `bill:view` | 已实现,并校验账单客户归属;Admin 尚未接入 |
|
|
|
|
|
|
| `POST /api/platform/finance/v1/vouchers?customerId=` | `receipt:create` 或 `cost:create` | 已实现图片上传,双权限兼容 |
|
2026-08-11 11:41:44 +08:00
|
|
|
|
| `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,不增加用户可见的“租户”层级。
|
|
|
|
|
|
|
2026-08-11 18:06:30 +08:00
|
|
|
|
## 3. 门禁状态(已解决与剩余)
|
2026-08-11 11:41:44 +08:00
|
|
|
|
|
2026-08-11 18:06:30 +08:00
|
|
|
|
本表保留 D1-D11 的稳定编号用于总控追踪。标为“后端完成/定向验证通过”的项目不再作为代码实现阻断;其余项目完成前不能宣称 F1 已具备完整业务闭环。
|
2026-08-11 11:41:44 +08:00
|
|
|
|
|
|
|
|
|
|
| 编号 | 阻断项 | 当前事实 | 完成标准 |
|
|
|
|
|
|
|---|---|---|---|
|
2026-08-11 18:06:30 +08:00
|
|
|
|
| D1 | 稳定响应 DTO | **后端完成。** 五页查询使用 `FinanceReadModels`、`FinanceQueryService` 和 `FinanceResponses`;平台/客户收款使用专用 DTO,成功/失败均带追踪字段;Finance 35/35 通过 | 后端门禁关闭;Admin 继续按固定 camelCase DTO 接入 |
|
|
|
|
|
|
| D2 | 列表形态统一 | **契约已冻结。** 首期维持非分页数组,Admin/Client 在适配层本地分页,OpenAPI 与 Java 一致 | 清理前端无效分页参数属于非阻断整理,不再要求后端改为分页对象 |
|
|
|
|
|
|
| D3 | 调整记录可查询 | **后端完成。** 调整前写 `fin_bill_revision`;`GET /bills/{billId}/revisions?customerId=` 已落地并校验客户归属,Finance 测试覆盖同客户和跨客户场景 | Admin 接入展示后完成产品闭环;后端门禁已通过 |
|
|
|
|
|
|
| D4 | 幂等语义 | **后端完成。** 幂等记录按客户、操作人、operation 和 key 隔离,请求哈希覆盖 method、path 和序列化 body;支持成功同参重放、异参 `FIN_409`、PROCESSING 冲突、超时 PROCESSING 抢占恢复和 FAILED 恢复 | 后端门禁关闭;保持写操作回归测试 |
|
|
|
|
|
|
| D5 | 财务凭证链路 | **后端完成。** 上传路径和双权限已对齐;File 客户端缺失返回 `FIN_503`,凭证归属/MIME/业务类型校验保持 fail-closed;Finance 35/35 通过 | 后端门禁关闭;测试环境保留一次真实 File HTTP 冒烟 |
|
|
|
|
|
|
| D6 | 整柜体积分摊 | **后端完成。** 公共请求只提交 `containerId`;Finance 调 Firstleg 真实柜次快照,按 6 位 `HALF_UP` 分摊并落 `fin_cost_allocation`;只有最后一票实际偏离常规舍入结果时才标记尾差 | Finance 12、Firstleg 527 测试通过;测试环境补一次真实跨服务冒烟即可进入联调验收 |
|
|
|
|
|
|
| D7 | 成本归属校验 | **后端完成。** Firstleg 只返回柜内属于客户且体积有效的订单;Finance 再以 `fin_fee_source` 校验单票/整柜订单属于客户 | 单票、整柜客户归属及无效快照测试通过 |
|
2026-08-11 13:55:19 +08:00
|
|
|
|
| D8 | Admin 成本字段映射 | **定向验证通过。** Admin 已兼容 `fee_item_name/expense_name` 与 `cost_amount/amount`;Finance API 测试 7/7 通过 | 保持回归测试;不得据此宣称成本创建端到端闭环通过 |
|
2026-08-11 18:06:30 +08:00
|
|
|
|
| D9 | Admin 完整操作 | **部分实现。** 已有详情、草稿修改、调整、作废、出账、凭证选择/上传和收款/成本创建;未接客户账期和 revision;整柜表单仍强制人工填写 `containerOrders/volumeCbm`,与最终后端只接 `containerId` 的契约不一致 | 删除人工体积录入,只提交 `containerId`;接客户账期和 revision;完成真实环境创建闭环 |
|
|
|
|
|
|
| D10 | 业务错误码 | **后端完成。** 通用财务异常固定为 `FIN_400/404/409/503/001`,来源事件固定为 `FIN-EVT-001` 至 `015`、`FIN-EVT-401`;未发布稳定返回 `FIN-EVT-015`,金额/币种错误返回 `FIN-EVT-010` | 后端门禁关闭;Admin/Client 按码处理,不依赖中文消息 |
|
|
|
|
|
|
| D11 | 客户状态可见性 | **后端完成。** 客户账单只见 `ISSUED/PARTIALLY_PAID/PAID`;客户收款只见 `CONFIRMED`,使用 `ClientReceipt` 专用 DTO 并去除凭证、操作人和内部字段;脱敏测试通过 | 后端门禁关闭;保留跨客户与序列化回归 |
|
|
|
|
|
|
| D12 | Finance 费用来源写入 | **后端完成。** 内部事件入口、令牌鉴权、Inbox 幂等、Firstleg 快照回查、来源写入/替代/作废均已实现;非作废事件必须 `PUBLISHED`,未发布返回 `FIN-EVT-015`;金额必须 `>0`,零/负返回 `FIN-EVT-010`;专项 10/10、Finance 全量 35/35 通过 | 后端门禁关闭;保留真实跨服务 HTTP 冒烟 |
|
|
|
|
|
|
| D13 | 柜子费用来源 | **后端完成并验证。** Firstleg 已有柜子费用模型、审核/参与结算/作废、事件、Relay 和内部快照;Firstleg 相关 17/17、Finance 柜子来源消费测试通过 | 后端门禁关闭;测试环境补真实跨服务事件冒烟 |
|
2026-08-11 18:43:53 +08:00
|
|
|
|
| D14 | 一期 5 页 | **FAIL / 一期 P0 未关闭。** 11 个目标 operation 契约已冻结;实现状态不再写入 OpenAPI 或主契约,G1-G4 证据矩阵当前均未放行 | G1-G4 分别完成组内全部后端直接行为测试和 Admin 真实接入,证据矩阵更新为 `PASS` 后再完成五页端到端验收 |
|
2026-08-11 11:41:44 +08:00
|
|
|
|
|
|
|
|
|
|
## 4. 非阻断但需锁定的契约说明
|
|
|
|
|
|
|
|
|
|
|
|
- `UpdateBillRequest` 与当前 Java 一致,包含 `customerId`、`billDate`、`lines`、`expectedVersion`。
|
|
|
|
|
|
- 平台账单列表的 `customerId` 必填;收款、成本列表可不传客户,供平台总览。
|
|
|
|
|
|
- 收款分配字段在请求中为 `allocations[].amount`;数据库返回联表字段为 `applied_amount`。对外 DTO 应统一一个命名,建议请求继续用 `amount`,响应用 `allocatedAmount`。
|
|
|
|
|
|
- 已收账单不得作废;当前 Java 只允许 `DRAFT/ISSUED` 且 `received_amount=0` 作废,符合首期简化原则。
|
|
|
|
|
|
- 调整后总额不得低于已收金额;这条现有服务端约束应保留。
|
|
|
|
|
|
- 客户停用才影响客户账单访问;客户子用户停用只影响该用户登录,不改变账单的客户主体归属。
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 可测试门禁
|
|
|
|
|
|
|
|
|
|
|
|
进入前后端联调前至少满足:
|
|
|
|
|
|
|
2026-08-11 18:43:53 +08:00
|
|
|
|
1. D1-D8、D10-D13 已具备后端直接证据;D14 当前 FAIL,G1-G4 任一组未同时通过后端行为测试与 Admin 真实接入,均不得通过一期完整联调验收。
|
2026-08-11 18:06:30 +08:00
|
|
|
|
2. D2 已固定为首期非分页数组;后续若改服务端分页须另行升级契约。
|
|
|
|
|
|
3. 幂等门禁已关闭;后续写 operation 继续复用同参重放、异参冲突和恢复语义。
|
2026-08-11 11:41:44 +08:00
|
|
|
|
4. Finance 集成测试覆盖:默认 30 天、CNY 拒绝、出账冻结、300 分 3 单、超额/跨客户/草稿拒绝、部分收款到收清、调整修订、已收不可作废。
|
2026-08-11 18:06:30 +08:00
|
|
|
|
5. 成本测试覆盖:单票归属、真实柜次快照、整柜按体积分摊、无有效体积拒绝、实际舍入尾差、跨客户对象拒绝。
|
2026-08-11 11:41:44 +08:00
|
|
|
|
6. 权限测试覆盖平台 12 个权限码和客户 2 个权限码,并验证客户无法写入及无法跨客户查询。
|
|
|
|
|
|
7. 客户查询测试证明列表、详情和收款均不会暴露 `DRAFT/VOIDED`、平台凭证 fileId 或内部备注。
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 放行结论
|
|
|
|
|
|
|
|
|
|
|
|
- **当前阶段:专项修复中。** Finance、SQL、Admin 和 Client 均已有实现,不再按“未开发”管理。
|
2026-08-11 18:17:02 +08:00
|
|
|
|
- **可继续开发:是。** 11 个 P0 的路径、权限、DTO、状态、凭证、幂等、错误码和客户隔离已经冻结,不再需要新增产品决策。
|
2026-08-11 11:41:44 +08:00
|
|
|
|
- **可进行接口冒烟:有条件。** 可验证现有路径、鉴权和基础创建/查询,但结果不代表业务验收通过。
|
2026-08-11 18:43:53 +08:00
|
|
|
|
- **可进入完整联调验收:否。** Finance 来源写入等既有门禁已通过;11 个 P0 的 G1-G4 证据矩阵尚未全部 `PASS`,Admin 五页真实接入和跨服务冒烟也未完成。开发中间态不改变该结论。
|
2026-08-11 11:41:44 +08:00
|
|
|
|
|
|
|
|
|
|
本次审查只修订文档与 OpenAPI,未修改 Java、前端或 SQL。
|