- 新增 tb_refund_post_process_attempt,每次尝试一条(步骤、触发方式、结果、错误码与信息、耗时) - 退款单增加 asset_post_status/attempts/last_error/next_at;失败按 2^(n-1) 分钟退避(最长 1 小时),10 次后转人工 - 中间失败只写应用日志,成功或转人工写一条结论审计(带总尝试次数、首次失败时间、最后错误码) - 补偿扫描跳过需人工处理与未到重试时间的退款单,Outbox 不再无限重投 - 新增 POST /refunds/:id/asset-post-processing/retry 人工重试 - 停复机指令执行前结束(已是目标状态、条件不再满足、需相反动作)写 skipped 停复机记录 - 迁移 000271 需维护者在测试库执行后再部署 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
49 lines
2.9 KiB
PL/PgSQL
49 lines
2.9 KiB
PL/PgSQL
-- 退款资产后处理:逐次尝试记录 + 退款单上的当前状态、次数、最后错误与下次重试时间。
|
|
-- 每单自动重试最多 10 次,尝试记录量很小,不分区。
|
|
BEGIN;
|
|
|
|
ALTER TABLE tb_refund_request
|
|
ADD COLUMN IF NOT EXISTS asset_post_status smallint NOT NULL DEFAULT 0,
|
|
ADD COLUMN IF NOT EXISTS asset_post_attempts int NOT NULL DEFAULT 0,
|
|
ADD COLUMN IF NOT EXISTS asset_post_last_error varchar(500) NOT NULL DEFAULT '',
|
|
ADD COLUMN IF NOT EXISTS asset_post_next_at timestamptz;
|
|
|
|
COMMENT ON COLUMN tb_refund_request.asset_post_status IS '资产后处理状态 0-未开始 1-待重试 2-已完成 3-需人工处理';
|
|
COMMENT ON COLUMN tb_refund_request.asset_post_attempts IS '资产后处理已尝试次数';
|
|
COMMENT ON COLUMN tb_refund_request.asset_post_last_error IS '资产后处理最后一次错误摘要';
|
|
COMMENT ON COLUMN tb_refund_request.asset_post_next_at IS '资产后处理下次自动重试时间,为空表示可立即执行';
|
|
|
|
-- 已完成的存量退款单同步为已完成。
|
|
UPDATE tb_refund_request SET asset_post_status = 2 WHERE asset_reset = true AND asset_post_status = 0;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_refund_request_asset_post_status ON tb_refund_request (asset_post_status, asset_post_next_at);
|
|
|
|
CREATE TABLE IF NOT EXISTS tb_refund_post_process_attempt (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
refund_id BIGINT NOT NULL,
|
|
refund_no VARCHAR(64) NOT NULL DEFAULT '',
|
|
step VARCHAR(32) NOT NULL,
|
|
asset_type VARCHAR(16) NOT NULL DEFAULT '',
|
|
asset_id BIGINT NOT NULL DEFAULT 0,
|
|
iccid VARCHAR(30) NOT NULL DEFAULT '',
|
|
attempt INT NOT NULL,
|
|
trigger VARCHAR(16) NOT NULL,
|
|
result VARCHAR(16) NOT NULL,
|
|
error_code VARCHAR(32) NOT NULL DEFAULT '',
|
|
error_message VARCHAR(500) NOT NULL DEFAULT '',
|
|
duration_ms INT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
COMMENT ON TABLE tb_refund_post_process_attempt IS '退款资产后处理逐次尝试记录,只新增不修改';
|
|
COMMENT ON COLUMN tb_refund_post_process_attempt.step IS '处理步骤 load-读取订单与资产 invalidate-套餐失效 activate-接续激活 check_main-查询生效主套餐 stop-停机评估或停机 mark-标记完成 done-全部完成';
|
|
COMMENT ON COLUMN tb_refund_post_process_attempt.trigger IS '触发方式 outbox-Outbox投递 manual-人工重试';
|
|
COMMENT ON COLUMN tb_refund_post_process_attempt.result IS '结果 success-成功 failed-失败';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_refund_post_attempt_refund ON tb_refund_post_process_attempt (refund_id, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_refund_post_attempt_time ON tb_refund_post_process_attempt (created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_refund_post_attempt_result ON tb_refund_post_process_attempt (result, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_refund_post_attempt_error ON tb_refund_post_process_attempt (error_code, created_at DESC);
|
|
|
|
COMMIT;
|