Files
backend_v2/db/migrations/2026-09-22-01-single-table-publish.sql

52 lines
2.8 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 单表发布模型(方案 2):取消草稿表,审核态由 status 承载,公开读走只读视图。
--
-- 本文件只做三件事:加列 / 存量行置已发布 / 建视图。幂等,可重复执行。
-- 数据搬迁见 scripts/migrate_single_table;删草稿表见 2026-09-22-02-drop-draft-tables.sql。
-- 1) 正式表补审核态与溯源列。默认 'pending' 是刻意的(fail-closed):
-- 任何漏赋值的行默认不可见,而不是意外对外发布。
ALTER TABLE brand_runways
ADD COLUMN IF NOT EXISTS status varchar(16) NOT NULL DEFAULT 'pending',
ADD COLUMN IF NOT EXISTS job_id bigint NOT NULL DEFAULT 0,
ADD COLUMN IF NOT EXISTS reviewer varchar(64) NOT NULL DEFAULT '',
ADD COLUMN IF NOT EXISTS reject_reason varchar(255) NOT NULL DEFAULT '';
ALTER TABLE street_snaps
ADD COLUMN IF NOT EXISTS status varchar(16) NOT NULL DEFAULT 'pending',
ADD COLUMN IF NOT EXISTS job_id bigint NOT NULL DEFAULT 0,
ADD COLUMN IF NOT EXISTS reviewer varchar(64) NOT NULL DEFAULT '',
ADD COLUMN IF NOT EXISTS reject_reason varchar(255) NOT NULL DEFAULT '';
-- 2) 存量行置已发布**不在本文件里**:它是数据变更且只能执行一次,见同目录
-- 2026-09-22-01b-publish-existing-rows.sql。
-- 为什么必须拆开:数据搬迁(scripts/migrate_single_table)会把 pending 草稿连原 created_at
-- 一起搬进正式表;若本文件含那条 UPDATE 且被重复执行(测试每次都会跑),
-- 这些待审内容会被误刷成已发布 —— 恰好是本设计要防的泄漏。
-- 3) 状态索引:审核列表与公开视图都按 status 过滤。
CREATE INDEX IF NOT EXISTS idx_br_status ON brand_runways (status);
CREATE INDEX IF NOT EXISTS idx_ss_status ON street_snaps (status);
-- 4) 公开只读视图:把「必须是已发布且未删除」固化成结构性保证,公开查询漏写过滤成为不可能。
-- 注意:视图列集被 SELECT * 冻结 —— 以后给这 4 张基表加列,必须同批重建视图。
DROP VIEW IF EXISTS public_brand_runway_images;
DROP VIEW IF EXISTS public_brand_runways;
DROP VIEW IF EXISTS public_street_snap_images;
DROP VIEW IF EXISTS public_street_snaps;
CREATE VIEW public_brand_runways AS
SELECT * FROM brand_runways WHERE status = 'published' AND is_deleted = 0;
CREATE VIEW public_brand_runway_images AS
SELECT i.* FROM brand_runway_images i
JOIN brand_runways r ON r.id = i.runway_id
WHERE i.is_deleted = 0 AND r.status = 'published' AND r.is_deleted = 0;
CREATE VIEW public_street_snaps AS
SELECT * FROM street_snaps WHERE status = 'published' AND is_deleted = 0;
CREATE VIEW public_street_snap_images AS
SELECT i.* FROM street_snap_images i
JOIN street_snaps s ON s.id = i.snap_id
WHERE i.is_deleted = 0 AND s.status = 'published' AND s.is_deleted = 0;