背景
----
双向握手补上了「接收人确认」,却只做了单向告知:接收人能看到待办,发起方却
对结果一无所知。**被拒绝时物品责任仍在发起方手上** —— 他若不主动查列表,
就会误以为已经交接出去,责任链出现静默断点。
(ACCEPTED 不需要告知:东西已经交出去了,发起方无需动作。)
改动
----
· trans_borrow_transfer 新增 reject_seen_at(NULL 且 REJECTED = 尚未告知)。
★ 为什么需要持久标记而不是前端去重:换台电脑、换个浏览器就会重新提醒;
而这条信息的分量(责任归属)值得一个持久标记。
★ 存量已拒绝的流水一律标记为已告知:它们产生于本功能上线之前,
追溯提醒只会打扰(实测仅 1 条:#22,验收时的测试数据)。
· get_unseen_rejects(user_id):返回「我发起、被拒、尚未告知我」的转交,
并批量解析物料名 —— 只说「某笔转交被拒」发起方仍不知是哪件东西还在
自己手上,必须让他一眼认出来。
· ack_rejects(user_id, ids):发起方确认后写 reject_seen_at,幂等。
· GET .../transfer/pending-count 的响应并入 rejects:与待接收数量共用同一次
轮询,前端不必多打一个请求。
· POST .../transfer/reject-ack:无 permission_required,同 accept/reject。
顺带补一处同源显示缺口
----
流转时间线里,被拒绝的转交与成功的长得一模一样 —— 发起方翻记录时同样会
误判。现将转交状态一并带出时间线事件。
验证(15 项断言全通过)
----
发起方收到待告知的拒绝(含物料名/接收人/拒绝原因);接收人与无关人看不到;
ack 后不再提醒且幂等;ACCEPTED 不产生告知;None/非法 user_id 均安全返回;
库存零副作用、数据零残留。
76 lines
3.4 KiB
PL/PgSQL
76 lines
3.4 KiB
PL/PgSQL
-- =============================================================================
|
||
-- 借库转交 · 拒收须告知发起方
|
||
--
|
||
-- 背景
|
||
-- 双向握手补上了「接收人确认」这一环,但只做了单向告知:接收人能看到待办,
|
||
-- 发起方却对结果一无所知 —— 尤其是**被拒绝**时,物品责任仍在发起方手上,
|
||
-- 他若不查列表就会误以为已经交接出去,责任链出现静默断点。
|
||
--
|
||
-- ---------------------------------------------------------------------------
|
||
-- 为什么需要 reject_seen_at 这一列
|
||
-- ACCEPTED 不需要告知(东西已经交出去了,发起方无需动作);
|
||
-- REJECTED 必须告知,且**必须能标记「已告知」** —— 否则发起方每次登录
|
||
-- 都会收到同一条提醒,从「提醒」退化成「骚扰」。
|
||
--
|
||
-- 不宜用前端 sessionStorage 去重:换台电脑、换个浏览器就会重新提醒,
|
||
-- 而这条信息的分量(责任归属)值得一个持久标记。
|
||
--
|
||
-- 语义
|
||
-- reject_seen_at IS NULL 且 status='REJECTED' → 尚未告知发起方
|
||
-- 发起方在前端看到提醒并确认后,写当前时间
|
||
--
|
||
-- ★ 存量已拒绝的流水一律标记为「已告知」
|
||
-- 它们产生于本功能上线之前,追溯提醒只会打扰(实测仅 1 条:
|
||
-- #22 测试 → 小龙虾,是验收时的测试数据)。新产生的拒绝才会触发提醒。
|
||
--
|
||
-- 幂等:带 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 reject_seen_at timestamp without time zone;
|
||
|
||
COMMENT ON COLUMN trans_borrow_transfer.reject_seen_at IS
|
||
'发起方看到「被拒绝」提醒并确认的时间。NULL 且 status=REJECTED 表示尚未告知';
|
||
|
||
-- 存量已拒绝的流转为已告知(本功能上线前的历史,不追溯打扰)
|
||
UPDATE trans_borrow_transfer
|
||
SET reject_seen_at = CURRENT_TIMESTAMP
|
||
WHERE status = 'REJECTED'
|
||
AND reject_seen_at IS NULL;
|
||
|
||
-- 支撑「待告知发起方的拒绝」查询
|
||
CREATE INDEX IF NOT EXISTS ix_trans_borrow_transfer_from_status
|
||
ON trans_borrow_transfer (from_user_id, status);
|
||
|
||
COMMIT;
|
||
|
||
|
||
-- =============================================================================
|
||
-- 执行后核对
|
||
-- =============================================================================
|
||
\echo '--- 1) 新列已就位 ---'
|
||
SELECT column_name, data_type FROM information_schema.columns
|
||
WHERE table_name = 'trans_borrow_transfer' AND column_name = 'reject_seen_at';
|
||
|
||
\echo '--- 2) 拒绝流水均已标记为已告知(应为 0 行待告知)---'
|
||
SELECT id, borrow_no, status, from_user_name, to_user_name, reject_seen_at
|
||
FROM trans_borrow_transfer
|
||
WHERE status = 'REJECTED' AND reject_seen_at IS NULL;
|
||
|
||
\echo '--- 3) 全部流水一览 ---'
|
||
SELECT id, status, from_user_name, to_user_name,
|
||
CASE WHEN reject_seen_at IS NULL THEN '' ELSE '已告知' END AS 拒绝告知
|
||
FROM trans_borrow_transfer ORDER BY id;
|
||
|
||
|
||
-- =============================================================================
|
||
-- 回滚段
|
||
-- =============================================================================
|
||
-- BEGIN;
|
||
-- DROP INDEX IF EXISTS ix_trans_borrow_transfer_from_status;
|
||
-- ALTER TABLE trans_borrow_transfer DROP COLUMN IF EXISTS reject_seen_at;
|
||
-- COMMIT;
|