Files
KCGL/db_migrations/phase4c_borrow_transfer_handshake.sql

94 lines
4.5 KiB
MySQL
Raw Normal View History

-- =============================================================================
-- 借库转交 · 双向握手 + 整单覆盖
--
-- 本次解决两个已发生的问题:
-- 1) **单内撕裂**:原 /transfer 收的是**明细行 ID**,只更新那一行。
-- 一张单有 2 条明细时,转交后 108 归属接收人、109 仍是原借用人 ——
-- 前端按 borrow_no 聚合,两个名字同时出现(实测 BOR-20260917-0001)。
-- 修复方向:转交必须按 **borrow_no** 覆盖该单全部未还明细。
-- 2) **单向强塞**:原实现发起即生效,接收人「被通知式」地背上资产责任。
-- 改为双向握手:发起只落 PENDING,接收人 accept 后才真正转移责任。
--
-- ---------------------------------------------------------------------------
-- 1) 为什么新增 borrow_no 而不是复用 borrow_id
-- borrow_id 是**明细行**主键,一条转交要覆盖该单多行,用单行 ID 无法表达
-- 「本次转交覆盖了哪些行」。borrow_no 是单据身份,accept 时据此批量更新。
-- borrow_id 保留为「发起时的代表明细」,供追溯与旧前端兼容。
--
-- 2) 为什么存量行标记为 ACCEPTED
-- 旧语义是「发起即生效」—— 写流水的同时就改了主表 current_holder。
-- 本表现有 1 行(BOR-20260917-0001)已是生效状态,标为 ACCEPTED 才符合
-- 事实;若标 PENDING,接收人会收到一条早已生效的待办。
--
-- 3) 状态机
-- PENDING ──accept──> ACCEPTED (主表 current_holder 正式转移)
-- └────reject──> REJECTED (主表不动,责任仍在原持有人)
-- 同一单号同一时刻只允许一条 PENDING(应用层强制),避免两个接收人
-- 争抢同一批实物。
--
-- 幂等:带 IF NOT EXISTS,可重复执行。
-- 执行:docker exec -i inventory_db psql -U test -d inventory_system < 本文件
-- =============================================================================
BEGIN;
ALTER TABLE trans_borrow_transfer
ADD COLUMN IF NOT EXISTS borrow_no varchar(100),
ADD COLUMN IF NOT EXISTS status varchar(20) NOT NULL DEFAULT 'PENDING';
COMMENT ON COLUMN trans_borrow_transfer.borrow_no IS
'借用单号(单据身份)。一次转交覆盖该单号下全部未还明细,accept 时据此批量更新';
COMMENT ON COLUMN trans_borrow_transfer.status IS
'PENDING 待接收 / ACCEPTED 已接收(主表已转移)/ REJECTED 已拒绝(主表未动)';
COMMENT ON COLUMN trans_borrow_transfer.borrow_id IS
'发起转交时的代表明细ID(trans_borrow.id),仅供追溯;覆盖范围以 borrow_no 为准';
-- 存量行:按旧语义(发起即生效)回填单号并标记为已接收
UPDATE trans_borrow_transfer t
SET borrow_no = tb.borrow_no,
status = 'ACCEPTED'
FROM trans_borrow tb
WHERE t.borrow_id = tb.id
AND t.status = 'PENDING';
CREATE INDEX IF NOT EXISTS ix_trans_borrow_transfer_no
ON trans_borrow_transfer (borrow_no);
CREATE INDEX IF NOT EXISTS ix_trans_borrow_transfer_status
ON trans_borrow_transfer (status);
-- 支撑「待我接收」的可见性与列表查询
CREATE INDEX IF NOT EXISTS ix_trans_borrow_transfer_to_user
ON trans_borrow_transfer (to_user_id, status);
COMMIT;
-- =============================================================================
-- 执行后核对
-- =============================================================================
\echo '--- 1) 新列已就位 ---'
SELECT column_name, data_type, column_default
FROM information_schema.columns
WHERE table_name = 'trans_borrow_transfer'
AND column_name IN ('borrow_no', 'status')
ORDER BY column_name;
\echo '--- 2) 存量行状态(应为 ACCEPTED 且 borrow_no 已回填)---'
SELECT id, borrow_id, borrow_no, status, from_user_name, to_user_name
FROM trans_borrow_transfer ORDER BY id;
\echo '--- 3) 不应存在无单号的流水(应为 0)---'
SELECT count(*) AS 缺单号 FROM trans_borrow_transfer WHERE borrow_no IS NULL;
-- =============================================================================
-- 回滚段
-- =============================================================================
-- BEGIN;
-- DROP INDEX IF EXISTS ix_trans_borrow_transfer_no;
-- DROP INDEX IF EXISTS ix_trans_borrow_transfer_status;
-- DROP INDEX IF EXISTS ix_trans_borrow_transfer_to_user;
-- ALTER TABLE trans_borrow_transfer
-- DROP COLUMN IF EXISTS borrow_no,
-- DROP COLUMN IF EXISTS status;
-- COMMIT;