30 lines
1.6 KiB
SQL
30 lines
1.6 KiB
SQL
-- Article pipeline: track articles from discovery through posting
|
|
CREATE TABLE IF NOT EXISTS official_account_articles (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
config_id UUID NOT NULL REFERENCES official_account_configs(id) ON DELETE CASCADE,
|
|
guid TEXT NOT NULL, -- unique article ID (Google News URL or RSS GUID)
|
|
title TEXT NOT NULL DEFAULT '',
|
|
link TEXT NOT NULL, -- resolved URL (what gets posted)
|
|
source_name TEXT NOT NULL DEFAULT '',
|
|
source_url TEXT NOT NULL DEFAULT '',
|
|
description TEXT NOT NULL DEFAULT '',
|
|
pub_date TIMESTAMPTZ,
|
|
status TEXT NOT NULL DEFAULT 'discovered', -- discovered | posted | failed | skipped
|
|
post_id UUID REFERENCES public.posts(id) ON DELETE SET NULL,
|
|
error_message TEXT,
|
|
discovered_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
posted_at TIMESTAMPTZ,
|
|
|
|
CONSTRAINT unique_article_guid_per_config UNIQUE (config_id, guid)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_oaa_config_status ON official_account_articles(config_id, status);
|
|
CREATE INDEX IF NOT EXISTS idx_oaa_discovered ON official_account_articles(discovered_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_oaa_guid ON official_account_articles(guid);
|
|
|
|
-- Migrate existing posted articles into the new table
|
|
INSERT INTO official_account_articles (config_id, guid, title, link, source_name, status, post_id, discovered_at, posted_at)
|
|
SELECT config_id, article_url, article_title, article_url, source_name, 'posted', post_id, posted_at, posted_at
|
|
FROM official_account_posted_articles
|
|
ON CONFLICT (config_id, guid) DO NOTHING;
|