.scratch/pending-order-payment-flow/README.md
@@ -190,3 +190,20 @@ - `issues/01-pending-order-deadlock.md`:用户报的死锁(诊断,不是票)。 - `issues/02-store-consume-order-notification.md`:D1(到店消费通知)的移交文档。 - `issues/03-stock-and-create-order-idempotency.md`:审计 §13(库存/销量/下单幂等)的移交文档。 ## 迁移编号让位(2026-09-17) 本轮新增的四个迁移原本取 V148–V151,但远端 `shinnosuke` 的两个提交(`d2d27be`、`38dd07d`)先推送了 `V148__policy_article_top_time`、`V149__clear_service_hero_placeholders`、`V150__merchant_hero_image`: 共同祖先只到 `V147`,双方各自独立占了同一段编号(git 不会报冲突,Flyway 会直接报「同一版本两个迁移」)。 合并时**本地让号**(远端那三个已推送,可能已在别人的环境里跑过),按原有先后顺延: | 原编号 | 现编号 | | --- | --- | | `V148__merchant_capability_sync_until` | `V151` | | `V149__payment_attempt_convergence` | `V152` | | `V150__merchant_numeric_code_attempt` | `V153` | | `V151__order_cancel_request` | `V154` | 两个 `scripts/dev-schema-*.sql` 同步改名,每个迁移文件头也留了让位记录。票面与 issue 里出现的旧编号 按当时的事实保留(历史记录),以后新增迁移请照 `AGENTS.md` 先看当前最大版本号再取。 .scratch/pending-order-payment-flow/plan.md
@@ -5,7 +5,7 @@ **一处修正**:我此前说过「第一刀大概率不需要迁移」,那是只考虑了新增 `status` 取值。C4(对账任务 无轮转)与 Q8(关单重试上限)都需要按行记状态,所以**第一刀需要一次迁移**。当前迁移最大版本是 `V148`,本次取 `V149`,开工前再确认没被他人占用(`AGENTS.md`:迁移编号全仓共享)。 `V148`,本次取 `V149`;实际开工时远端另有提交把 V148–V150 占走,本地让号后落在 `V152`(见 README「编号让位」)。 --- @@ -13,7 +13,7 @@ **目标**:任何入口进的待支付订单都不再卡死——能再付、能取消、能到期。 ### 迁移 `V149` ### 迁移 `V149` → `V152`(编号让位后) `payment_transaction` 加两列(都在 `payment_transaction` 上,不动别人的区域): docs/adr/0003-payment-converges-per-attempt.md
@@ -45,6 +45,6 @@ 真实的收款+退款流水(手续费大概率不退,对账也要处理),换来的是取消立刻生效。这是产品明确选的取舍: 取消是高频操作,「等一分钟」是每次都要付的代价;「收了再退」是极少数情况。 同时把取消意图降级为审计事实:`benefit_order.cancel_requested_at`(V151)只记录用户何时点的取消, 同时把取消意图降级为审计事实:`benefit_order.cancel_requested_at`(V154)只记录用户何时点的取消, **不再驱动任何行为**——它驱动的那个「等关单结论再落地」的对账扫描已经删掉,留它只是为了在 「取消后收到钱」那类偶发路径上把时间对得上。 docs/agents/testing.md
@@ -12,7 +12,7 @@ 三条由此推出的硬约束: - **迁移必须同时兼容 5.7 与 8.0**:测试只在 8.0 上跑,跑绿不代表开发库能执行(`V148` 的存储过程写法 - **迁移必须同时兼容 5.7 与 8.0**:测试只在 8.0 上跑,跑绿不代表开发库能执行(`V151` 的存储过程写法 已在 5.7 上实跑验证过,但每次新增迁移都值得照做一遍)。 - **开发库的结构不由 Flyway 维护**:缺表缺列只能靠启动时的初始化器 best-effort 补,补不上就手工补(见下)。 - 本机 `8134` 实例上另有 `talent_card`、`talent_card_dryrun`、`talent_card_verify1` 三个库:它们是 @@ -79,8 +79,8 @@ 逐条执行 SQL(默认连开发库,可 `-Database/-DatabaseHost/-Port` 覆盖;不带 `-Yes` 只打印不执行)。 它认得 `DELIMITER`,所以 `db/migration/V*.sql` 也能原样重放。默认指向**开发库**,别拿它去改测试库 (测试库由 Flyway 从 `db/migration` 重建,手工 DDL 会让迁移与 history 表对不上)。 开发者首次拿到新列:2026-09-17 的 `V149`(支付流水两列)与 `V150`(手输核销码计数表)就是这样落地的, 对应脚本 `scripts/dev-schema-v149-payment-attempt.sql`(写法可重复执行的那份在迁移里,两者等价)。 开发者首次拿到新列:2026-09-17 的 `V152`(支付流水两列)与 `V153`(手输核销码计数表)就是这样落地的, 对应脚本 `scripts/dev-schema-v152-payment-attempt.sql`(写法可重复执行的那份在迁移里,两者等价)。 - 动结构之前先备份。本机**没有** mysql 客户端、也没有 Docker(README 里指向 `D:\MySQL\...` 和 `docker exec talent-card-mysql-1` 的两条老做法都已失效),要备份就在 DB 主机上做,或照 `scripts/reset-test-db.ps1` 的办法用项目已有的 JDBC 驱动写个单文件程序。 talent-card-server/scripts/apply-sql-file.ps1
@@ -6,8 +6,8 @@ # request that touches it fails with "Unknown column ...". See docs/agents/testing.md. # # Usage: # .\scripts\apply-sql-file.ps1 -File scripts\dev-schema-v149-payment-attempt.sql -Yes # .\scripts\apply-sql-file.ps1 -File src\main\resources\db\migration\V149__payment_attempt_convergence.sql -Yes # .\scripts\apply-sql-file.ps1 -File scripts\dev-schema-v152-payment-attempt.sql -Yes # .\scripts\apply-sql-file.ps1 -File src\main\resources\db\migration\V152__payment_attempt_convergence.sql -Yes # .\scripts\apply-sql-file.ps1 -File <file> # prints the statements without executing # # The target defaults to the shared dev database. It is a shared database, so the script executes talent-card-server/scripts/dev-schema-v152-payment-attempt.sql
File was renamed from talent-card-server/scripts/dev-schema-v149-payment-attempt.sql @@ -1,10 +1,13 @@ -- 开发库(局域网共享的 talent_card,MySQL 5.7,Flyway 关闭)手工补齐 V149 的两列。 -- 开发库(局域网共享的 talent_card,MySQL 5.7,Flyway 关闭)手工补齐支付尝试收敛的两列。 -- -- 编号让位(2026-09-17):这两列对应的迁移原为 V149,因与远端已推送的 V149__clear_service_hero_placeholders -- 撞号,本地让号改为 V152__payment_attempt_convergence.sql;本脚本同步改名。 -- -- 为什么需要这份文件:开发库的结构不由迁移维护,而现有启动初始化器只补商户进件相关的表, -- 不覆盖 payment_transaction。只写迁移会让开发库缺列,对账任务与支付接口直接以 -- Unknown column 500(见 docs/agents/testing.md 记录的同类事故)。 -- -- 与 V149__payment_attempt_convergence.sql 逐列等价,只是不含存储过程(JDBC 无法直接执行 -- 与 V152__payment_attempt_convergence.sql 逐列等价,只是不含存储过程(JDBC 无法直接执行 -- DELIMITER 批处理),所以只能执行一次:重复执行会在「列已存在」上报错,这是安全的失败。 -- -- 执行方式(本机没有 mysql 客户端,用项目已有的 JDBC 驱动): talent-card-server/scripts/dev-schema-v154-order-cancel-request.sql
File was renamed from talent-card-server/scripts/dev-schema-v151-order-cancel-request.sql @@ -1,6 +1,7 @@ -- 编号让位(2026-09-17):这一列对应的迁移原为 V151,同批让号后为 V154__order_cancel_request.sql;本脚本同步改名。 -- 开发库(局域网共享的 talent_card,MySQL 5.7,Flyway 关闭)手工补列。 -- -- 与 V151__order_cancel_request.sql 等价,只是不含存储过程(JDBC 无法直接执行 DELIMITER 批处理), -- 与 V154__order_cancel_request.sql 等价,只是不含存储过程(JDBC 无法直接执行 DELIMITER 批处理), -- 所以只能执行一次:重复执行会在「列已存在」上报错,这是安全的失败。 -- -- 执行方式: talent-card-server/src/main/resources/db/migration/V151__merchant_capability_sync_until.sql
File was renamed from talent-card-server/src/main/resources/db/migration/V148__merchant_capability_sync_until.sql @@ -1,3 +1,4 @@ -- 编号让位(2026-09-17):本文件原为 V148,与远端已推送的 V148__policy_article_top_time 撞号,本地让号改为 V151。 -- 商户端「立即核实」的冷却时间戳:手动核实一次通道查询后,在此时间之前不再重复查询。 -- 不放在 capability_verified_at:查询失败时那一列不推进,会被连点;也不放在 updated_at: -- 那是 MySQL 的 on update current_timestamp,任何无关 UPDATE 都会顺带把它重置。 talent-card-server/src/main/resources/db/migration/V152__payment_attempt_convergence.sql
File was renamed from talent-card-server/src/main/resources/db/migration/V149__payment_attempt_convergence.sql @@ -1,3 +1,4 @@ -- 编号让位(2026-09-17):本文件原为 V149,与远端已推送的 V149__clear_service_hero_placeholders 撞号,本地让号改为 V152。 -- 支付尝试按「这一次尝试」收敛所需要的两列(判定见 docs/adr/0003)。 -- -- last_reconciled_at 对账任务的公平轮转与退避依据。旧实现按「最早 100 条」取未决流水,一旦积压 talent-card-server/src/main/resources/db/migration/V153__merchant_numeric_code_attempt.sql
File was renamed from talent-card-server/src/main/resources/db/migration/V150__merchant_numeric_code_attempt.sql @@ -1,3 +1,4 @@ -- 编号让位(2026-09-17):本文件原为 V150,与远端已推送的 V150__merchant_hero_image 撞号,本地让号改为 V153。 -- 商户端手输 6 位数字核销码的失败计数与锁定。 -- -- 核销码本来就下发一个 6 位数字码给顾客(order_dynamic_verification_code.display_code),但系统里 talent-card-server/src/main/resources/db/migration/V154__order_cancel_request.sql
File was renamed from talent-card-server/src/main/resources/db/migration/V151__order_cancel_request.sql @@ -1,3 +1,4 @@ -- 编号让位(2026-09-17):本文件原为 V151,同批让号后顺延为 V154(远端那两个提交占了 V148–V150)。 -- 「取消意图」要能跨请求活到关单结论回来的那一刻。 -- -- 用户在通道说「关单处理中」时点了取消,服务端当次只能回一句「取消处理中」——真正该取消的时机是