feat: scope articles by brand

This commit is contained in:
2026-05-20 15:37:25 +08:00
parent 5fb9d0b0dd
commit dd082e2ed1
72 changed files with 3213 additions and 432 deletions
@@ -0,0 +1,5 @@
DROP INDEX IF EXISTS idx_article_tenant_brand_status_created;
DROP INDEX IF EXISTS idx_article_tenant_brand_created;
ALTER TABLE articles
DROP COLUMN IF EXISTS brand_id;
@@ -0,0 +1,100 @@
ALTER TABLE articles
ADD COLUMN IF NOT EXISTS brand_id BIGINT REFERENCES brands(id);
WITH task_brand AS (
SELECT DISTINCT ON (gt.article_id)
gt.article_id,
CASE
WHEN gt.input_params_json ->> 'brand_id' ~ '^[0-9]+$'
THEN (gt.input_params_json ->> 'brand_id')::BIGINT
ELSE NULL
END AS brand_id
FROM generation_tasks gt
WHERE gt.article_id IS NOT NULL
ORDER BY gt.article_id, gt.created_at DESC, gt.id DESC
)
UPDATE articles a
SET brand_id = tb.brand_id
FROM task_brand tb
JOIN brands b
ON b.id = tb.brand_id
AND b.deleted_at IS NULL
WHERE a.id = tb.article_id
AND b.tenant_id = a.tenant_id
AND a.brand_id IS NULL
AND tb.brand_id IS NOT NULL;
WITH task_brand_name AS (
SELECT DISTINCT ON (gt.article_id)
gt.article_id,
NULLIF(BTRIM(gt.input_params_json ->> 'brand_name'), '') AS brand_name
FROM generation_tasks gt
WHERE gt.article_id IS NOT NULL
ORDER BY gt.article_id, gt.created_at DESC, gt.id DESC
)
UPDATE articles a
SET brand_id = b.id
FROM task_brand_name tbn
JOIN brands b
ON b.name = tbn.brand_name
AND b.deleted_at IS NULL
WHERE a.id = tbn.article_id
AND b.tenant_id = a.tenant_id
AND a.brand_id IS NULL
AND tbn.brand_name IS NOT NULL;
UPDATE articles a
SET brand_id = b.id
FROM brands b
WHERE b.tenant_id = a.tenant_id
AND b.deleted_at IS NULL
AND a.brand_id IS NULL
AND a.wizard_state_json ->> 'selected_brand_id' ~ '^[0-9]+$'
AND b.id = (a.wizard_state_json ->> 'selected_brand_id')::BIGINT;
UPDATE articles a
SET brand_id = b.id
FROM brands b
WHERE b.tenant_id = a.tenant_id
AND b.deleted_at IS NULL
AND a.brand_id IS NULL
AND a.wizard_state_json ->> 'brand_id' ~ '^[0-9]+$'
AND b.id = (a.wizard_state_json ->> 'brand_id')::BIGINT;
UPDATE articles a
SET brand_id = b.id
FROM brands b
WHERE b.tenant_id = a.tenant_id
AND b.deleted_at IS NULL
AND a.brand_id IS NULL
AND b.name = NULLIF(BTRIM(a.wizard_state_json ->> 'brand_name'), '');
INSERT INTO brands (tenant_id, name, description, status)
SELECT DISTINCT a.tenant_id, '未归属', '系统迁移生成,用于存放无法自动推断公司的历史文章。', 'active'
FROM articles a
WHERE a.brand_id IS NULL
AND a.deleted_at IS NULL
AND NOT EXISTS (
SELECT 1
FROM brands b
WHERE b.tenant_id = a.tenant_id
AND b.name = '未归属'
AND b.deleted_at IS NULL
);
UPDATE articles a
SET brand_id = b.id
FROM brands b
WHERE b.tenant_id = a.tenant_id
AND b.name = '未归属'
AND b.deleted_at IS NULL
AND a.brand_id IS NULL
AND a.deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_article_tenant_brand_created
ON articles(tenant_id, brand_id, created_at DESC)
WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_article_tenant_brand_status_created
ON articles(tenant_id, brand_id, generate_status, publish_status, created_at DESC)
WHERE deleted_at IS NULL;
@@ -0,0 +1,2 @@
DROP INDEX IF EXISTS idx_schedule_task_tenant_brand_next_run;
DROP INDEX IF EXISTS idx_schedule_task_tenant_brand_created;
@@ -0,0 +1,51 @@
WITH task_brand AS (
SELECT DISTINCT ON (NULLIF(gt.input_params_json ->> 'schedule_task_id', '')::BIGINT)
NULLIF(gt.input_params_json ->> 'schedule_task_id', '')::BIGINT AS schedule_task_id,
(gt.input_params_json ->> 'brand_id')::BIGINT AS brand_id
FROM generation_tasks gt
WHERE gt.input_params_json ->> 'schedule_task_id' ~ '^[0-9]+$'
AND gt.input_params_json ->> 'brand_id' ~ '^[0-9]+$'
ORDER BY NULLIF(gt.input_params_json ->> 'schedule_task_id', '')::BIGINT, gt.created_at DESC, gt.id DESC
)
UPDATE schedule_tasks st
SET brand_id = tb.brand_id,
updated_at = NOW()
FROM task_brand tb
JOIN brands b
ON b.id = tb.brand_id
AND b.deleted_at IS NULL
WHERE st.id = tb.schedule_task_id
AND st.tenant_id = b.tenant_id
AND st.brand_id IS NULL
AND tb.brand_id IS NOT NULL;
INSERT INTO brands (tenant_id, name, description, status)
SELECT DISTINCT st.tenant_id, '未归属', '系统迁移生成,用于存放无法自动推断公司的历史定时任务。', 'active'
FROM schedule_tasks st
WHERE st.brand_id IS NULL
AND st.deleted_at IS NULL
AND NOT EXISTS (
SELECT 1
FROM brands b
WHERE b.tenant_id = st.tenant_id
AND b.name = '未归属'
AND b.deleted_at IS NULL
);
UPDATE schedule_tasks st
SET brand_id = b.id,
updated_at = NOW()
FROM brands b
WHERE b.tenant_id = st.tenant_id
AND b.name = '未归属'
AND b.deleted_at IS NULL
AND st.brand_id IS NULL
AND st.deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_schedule_task_tenant_brand_created
ON schedule_tasks(tenant_id, brand_id, created_at DESC)
WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_schedule_task_tenant_brand_next_run
ON schedule_tasks(tenant_id, brand_id, status, next_run_at, id)
WHERE deleted_at IS NULL;
@@ -0,0 +1,2 @@
ALTER TABLE articles
ALTER COLUMN brand_id DROP NOT NULL;
@@ -0,0 +1,22 @@
INSERT INTO brands (tenant_id, name, description, status)
SELECT DISTINCT a.tenant_id, '未归属', '系统迁移生成,用于存放无法自动推断公司的历史文章。', 'active'
FROM articles a
WHERE a.brand_id IS NULL
AND NOT EXISTS (
SELECT 1
FROM brands b
WHERE b.tenant_id = a.tenant_id
AND b.name = '未归属'
AND b.deleted_at IS NULL
);
UPDATE articles a
SET brand_id = b.id
FROM brands b
WHERE b.tenant_id = a.tenant_id
AND b.name = '未归属'
AND b.deleted_at IS NULL
AND a.brand_id IS NULL;
ALTER TABLE articles
ALTER COLUMN brand_id SET NOT NULL;