REV-005 验证记录
1. 验证范围
本记录用于沉淀 REV-005 当前已完成的发票业务闭环验证证据,覆盖以下范围:
- US1:后台发票申请与校验
- US2:
SYS-008 异步协同与查询兜底
- US3:结果回写、账单关联与客户侧电子发票消费
- US4:后台作废与红冲二期入口
当前验证结论以已执行命令、已完成文档修订、最小编译验证和范围边界复核为主;spec.md 中 SC-001 ~ SC-005 的性能/统计指标尚未形成专门压测脚本或批量样本统计,本文件先记录现有证据、缺口与后续建议。
2. 已执行验证命令与结果
| 类别 |
命令 |
结果 |
说明 |
| 文档单文件校验 |
make validate-file FILE=docs/design/03_Technical_Design/01_Database_Design.md |
通过 |
已用于验证发票数据承接口径 |
| 文档单文件校验 |
make validate-file FILE=docs/design/03_Technical_Design/03_Interface_Design.md |
通过 |
已用于验证客户侧查询/下载/推送与作废/红冲接口边界文档 |
| 文档单文件校验 |
make validate-file FILE=docs/design/02_Detailed_Design/12_REV_Detailed.md |
通过 |
已用于验证 REV-005 二期作废/红冲详细设计修订 |
| backend 最小编译 |
mvn -f backend/sw-business/sw-business-server/pom.xml -DskipTests compile |
通过 |
已用于验证 REV-005 US3/US4 代码可编译 |
| 仓库交叉引用校验 |
make check-links |
通过 |
当前链接检查输出为“所有链接检查通过” |
| Mermaid 语法校验 |
make validate-mermaid |
通过 |
当前 Mermaid 验证输出为“所有 mermaid 图表语法验证通过” |
| 验收资产复核 |
仓库关键字检索(SC-001、SC-002、SC-003、SC-004、样本统计、压测脚本、P95) |
未发现现成统计资产 |
当前仓库内暂未定位到可直接复用的压测脚本、统计脚本或样本台账,SC-001 ~ SC-004 仍需在测试或联调环境补充专项证据 |
3. Success Criteria 对照
SC-001 发票申请接口响应时间 < 500ms(不包含外部服务调用)
- 当前状态:待补充专项验证(实现态证据已补强)
- 现有证据:backend 最小编译通过,后台申请接口与校验链路已实现
- 实现态补充证据:
InvoiceController.applyInvoice 已固定暴露 /business/invoice/apply 入口;InvoiceApplyReqVO 强制要求 chargeIds、custId、invoiceType、invoiceTitle、sourceChannel;InvoiceServiceImpl.applyInvoice 当前同步执行的仅包括账单去重排序、幂等单号生成、客户/客户开票信息/账单/税率校验、InvoiceDO 落库与操作日志写入,并未在该方法内直接同步调用外部 SYS-008,而是通过生成 sysRequestNo、写入 PENDING 状态后结束本地受理流程。
- 缺口说明:尚未执行接口响应时延采样,也未沉淀固定样本、环境与统计结果
- 后续建议:在可用测试环境中对
/business/invoice/apply 执行最小样本压测或定点采样,至少记录样本量、平均值、P95、排除外部调用口径
- 建议统计口径:仅统计
SYS-002 本地受理、账单/客户/税率/限额校验、申请记录落库等内部处理时延;明确剔除 SYS-008 外部接口等待时间;结果表至少记录样本时间、样本环境、请求体摘要、平均值、P95、最大值与异常样本说明
SC-002 发票申请校验通过率 > 95%(正常业务场景)
- 当前状态:待补充样本统计(实现态证据已补强)
- 现有证据:已实现账单收费状态、开票状态、客户开票信息、税率配置、开票限额、幂等控制等校验规则
- 实现态补充证据:
validateCustInvoice 已明确拦截“客户未维护开票信息”“客户开票信息不存在”“发票抬头不一致”“税号不一致”“电子发票缺少邮箱/手机号”等场景;validateCharges 已明确拦截“账单不存在”“账单与客户不匹配”“仅已收费账单允许申请开票”“存在已开票账单”;validateInvoiceTaxrate 会拦截缺少可用税率配置;applyInvoice 对同一 applicationNo 或 custId + chargeIds 组合会直接返回既有申请,因此幂等命中样本应单列说明,不能混入正常成功率分母。
- 缺口说明:尚未基于真实或模拟样本形成“正常场景通过率”统计
- 后续建议:准备覆盖正常账单、已开票账单、未缴费账单、限额超限账单等样本集,按样本分组输出通过/拦截统计
- 建议统计口径:将样本分为“正常业务场景”和“规则拦截场景”两组;SC-002 仅统计正常业务场景的申请成功率,结果表至少记录样本总数、成功数、失败数、失败原因分类,并单列幂等命中、原始单账单直接部分开票拦截等非正常场景说明
SC-003 开票结果回写成功率 > 99%
- 当前状态:待补充样本统计(实现态证据已补强)
- 现有证据:已实现结果回写、成功终态保护、账单状态联动、失败原因留痕
- 实现态补充证据:
writeBackInvoice 已支持按 applicationNo / sysRequestNo 定位发票,统一回写 invoiceStatus、invoiceCode、invoiceNumber、fileUrl、pushStatus、latestResult、latestError 与 failReason,并调用 syncChargeInvoiceState 做账单联动;若当前记录已是 SUCCESS 且收到非成功回写,会命中“成功终态保护”分支,仅刷新查询上下文与日志,不覆盖既有成功结果;queryInvoice 与 /query/compensate 复用 refreshQueryContext,可为回写失败、超时与补偿查询样本提供统一追溯键。
- 缺口说明:尚未基于批量样本统计回写成功率
- 后续建议:在联调或测试环境中按申请单号、受理号建立样本集,统计回写请求总量、成功量、失败量与失败原因分类
- 建议统计口径:按“回写请求总量”“业务成功落账量”“业务失败量”“因成功终态保护而不覆盖原状态量”四类指标统计;失败样本需区分外部返回失败、查询超时、账单联动异常、数据缺失等分类,并保留申请单号/受理号映射以便追溯
SC-004 电子发票下载成功率 > 99%
- 当前状态:待补充样本统计(实现态证据已补强)
- 现有证据:已实现仅
SUCCESS + fileUrl 可下载/推送的前置校验,客户归属校验与推送状态回写已落地
- 实现态补充证据:
getRequiredCustomerInvoice 已要求 custId 必填,且 invoiceId、applicationNo、sysRequestNo 至少提供一个定位键,并会拦截“未找到当前客户可访问的电子发票”;validateDownloadableInvoice 已明确拦截“当前发票状态不可下载或推送”“电子发票文件地址不存在”;pushInvoice 仅支持 EMAIL、SMS 两类渠道,并分别校验邮箱/手机号是否可用,成功后会更新 pushStatus、latestResult 并记录渠道与目标。
- 缺口说明:尚未形成客户侧下载成功率样本统计
- 后续建议:在具备有效电子票文件地址的样本下,统计查询、下载、推送三类动作成功率,并区分“无权限”“无文件”“非成功终态”等拦截原因
- 建议统计口径:以具备有效
SUCCESS + fileUrl 条件的样本作为成功率分母,同时单独记录被权限校验、文件缺失、非成功终态拦截的请求量;建议分别输出“客户查询成功率”“下载成功率”“推送成功率”三个子指标,避免把前置拦截与真实下载失败混为一类
SC-005 操作日志完整率 100%(所有关键操作均有日志)
- 当前状态:实现态证据已补齐,运行态样本待抽查
- 现有证据:
InvoiceServiceImpl 已通过统一 recordInvoiceOperatLog 入口写入关键动作日志,并由 OperatLogService.createOperatLog 承接操作人、客户标识与日志内容上下文
- 关键动作 ↔ 日志写入点矩阵:
| 关键动作 |
业务入口 |
日志写入点 |
说明 |
| 发票申请 / 提交 SYS-008 开票申请 |
applyInvoice |
recordInvoiceOperatLog(invoice, "提交SYS-008开票申请...") |
记录申请受理与受理号 |
| 后台查询结果 |
queryInvoice → refreshQueryContext |
recordInvoiceOperatLog(invoice, "发票查询补偿,来源:...") |
普通查询与补偿查询复用同一留痕点,依赖 querySource 区分 |
| 结果回写 |
writeBackInvoice |
recordInvoiceOperatLog(invoice, "回写发票结果...") |
成功/失败终态更新后统一留痕 |
| 成功终态保护 |
writeBackInvoice |
recordInvoiceOperatLog(invoice, "收到回写结果但因成功终态保护未覆盖原状态...") |
记录保护分支未覆盖原状态的原因 |
| 客户侧查询 |
queryCustomerInvoice → refreshCustomerQueryContext |
recordInvoiceOperatLog(invoice, "发票查询补偿,来源:CUSTOMER_QUERY...") |
记录客户侧查询动作 |
| 客户侧下载 |
downloadInvoice |
recordInvoiceOperatLog(invoice, "客户侧下载电子发票") |
记录电子发票下载动作 |
| 客户侧推送 |
pushInvoice |
recordInvoiceOperatLog(invoice, "客户侧推送电子发票...") |
记录推送渠道与目标 |
| 后台作废 |
invalidateInvoice |
recordInvoiceOperatLog(invoice, buildPostProcessLog(...)) |
记录原因、备注与原票代码/号码 |
| 后台红冲 |
redInkInvoice |
recordInvoiceOperatLog(invoice, buildPostProcessLog(...)) |
记录原因、备注与原票代码/号码 |
- 缺口说明:尚未在测试或联调环境按上述矩阵逐项抽取实际日志样本,当前仍缺运行态日志记录证据
- DDL/迁移跟进结论:已交叉核查
backend/sql、Archive 数据库设计、sql/lhc_数据库设计.md 与 BACKEND_TABLE_MAPPING.md;当前仍未定位到与 InvoiceDO 最新字段完全一致的 biz_invoice 物理 DDL / migration 脚本,现有同名历史对象更偏开票配置表,US4 的物理落库链路仍需继续结合实际数据库变更记录确认。
- 后续建议:按矩阵至少抽取申请、补偿查询、结果回写、客户下载、客户推送、作废、红冲各 1 条日志样本,核对操作人、客户、状态与日志内容是否一致
待补样本记录模板(不含实际结果)
T060 / SC-001 响应时延记录模板
| 采样时间 |
环境 |
接口 |
样本量 |
平均值(ms) |
P95(ms) |
最大值(ms) |
是否剔除 SYS-008 等待 |
异常样本说明 |
| 待补 |
待补 |
/business/invoice/apply |
待补 |
待补 |
待补 |
待补 |
是 / 否(待补) |
待补 |
- 待补说明:采样时需同步记录请求体摘要(账单数、开票类型、客户类型)与测试环境配置,避免不同批次结果不可比。
T061 / SC-002 申请通过率记录模板
| 样本分组 |
样本总数 |
成功数 |
失败数 |
失败原因分类 |
统计口径说明 |
| 正常业务场景 |
待补 |
待补 |
待补 |
待补 |
仅统计应当成功的申请样本 |
| 规则拦截场景 |
待补 |
待补 |
待补 |
待补 |
单独记录,不计入 SC-002 分母 |
- 待补说明:建议至少覆盖正常账单、已开票账单、未缴费账单、限额超限账单、幂等命中、原始单账单直接部分开票拦截等样本。
T062 / SC-003 回写成功率记录模板
| 回写批次 |
回写请求总量 |
业务成功落账量 |
业务失败量 |
成功终态保护量 |
失败原因分类 |
追溯主键 |
| 待补 |
待补 |
待补 |
待补 |
待补 |
待补 |
applicationNo / sysRequestNo(待补) |
- 待补说明:失败原因建议至少区分外部返回失败、查询超时、账单联动异常、数据缺失;同一批次需保留申请单号与受理号映射关系。
T063 / SC-004 客户侧查询/下载/推送成功率记录模板
| 动作类型 |
样本总数 |
成功数 |
失败数 |
前置拦截数 |
失败/拦截原因分类 |
统计口径说明 |
| 客户查询 |
待补 |
待补 |
待补 |
待补 |
待补 |
仅统计客户侧查询动作 |
| 发票下载 |
待补 |
待补 |
待补 |
待补 |
待补 |
分母建议取具备 SUCCESS + fileUrl 条件的样本 |
| 发票推送 |
待补 |
待补 |
待补 |
待补 |
待补 |
单列推送渠道与目标类型 |
- 待补说明:需区分“无权限”“无文件”“非成功终态”等前置拦截,不建议与真实下载/推送失败混算。
T055 / SC-005 运行态日志抽样模板
| 动作类型 |
样本来源 |
操作人/客户 |
状态前后值 |
日志摘要 |
结果 |
| 发票申请 |
待补 |
待补 |
待补 |
待补 |
待补 |
| 查询补偿 |
待补 |
待补 |
待补 |
待补 |
待补 |
| 结果回写 |
待补 |
待补 |
待补 |
待补 |
待补 |
| 客户下载 |
待补 |
待补 |
待补 |
待补 |
待补 |
| 客户推送 |
待补 |
待补 |
待补 |
待补 |
待补 |
| 后台作废 |
待补 |
待补 |
待补 |
待补 |
待补 |
| 后台红冲 |
待补 |
待补 |
待补 |
待补 |
待补 |
- 待补说明:样本抽取时需能回扣到
recordInvoiceOperatLog / OperatLogService.createOperatLog 的实现态矩阵,并保留查询来源、渠道、原票代码/号码等关键上下文。
- DDL 跟进说明:与日志样本同步收口时,还需补记本轮核查结论:当前仓库仍未定位到与
InvoiceDO 当前模型完全对齐的 biz_invoice 物理 DDL / migration 来源;若联调环境已完成数据库变更,应同时记录变更单号、脚本路径或 DBA 提供的物理表结构证明。
待补样本执行入口清单
| 对应待办 |
接口/合同 |
当前请求路径 |
Controller 入口 |
Service 入口 |
说明 |
T060 / T061 |
IF-REV-008 |
/business/invoice/apply |
InvoiceController.applyInvoice |
InvoiceService.applyInvoice / InvoiceServiceImpl.applyInvoice |
用于申请时延采样与正常/拦截样本统计 |
T062 |
IF-REV-009 |
/business/invoice/query、/business/invoice/query/compensate、/business/invoice/write-back |
InvoiceController.queryInvoice、compensateQueryInvoice、writeBackInvoice |
InvoiceService.queryInvoice、writeBackInvoice / InvoiceServiceImpl.queryInvoice、writeBackInvoice |
用于查询补偿、回写成功率与成功终态保护样本 |
T063 |
IF-CS-004 |
/business/invoice/customer/query、/business/invoice/customer/download、/business/invoice/customer/push |
InvoiceController.queryCustomerInvoice、downloadInvoice、pushInvoice |
InvoiceService.queryCustomerInvoice、downloadInvoice、pushInvoice / InvoiceServiceImpl.queryCustomerInvoice、downloadInvoice、pushInvoice |
用于客户查询、下载、推送成功率统计 |
T055 |
IF-REV-008、IF-REV-009、IF-CS-004、IF-EXT-007 |
/business/invoice/apply、/business/invoice/query、/business/invoice/customer/*、/business/invoice/invalidate、/business/invoice/red-ink |
InvoiceController.applyInvoice、queryInvoice、queryCustomerInvoice、downloadInvoice、pushInvoice、invalidateInvoice、redInkInvoice |
InvoiceServiceImpl.applyInvoice、queryInvoice、writeBackInvoice、queryCustomerInvoice、downloadInvoice、pushInvoice、invalidateInvoice、redInkInvoice |
用于运行态日志抽样与动作-日志矩阵回扣 |
- 执行说明:当前仓库正式文档与 backend
InvoiceController 的实现入口统一使用 /business/invoice/* 路径;若后续联调环境存在网关前缀或转发规则,应在样本记录中额外注明映射关系。
- 本地验证入口排查结论:当前仓库
quickstart.md 未提供可直接复用的 curl / Postman / HTTP 脚本来采集 T055、T060 ~ T063 的真实样本;现阶段可直接依赖的入口主要是接口设计、InvoiceController 路径声明与 InvoiceService(Impl) 调用链,真实样本仍需在可用测试或联调环境手工执行并回填。
最小请求模板(待联调填真实值)
- 用途说明:以下 JSON 仅作为
T055、T060 ~ T063 的最小请求体草稿,用于后续在测试或联调环境手工发起请求并回填真实样本。
- 填写约束:示例中的
applicationNo、sysRequestNo、invoiceId、chargeIds、custId 等值均为占位符,执行前必须替换为环境中的真实数据。
/business/invoice/apply
{
"chargeIds": [10001],
"custId": 1024,
"invoiceType": "ELECTRONIC",
"invoiceTitle": "福建水务测试客户",
"sourceChannel": "COUNTER"
}
- 最小必填字段来源:
chargeIds、custId、invoiceType、invoiceTitle、sourceChannel
- 可选补充字段:
applicationNo(幂等单号)、taxNo、email、mobile、remark
/business/invoice/query
{
"applicationNo": "APP-REV005-001",
"querySource": "MANUAL"
}
- 最小必填字段来源:
querySource
- 定位建议:
applicationNo、sysRequestNo 二选一至少补一个真实定位键,避免联调时无法唯一定位申请记录
/business/invoice/query/compensate
{
"applicationNo": "APP-REV005-001",
"querySource": "AUTO_COMPENSATE"
}
- 最小必填字段来源:
querySource
- 说明:controller 会按补偿查询语义覆盖
querySource,但请求体仍建议显式传入 AUTO_COMPENSATE
/business/invoice/write-back
{
"applicationNo": "APP-REV005-001",
"invoiceStatus": "SUCCESS"
}
- 最小必填字段来源:
invoiceStatus
- 定位建议:
applicationNo、sysRequestNo 二选一至少补一个真实定位键;若为成功样本,建议同步补 invoiceCode、invoiceNumber、fileUrl
/business/invoice/customer/query
{
"custId": 1024,
"invoiceId": 2048
}
- 最小 Bean Validation 字段:
custId
- 定位建议:联调时应至少补
applicationNo、sysRequestNo、invoiceId 之一;上例默认使用 invoiceId 作为定位键
/business/invoice/customer/download
{
"custId": 1024,
"invoiceId": 2048
}
- 最小 Bean Validation 字段:
custId
- 定位建议:与客户查询一致,联调时应至少补
applicationNo、sysRequestNo、invoiceId 之一
/business/invoice/customer/push
{
"custId": 1024,
"invoiceId": 2048,
"pushChannel": "EMAIL",
"pushEmail": "test@example.com"
}
- 最小必填字段来源:
custId、invoiceId、pushChannel
- 渠道补充说明:
pushChannel=EMAIL 时建议同时补 pushEmail;pushChannel=SMS 时建议同时补 pushMobile
/business/invoice/invalidate
{
"invoiceId": 2048,
"invalidReason": "测试作废样本"
}
- 最小必填字段来源:
invoiceId、invalidReason
- 可选补充字段:
invalidRemark、originalInvoiceCode、originalInvoiceNumber
/business/invoice/red-ink
{
"invoiceId": 2048,
"redInkReason": "测试红冲样本"
}
- 最小必填字段来源:
invoiceId、redInkReason
- 可选补充字段:
redInkRemark、originalInvoiceCode、originalInvoiceNumber
执行命令草稿与样本采集顺序
- 使用原则:以下命令仅作为测试或联调环境的执行草稿,不包含真实环境地址、鉴权信息与业务主键;执行前需替换
${BASE_URL}、${TOKEN}、${APPLICATION_NO}、${SYS_REQUEST_NO}、${INVOICE_ID}、${CUST_ID}、${CHARGE_ID} 等占位符。
- 结果约束:命令执行后的真实响应、日志截图、统计数值不得预填,需在拿到实际结果后回填到本文件对应模板。
通用命令头草稿
curl -X POST "${BASE_URL}/business/invoice/apply" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"chargeIds":[${CHARGE_ID}],"custId":${CUST_ID},"invoiceType":"ELECTRONIC","invoiceTitle":"福建水务测试客户","sourceChannel":"COUNTER"}'
- 说明:若联调环境存在网关前缀、灰度路由、租户头或其他鉴权头,应在执行记录中一并注明。
T060 / T061:申请时延与通过率采样顺序
- 使用正常账单样本执行
/business/invoice/apply,记录请求时间、响应时间、applicationNo 与是否命中正常受理。
- 复用同一命令替换不同样本,分别覆盖已开票、未缴费、限额超限、幂等命中、原始单账单直接部分开票等场景。
- 将正常业务场景样本汇总到
T061 / SC-002 表,将规则拦截场景单独归类,不计入 SC-002 分母。
curl -X POST "${BASE_URL}/business/invoice/apply" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"chargeIds":[${CHARGE_ID}],"custId":${CUST_ID},"invoiceType":"ELECTRONIC","invoiceTitle":"福建水务测试客户","sourceChannel":"COUNTER"}'
T062:回写成功率采样顺序
- 先对已申请样本执行
/business/invoice/query,确认当前状态与 sysRequestNo。
- 对已拿到税控结果的样本执行
/business/invoice/write-back,分别覆盖成功回写、失败回写、成功终态保护三类场景。
- 若存在查询兜底场景,再执行
/business/invoice/query/compensate,补录补偿查询命中情况与失败分类。
curl -X POST "${BASE_URL}/business/invoice/query" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"applicationNo":"${APPLICATION_NO}","querySource":"MANUAL"}'
curl -X POST "${BASE_URL}/business/invoice/write-back" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"applicationNo":"${APPLICATION_NO}","invoiceStatus":"SUCCESS"}'
curl -X POST "${BASE_URL}/business/invoice/query/compensate" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"applicationNo":"${APPLICATION_NO}","querySource":"AUTO_COMPENSATE"}'
T063:客户侧查询 / 下载 / 推送采样顺序
- 先执行
/business/invoice/customer/query,确认客户归属与发票定位键可用。
- 对满足
SUCCESS + fileUrl 的样本执行 /business/invoice/customer/download。
- 在同一批样本上继续执行
/business/invoice/customer/push,按 EMAIL、SMS 等渠道分别统计。
curl -X POST "${BASE_URL}/business/invoice/customer/query" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"custId":${CUST_ID},"invoiceId":${INVOICE_ID}}'
curl -X POST "${BASE_URL}/business/invoice/customer/download" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"custId":${CUST_ID},"invoiceId":${INVOICE_ID}}'
curl -X POST "${BASE_URL}/business/invoice/customer/push" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"custId":${CUST_ID},"invoiceId":${INVOICE_ID},"pushChannel":"EMAIL","pushEmail":"test@example.com"}'
T055:运行态日志抽样顺序
- 任选一组完整样本,按“申请 → 查询/补偿 → 回写 → 客户查询/下载/推送 → 作废或红冲”顺序执行。
- 每执行一步立即在日志系统或数据库中抽取对应操作日志,核对操作人、客户标识、状态前后值与日志摘要。
- 作废与红冲建议分别至少准备 1 条独立成功样本,避免同一张票重复处理导致统计混淆。
curl -X POST "${BASE_URL}/business/invoice/invalidate" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"invoiceId":${INVOICE_ID},"invalidReason":"测试作废样本"}'
curl -X POST "${BASE_URL}/business/invoice/red-ink" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"invoiceId":${INVOICE_ID},"redInkReason":"测试红冲样本"}'
- 日志抽样补充要求:若运行态日志需经 Kibana、数据库表或应用日志文件检索取得,应在样本记录中额外注明检索入口、检索条件与截图/导出附件位置。
当天联调最小执行卡片
适用场景:当天已经拿到可用环境、鉴权信息和最小样本,目标不是重新梳理设计,而是直接补 T060、T061、T062、T063、T055 的真实证据。
开始前只确认 6 件事
| 检查项 |
最低要求 |
BASE_URL |
已确认实际网关地址和前缀 |
TOKEN |
已确认可访问 /business/invoice/* 的鉴权信息 |
| 正常申请样本 |
至少 1 组可成功申请的 custId + chargeIds |
| 规则拦截样本 |
至少 2 组,如未缴费、已开票、限额超限或重复申请 |
| 成功发票样本 |
至少 1 组能进入 SUCCESS + fileUrl |
| 日志入口 |
已确认日志查询入口或数据库检索方式 |
当天最小执行顺序
| 顺序 |
动作 |
目标待办 |
最少产出 |
| 1 |
执行 /business/invoice/apply 正常样本和拦截样本 |
T060、T061 |
响应时间、applicationNo、成功/拦截分类 |
| 2 |
对成功申请样本执行 /business/invoice/query |
T062 |
sysRequestNo、当前状态、查询结果 |
| 3 |
执行 /business/invoice/write-back,至少覆盖 SUCCESS 和 1 类失败 |
T062 |
回写结果、失败分类、是否命中成功终态保护 |
| 4 |
对兜底样本执行 /business/invoice/query/compensate |
T062 |
补偿查询结果 |
| 5 |
对 SUCCESS + fileUrl 样本执行客户侧查询/下载/推送 |
T063 |
查询结果、下载结果、推送结果 |
| 6 |
对成功样本执行作废或红冲,并立即抽取日志 |
T055 |
后处理结果、状态前后值、日志样本 |
当天必须回填的 5 个位置
| 待办 |
回填位置 |
最低回填要求 |
T060 |
SC-001 响应时延表 |
样本量、平均值、P95、最大值 |
T061 |
SC-002 申请通过率表 |
正常样本与拦截样本分组统计 |
T062 |
SC-003 回写成功率表 |
成功量、失败量、失败分类、保护量 |
T063 |
SC-004 客户侧消费表 |
查询/下载/推送三类统计 |
T055 |
SC-005 日志抽样表 |
至少 1 条关键动作日志样本 |
当天结束前的收口判断
- 若已拿到真实样本,但还没回填正式表格:不要关闭
tasks.md 中对应待办。
- 若已回填表格,但没有请求报文、响应报文或日志截图:仍视为证据不完整。
- 只有“样本已拿到 + 表格已回填 + 附件已留存”同时满足,才建议勾掉对应任务。
当天可直接复制的变量模板
export BASE_URL="https://your-host"
export TOKEN="replace-with-real-token"
export CUST_ID="1024"
export CHARGE_ID="10001"
export INVOICE_ID="2048"
export APPLICATION_NO="APP-REV005-001"
export SYS_REQUEST_NO="SYS008-APP-REV005-001"
export PUSH_EMAIL="test@example.com"
export PUSH_MOBILE="13800000000"
当天可直接复制的最小命令组
# 1. 申请
curl -X POST "${BASE_URL}/business/invoice/apply" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"chargeIds\":[${CHARGE_ID}],\"custId\":${CUST_ID},\"invoiceType\":\"ELECTRONIC\",\"invoiceTitle\":\"福建水务测试客户\",\"sourceChannel\":\"COUNTER\"}"
# 2. 查询
curl -X POST "${BASE_URL}/business/invoice/query" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"applicationNo\":\"${APPLICATION_NO}\",\"querySource\":\"MANUAL\"}"
# 3. 回写成功
curl -X POST "${BASE_URL}/business/invoice/write-back" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"applicationNo\":\"${APPLICATION_NO}\",\"sysRequestNo\":\"${SYS_REQUEST_NO}\",\"invoiceStatus\":\"SUCCESS\",\"invoiceCode\":\"FPDM001\",\"invoiceNumber\":\"FPHM001\",\"fileUrl\":\"https://example.com/invoice.pdf\"}"
# 4. 补偿查询
curl -X POST "${BASE_URL}/business/invoice/query/compensate" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"applicationNo\":\"${APPLICATION_NO}\",\"querySource\":\"AUTO_COMPENSATE\"}"
# 5. 客户侧查询 / 下载 / 推送
curl -X POST "${BASE_URL}/business/invoice/customer/query" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"custId\":${CUST_ID},\"invoiceId\":${INVOICE_ID}}"
curl -X POST "${BASE_URL}/business/invoice/customer/download" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"custId\":${CUST_ID},\"invoiceId\":${INVOICE_ID}}"
curl -X POST "${BASE_URL}/business/invoice/customer/push" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"custId\":${CUST_ID},\"invoiceId\":${INVOICE_ID},\"pushChannel\":\"EMAIL\",\"pushEmail\":\"${PUSH_EMAIL}\"}"
# 6. 作废 / 红冲
curl -X POST "${BASE_URL}/business/invoice/invalidate" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"invoiceId\":${INVOICE_ID},\"invalidReason\":\"测试作废样本\"}"
curl -X POST "${BASE_URL}/business/invoice/red-ink" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"invoiceId\":${INVOICE_ID},\"redInkReason\":\"测试红冲样本\"}"
单日执行记录表
| 时间 |
执行动作 |
样本主键 |
响应摘要 |
日志是否已取到 |
已回填位置 |
| 待补 |
apply |
applicationNo / chargeId |
待补 |
待补 |
T060/T061 |
| 待补 |
query |
applicationNo / sysRequestNo |
待补 |
待补 |
T062 |
| 待补 |
write-back |
applicationNo / sysRequestNo |
待补 |
待补 |
T062 |
| 待补 |
compensate |
applicationNo / sysRequestNo |
待补 |
待补 |
T062 |
| 待补 |
customer query |
invoiceId / custId |
待补 |
待补 |
T063 |
| 待补 |
download |
invoiceId / custId |
待补 |
待补 |
T063 |
| 待补 |
push |
invoiceId / custId |
待补 |
待补 |
T063 |
| 待补 |
invalidate / red-ink |
invoiceId |
待补 |
待补 |
T055 |
联调补录清单(按顺序执行)
| 步骤 |
对应待办 |
执行动作 |
主要输入 |
预期产出 |
回填位置 |
| 1 |
T060、T061 |
准备正常样本与规则拦截样本,执行 /business/invoice/apply |
BASE_URL、鉴权头、custId、chargeIds、账单分组清单 |
响应报文、耗时、applicationNo、成功/拦截结论 |
T060 / SC-001、T061 / SC-002 模板 |
| 2 |
T062 |
对步骤 1 成功样本执行 /business/invoice/query,确认当前状态与 sysRequestNo |
applicationNo 或 sysRequestNo |
查询结果、受理号、当前状态 |
T062 / SC-003 模板 |
| 3 |
T062 |
执行 /business/invoice/write-back,覆盖成功、失败、成功终态保护样本 |
applicationNo / sysRequestNo、invoiceStatus |
回写结果、失败分类、成功终态保护命中情况 |
T062 / SC-003 模板 |
| 4 |
T062 |
对兜底样本执行 /business/invoice/query/compensate |
applicationNo / sysRequestNo |
补偿查询结果、失败分类、补偿是否命中 |
T062 / SC-003 模板 |
| 5 |
T063 |
执行 /business/invoice/customer/query,确认客户归属与发票定位键有效 |
custId、invoiceId / applicationNo / sysRequestNo |
查询结果、客户归属校验结论 |
T063 / SC-004 模板 |
| 6 |
T063 |
对 SUCCESS + fileUrl 样本执行 /business/invoice/customer/download |
custId、invoiceId |
下载结果、前置拦截/真实失败分类 |
T063 / SC-004 模板 |
| 7 |
T063 |
对同批样本执行 /business/invoice/customer/push,按渠道分别采样 |
custId、invoiceId、pushChannel |
推送结果、渠道分类、失败原因 |
T063 / SC-004 模板 |
| 8 |
T055 |
基于已成功样本执行 /business/invoice/invalidate 与 /business/invoice/red-ink |
invoiceId、作废/红冲原因 |
后处理结果、日志抽样、状态前后值 |
T055 / SC-005 模板 |
| 9 |
T055 |
从日志系统、数据库表或应用日志文件提取关键动作留痕 |
检索入口、检索条件、时间窗口 |
日志截图/导出件、操作人/客户/状态核对结果 |
T055 / SC-005 模板 |
- 执行顺序约束:步骤 2 ~ 4 依赖步骤 1 至少生成一批成功申请样本;步骤 6 ~ 8 依赖样本已达到
SUCCESS 且可定位到目标发票。
- 补录原则:每完成一步就即时回填对应表格,不要等全部联调结束后再集中补录,避免申请单号、受理号、日志检索条件丢失。
- 证据留存建议:除表格外,建议同时保留请求报文、响应报文、日志截图和必要的数据库查询结果,统一按
applicationNo 或 sysRequestNo 归档。
联调日报 / 回填模板
日报头模板
| 字段 |
填写说明 |
| 联调日期 |
填写当天日期 |
| 联调环境 |
如 SIT / UAT / 联调环境名称 |
| 执行人 |
填写执行人 |
| 服务版本 |
填写分支、构建号或部署批次 |
| 网关地址 |
填写实际调用入口,若有前置网关前缀需写明 |
| 鉴权方式 |
如 Bearer Token、租户头、会话信息 |
| 样本范围 |
填写当日使用的账单、客户、发票样本范围 |
当日执行摘要模板
| 对应待办 |
是否执行 |
样本量 |
成功样本 |
失败/拦截样本 |
产出附件 |
T060 / SC-001 响应时延 |
待补 |
待补 |
待补 |
待补 |
待补 |
T061 / SC-002 申请通过率 |
待补 |
待补 |
待补 |
待补 |
待补 |
T062 / SC-003 回写成功率 |
待补 |
待补 |
待补 |
待补 |
待补 |
T063 / SC-004 客户侧消费成功率 |
待补 |
待补 |
待补 |
待补 |
待补 |
T055 / SC-005 日志抽样 |
待补 |
待补 |
待补 |
待补 |
待补 |
样本回填索引模板
| 样本标识 |
applicationNo |
sysRequestNo |
invoiceId |
对应步骤 |
回填表格位置 |
备注 |
| 样本 A |
待补 |
待补 |
待补 |
步骤 1 ~ 9(按实际填写) |
T060/T061/T062/T063/T055(按实际填写) |
待补 |
| 样本 B |
待补 |
待补 |
待补 |
待补 |
待补 |
待补 |
风险与阻塞模板
| 分类 |
现象 |
影响待办 |
临时处理 |
后续动作 |
| 环境 |
待补 |
待补 |
待补 |
待补 |
| 数据 |
待补 |
待补 |
待补 |
待补 |
| 接口 |
待补 |
待补 |
待补 |
待补 |
| 日志 |
待补 |
待补 |
待补 |
待补 |
当日结论模板
联调前置检查清单
| 检查项 |
核对内容 |
当前状态 |
| 环境地址 |
已确认 ${BASE_URL}、网关前缀、服务版本与部署批次 |
待补 |
| 鉴权信息 |
已确认 Bearer Token、租户头、会话信息或其他鉴权方式 |
待补 |
| 样本数据 |
已准备正常样本、规则拦截样本、成功发票样本、作废样本、红冲样本 |
待补 |
| 主键映射 |
已确认 custId、chargeIds、applicationNo、sysRequestNo、invoiceId 的映射关系 |
待补 |
| 日志入口 |
已确认 Kibana、数据库表或应用日志文件的检索入口 |
待补 |
| 回填责任 |
已确认谁负责日报填写、谁负责正式表格回填、谁负责附件归档 |
待补 |
| 归档路径 |
已确认请求报文、响应报文、截图与日志附件的归档位置 |
待补 |
- 执行要求:未完成上述检查前,不建议直接开始批量联调,避免后续出现样本无法回溯、日志无法检索或统计口径不一致的问题。
- 建议时点:每轮联调开始前先更新本清单;若环境、样本或鉴权方式发生变化,应重新复核并更新时间。
最终联调执行顺序与完成判定清单
| 顺序 |
对应待办 |
完成标志 |
可勾选条件 |
| 1 |
T060 |
已形成一批申请时延样本 |
已记录 /business/invoice/apply 的样本量、平均值、P95、最大值,并注明是否剔除 SYS-008 等待 |
| 2 |
T061 |
已形成正常场景与拦截场景分组统计 |
已区分正常业务场景与规则拦截场景,且正常场景成功/失败统计可追溯到样本主键 |
| 3 |
T062 |
已形成查询、回写、补偿查询三类结果统计 |
已记录回写请求总量、业务成功落账量、业务失败量、成功终态保护量,并保留失败分类 |
| 4 |
T063 |
已形成客户查询、下载、推送三类统计 |
已分别记录查询、下载、推送样本量、成功数、失败/前置拦截分类,并保留渠道与定位键 |
| 5 |
T055 |
已形成关键动作日志样本 |
已抽取申请、查询/补偿、回写、客户下载、客户推送、作废、红冲至少各 1 条日志样本,并能回扣动作矩阵 |
建议最终执行顺序
- 先完成
T060,确保申请入口、环境耗时与基础样本可用。
- 再完成
T061,把同批申请样本分成“正常业务场景 / 规则拦截场景”两组。
- 基于成功申请样本推进
T062,补齐查询、回写与补偿查询链路统计。
- 仅在样本达到
SUCCESS + fileUrl 后推进 T063,避免把前置条件不满足的样本误计为下载失败。
- 最后完成
T055,对上述链路中已成功执行的样本逐项抽取日志,形成最终运行态留痕证据。
单项完成判定模板
| 待办 |
是否已拿到真实样本 |
是否已回填正式表格 |
是否已留存附件 |
是否满足勾选条件 |
备注 |
T060 |
待补 |
待补 |
待补 |
待补 |
待补 |
T061 |
待补 |
待补 |
待补 |
待补 |
待补 |
T062 |
待补 |
待补 |
待补 |
待补 |
待补 |
T063 |
待补 |
待补 |
待补 |
待补 |
待补 |
T055 |
待补 |
待补 |
待补 |
待补 |
待补 |
- 勾选原则:只有当“真实样本已拿到 + 正式统计表已回填 + 附件已留存”三项同时满足时,对应待办才建议从
tasks.md 标记为完成。
- 收口顺序:建议按
T060 → T061 → T062 → T063 → T055 顺序逐项关闭,避免后置任务缺少前置样本支撑。
剩余工作摘要(可直接引用)
- 当前状态:REV-005 已完成 US1 ~ US4 的实现态闭环与文档侧验证准备,当前处于
Verification Pending,剩余工作全部集中在 T055、T060 ~ T063 的真实联调取证与结果回填。
- 剩余待办:
T060:补 /business/invoice/apply 的真实响应时延样本与统计结果。
T061:补正常业务场景与规则拦截场景的申请通过率统计。
T062:补查询、回写、补偿查询链路的成功率与失败分类统计。
T063:补客户查询、下载、推送三类动作的成功率与前置拦截分类。
T055:补申请、查询/补偿、回写、客户下载/推送、作废、红冲的运行态日志样本。
- 完成条件:上述待办均需满足“真实样本已拿到、正式统计表已回填、附件已留存”三项条件后,方可在
tasks.md 中关闭。
- 建议对外口径:REV-005 当前已具备提测前文档与验证准备条件,剩余工作不在于设计或实现补充,而在于测试/联调环境下补齐运行态统计与日志证据。
4. US4 二期实现结论
当前已在以下正式文档与实现文件中明确:
docs/design/02_Detailed_Design/12_REV_Detailed.md
docs/design/03_Technical_Design/03_Interface_Design.md
specs/002-rev005-invoice-flow/spec.md
specs/002-rev005-invoice-flow/plan.md
specs/002-rev005-invoice-flow/tasks.md
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/InvoiceController.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/vo/InvoiceInvalidateReqVO.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/vo/InvoiceRedInkReqVO.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/dal/dataobject/invoice/InvoiceDO.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/invoice/InvoiceService.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/invoice/InvoiceServiceImpl.java
当前结论如下:
- 发票作废、红冲仍由
SYS-008 统一承接税控侧处理。
SYS-002 已补齐后台作废 /business/invoice/invalidate 与红冲 /business/invoice/red-ink 入口,并通过专门请求 VO 承接原因、备注与原发票代码/号码。
- 当前实现仅允许对
SUCCESS 发票发起作废或红冲;若传入 originalInvoiceCode、originalInvoiceNumber,必须与当前发票记录一致,重复处理会被拦截。
InvoiceDO 与 01_Database_Design.md 已补齐作废原因/备注、红冲原因/备注、原发票代码/号码与 postProcessSource 等承接口径;service 会同步写入 latestResult、latestError、账单关联状态与操作日志。
- 当前剩余风险主要集中在物理表结构/DDL 来源未在仓库内定位、批量作废/红冲能力未覆盖,以及缺少端到端联调样本。
5. 当前已完成文件
正式文档
docs/design/02_Detailed_Design/12_REV_Detailed.md
docs/design/03_Technical_Design/01_Database_Design.md
docs/design/03_Technical_Design/03_Interface_Design.md
docs/design/00_Management/01_Project_Progress.md
docs/design/00_Management/03_Task_Checklist.md
spec/planning 产物
specs/002-rev005-invoice-flow/spec.md
specs/002-rev005-invoice-flow/plan.md
specs/002-rev005-invoice-flow/research.md
specs/002-rev005-invoice-flow/data-model.md
specs/002-rev005-invoice-flow/contracts/if-rev-008-invoice-application.md
specs/002-rev005-invoice-flow/contracts/if-rev-009-invoice-query.md
specs/002-rev005-invoice-flow/tasks.md
specs/002-rev005-invoice-flow/verification.md
backend 相关实现
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/InvoiceController.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/vo/InvoiceApplyReqVO.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/vo/InvoiceApplyRespVO.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/vo/InvoiceCustomerQueryReqVO.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/vo/InvoiceInvalidateReqVO.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/vo/InvoicePushReqVO.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/vo/InvoiceQueryReqVO.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/vo/InvoiceQueryRespVO.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/vo/InvoiceRedInkReqVO.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/invoice/vo/InvoiceWriteBackReqVO.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/dal/dataobject/invoice/InvoiceDO.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/dal/mysql/invoice/InvoiceMapper.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/invoice/InvoiceService.java
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/invoice/InvoiceServiceImpl.java
6. 剩余风险
SC-001 ~ SC-005 尚缺可重复执行的专项测量脚本或统计记录。
- 当前
make validate-mermaid 输出仅覆盖仓库现有扫描范围,若后续扩展更多图表文件,仍需复核目标文件是否全部纳入。
- 当前仓库内尚未定位到与
backend/sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/dal/dataobject/invoice/InvoiceDO.java 当前模型对应的 biz_invoice 物理 DDL 或迁移脚本;已核查 backend/sql、Archive 数据库设计与 sql/lhc_数据库设计.md,现有同名 biz_invoice 更偏开票配置表,作废/红冲新增字段的物理落库仍需结合实际数据库变更链路确认。
- 作废/红冲当前以单笔后台入口为主,尚未覆盖批量后处理、
SYS-008 端到端联调样本与自动化回归验证。
7. 下一步建议
- 若继续推进一期验收,优先补
SC-001 ~ SC-005 的专项统计与样本口径。
- 若继续推进 US4,优先确认
biz_invoice 物理 DDL/迁移脚本来源,并补批量作废/红冲与联调样本,而不是继续重复扩展已完成的请求对象或数据承接口径。
- 若准备提测或评审,可直接引用本文件作为当前已完成验证、US4 二期实现范围与剩余风险摘要。
8. 当前交付摘要
8.1 已完成交付
- REV-005 的 US1 ~ US4 已完成正式文档、spec/planning 产物与 backend 最小实现闭环,并已补齐最小编译、文档校验、链接校验与 Mermaid 校验证据。
spec.md、tasks.md、verification.md、01_Project_Progress.md、03_Task_Checklist.md 当前已统一到“实现闭环基本完成、量化验收证据待补”的一致状态。
- 当前仓库已明确可直接用于评审/提测前范围说明的结论:正常开票闭环与作废/红冲最小入口已形成正式实现范围,SC-005 实现态日志追溯矩阵已补齐。
8.2 当前未闭环事项
T055、T060、T061、T062、T063 仍未完成,分别对应运行态日志抽样、SC-001 响应时延、SC-002 申请通过率、SC-003 回写成功率、SC-004 客户侧查询/下载/推送成功率等专项统计证据。
biz_invoice 物理 DDL / migration 来源仍未在仓库中定位,US4 的物理落库链路、批量后处理与端到端联调样本仍需继续跟踪。
8.3 建议引用口径
- 若当前需要向评审或提测说明 REV-005 状态,建议统一表述为:REV-005 已完成 US1 ~ US4 的实现态闭环与最小校验,当前处于 Verification Pending,剩余工作主要是补 SC-001 ~ SC-005 的运行态样本与专项统计证据。