背景 ---- 原 trans_borrow 是单行记录模式,身份维度只有 borrower_name 一个字符串: 「谁借的」与「谁现在还拿着」是同一个字段,无法表达持有权变更;归还时 return_time/return_operator/return_signature 被逐次覆盖,部分归还下 「谁在什么时候还了多少」永久丢失。 本次改动(全部增量,无破坏性 DDL,可回滚) ---- 1) trans_borrow 补列 · borrower_id / current_holder_id / current_holder_name —— 身份锚点 · dispatch_operator —— 执行借出的库管(operator_name 形参此前被接收却从未落库) 2) 新建 trans_borrow_transfer —— 转交流水,一行=一次转交,不做覆盖式更新 3) 新建 trans_borrow_return —— 归还流水,逐次记录,根治部分归还失忆症 4) 历史回填(已执行):85 行中 84 行 borrower_id 唯一命中 sys_user; 未归还的 32 行全部绑定 current_holder 5) 注册 borrow_transfer 权限码(无冒号形式,避免 _expand_operation_perms 前缀桥接把权限放大给所有持有 op_borrow:operation 的角色) 设计取舍 ---- · current_holder 只回填「未归还」行:已归还=物品已回库、无人持有,保持 NULL。 这样「current_holder_id IS NOT NULL」本身就是「仍在某人手上」的有效信号, 归还校验不会对已结清单据误触发。 · 三张表都不建外键:与 trans_return / trans_defective_goods 一致 —— 库存行会被入库模块物理删除(实测已有悬空),台账必须能独立存活。 · dispatch_operator 不回填历史:执行人信息从未被采集,系统中不存在可回填的 数据源;用申请人或借用人冒充实物交接人比留空更危险。 验证:迁移已对 inventory_db 执行,核对段全部通过。
59 lines
2.9 KiB
PL/PgSQL
59 lines
2.9 KiB
PL/PgSQL
-- =============================================================================
|
||
-- 借库转交一期收口:trans_borrow 补 dispatch_operator(发货操作人)
|
||
--
|
||
-- 背景
|
||
-- 责任链上「谁借的 / 谁现在拿着 / 谁还的」在此前改造中已全部锚定到 ID,
|
||
-- 唯独**执行借出的库管操作人**一直没落库 —— execute_dispatch 的
|
||
-- operator_name 形参被接收后从未写入任何字段(首轮调研已标记该缺口)。
|
||
-- 本迁移补齐最后一环,使一次借出在台账上能回答四个问题:
|
||
-- 借用人 borrower_id / 当前持有人 current_holder_id /
|
||
-- 发货操作人 dispatch_operator / 归还人 trans_borrow_return.returner_id
|
||
--
|
||
-- ---------------------------------------------------------------------------
|
||
-- ★ 为什么存「姓名」而不是 ID
|
||
-- execute_dispatch 的 operator_name 由 API 层经 _current_username() 取得,
|
||
-- 本身就是展示口径的字符串(与 trans_borrow_return.operator_name 一致)。
|
||
-- 该字段仅用于台账展示与追溯,不参与任何权限判定或持有人校验,
|
||
-- 故不引入 ID —— 需要精确到人时,审计日志(audit_listener)另有记录。
|
||
--
|
||
-- ★ 为什么不回填历史值
|
||
-- 改造前的执行人信息**从未被采集**,系统中不存在任何可回填的数据源
|
||
-- (trans_borrow 没有对应列,TransBorrow 也没有其它操作人字段)。
|
||
-- 刻意留空而非猜测填充 —— 用申请人或借用人冒充实物交接人,
|
||
-- 比留空更危险。NULL 即表示「本次借出发生在该字段上线之前」。
|
||
--
|
||
-- 幂等:带 IF NOT EXISTS,可重复执行。
|
||
-- 执行:docker exec -i inventory_db psql -U test -d inventory_system < 本文件
|
||
-- =============================================================================
|
||
|
||
BEGIN;
|
||
|
||
ALTER TABLE trans_borrow
|
||
ADD COLUMN IF NOT EXISTS dispatch_operator varchar(100);
|
||
|
||
COMMENT ON COLUMN trans_borrow.dispatch_operator IS
|
||
'执行借出(扫码发货)的库管操作人姓名。仅展示/追溯用,不参与权限判定;'
|
||
'该列上线前的历史记录为 NULL';
|
||
|
||
COMMIT;
|
||
|
||
|
||
-- =============================================================================
|
||
-- 执行后核对
|
||
-- =============================================================================
|
||
\echo '--- 1) 新列已就位 ---'
|
||
SELECT column_name, data_type, character_maximum_length
|
||
FROM information_schema.columns
|
||
WHERE table_name = 'trans_borrow' AND column_name = 'dispatch_operator';
|
||
|
||
\echo '--- 2) 存量行均为 NULL(预期:全部为 NULL,历史数据无从回填)---'
|
||
SELECT count(*) AS total, count(dispatch_operator) AS filled FROM trans_borrow;
|
||
|
||
|
||
-- =============================================================================
|
||
-- 回滚段
|
||
-- =============================================================================
|
||
-- BEGIN;
|
||
-- ALTER TABLE trans_borrow DROP COLUMN IF EXISTS dispatch_operator;
|
||
-- COMMIT;
|