fix(infra): enforce one open request
新增 V8 部分唯一索引 uq_req_open:(REQ_TYPE, OPERATION_DAY, SENDER) 仅在 PENDING/SENT 唯一;建索引前用 DO 块检测存量重复组并以带业务键的异常中止迁移,禁止静默删数据。保留 idx_req_open 服务含关闭态的查询;不引入运行时协调器(归 US-08)。 验证:全量 ./gradlew test 126 tests / 0 fail;索引与拒绝第二条开放请求的断言在 FlywayMigrationTest(需真实 PG,本机无 Docker 时按既有 assumeTrue 跳过)。
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
-- =====================================================================
|
||||
-- V8:REQ_TRACK 开放态部分唯一约束
|
||||
-- ---------------------------------------------------------------------
|
||||
-- 只动自有 PostgreSQL;共享 MySQL 不建表、不改结构。
|
||||
--
|
||||
-- design「记录模型」:同一 (REQ_TYPE, OPERATION_DAY, SENDER) 只允许一个开放请求,
|
||||
-- 且仅对开放状态(PENDING / SENT)生效。这里只建立数据库防线;「新请求原子过期旧请求
|
||||
-- 并登记自身」的运行时流程仍归 US-08 协调器([G-REQ-TRACK])。
|
||||
--
|
||||
-- 存量若已有重复开放组,不静默删数据:带业务键的诊断直接让迁移失败,由人工处置。
|
||||
-- 保留既有普通索引 idx_req_open(仍服务含关闭态的查询)。
|
||||
-- =====================================================================
|
||||
|
||||
DO $$
|
||||
DECLARE offenders text;
|
||||
BEGIN
|
||||
SELECT string_agg(format('%s/%s/%s', req_type, operation_day, sender), ', ')
|
||||
INTO offenders
|
||||
FROM (
|
||||
SELECT req_type, operation_day, sender
|
||||
FROM req_track
|
||||
WHERE state IN ('PENDING', 'SENT')
|
||||
GROUP BY req_type, operation_day, sender
|
||||
HAVING count(*) > 1
|
||||
LIMIT 20
|
||||
) dup;
|
||||
IF offenders IS NOT NULL THEN
|
||||
RAISE EXCEPTION 'V8 aborted: duplicate open REQ_TRACK rows for (req_type/operation_day/sender): %', offenders;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
CREATE UNIQUE INDEX uq_req_open
|
||||
ON req_track (req_type, operation_day, sender)
|
||||
WHERE state IN ('PENDING', 'SENT');
|
||||
Reference in New Issue
Block a user