Files
lindyson-ai/apps/api/migrations/030_admin_idempotency.sql
Juno ChowandClaude Fable 5.1 f665082dad chore: 建立产品仓库,完成开源前的敏感信息清理
前端(Vite + React)、API/worker(Fastify + BullMQ)、api-contracts 契约包、
迁移脚本、测试与自托管 docker-compose 示例。

开源准备:运维脚本与机器信息已拆到私有仓库;公司名、备案号、隐私邮箱改读
publicCompliance.local.json(仓库只保留占位模板);站点地址与客服二维码改为
VITE_ 环境变量;fixtures 中的真实用户标识已匿名化;三个 package.json 标注
Apache-2.0。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-16 02:10:46 +08:00

54 lines
2.1 KiB
SQL

ALTER TABLE admin_action_idempotency
ADD COLUMN IF NOT EXISTS response_status integer,
ADD COLUMN IF NOT EXISTS completed_at timestamptz,
ADD COLUMN IF NOT EXISTS response_expires_at timestamptz,
ADD COLUMN IF NOT EXISTS key_expires_at timestamptz;
DO $$
DECLARE
legacy_constraint text;
BEGIN
SELECT conname INTO legacy_constraint
FROM pg_constraint
WHERE conrelid = 'admin_action_idempotency'::regclass
AND contype = 'u'
AND pg_get_constraintdef(oid) = 'UNIQUE (admin_user_id, action, idempotency_key)'
LIMIT 1;
IF legacy_constraint IS NOT NULL THEN
EXECUTE format(
'ALTER TABLE admin_action_idempotency DROP CONSTRAINT %I',
legacy_constraint
);
END IF;
END $$;
CREATE UNIQUE INDEX IF NOT EXISTS idx_admin_action_idempotency_admin_key
ON admin_action_idempotency(admin_user_id, idempotency_key);
UPDATE admin_action_idempotency
SET response_status = CASE WHEN response_json IS NOT NULL THEN COALESCE(response_status, 200) ELSE response_status END,
completed_at = CASE WHEN response_json IS NOT NULL THEN COALESCE(completed_at, created_at) ELSE completed_at END,
response_expires_at = COALESCE(response_expires_at, created_at + interval '30 days'),
key_expires_at = COALESCE(key_expires_at, created_at + interval '365 days');
ALTER TABLE admin_action_idempotency
ALTER COLUMN response_expires_at SET DEFAULT (now() + interval '30 days'),
ALTER COLUMN response_expires_at SET NOT NULL,
ALTER COLUMN key_expires_at SET DEFAULT (now() + interval '365 days'),
ALTER COLUMN key_expires_at SET NOT NULL;
ALTER TABLE admin_action_idempotency
DROP CONSTRAINT IF EXISTS admin_action_idempotency_response_status_check;
ALTER TABLE admin_action_idempotency
ADD CONSTRAINT admin_action_idempotency_response_status_check
CHECK (response_status IS NULL OR response_status BETWEEN 100 AND 599);
CREATE INDEX IF NOT EXISTS idx_admin_action_idempotency_response_expiry
ON admin_action_idempotency(response_expires_at)
WHERE response_json IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_admin_action_idempotency_key_expiry
ON admin_action_idempotency(key_expires_at);