42 lines
1.4 KiB
SQL
42 lines
1.4 KiB
SQL
-- Create normalized article table for blog-backup.
|
|
-- One row = one article. digest_date groups rows by daily digest.
|
|
|
|
CREATE TABLE IF NOT EXISTS public.blog_articles (
|
|
id TEXT PRIMARY KEY,
|
|
title TEXT NOT NULL,
|
|
summary TEXT NOT NULL,
|
|
source_url TEXT,
|
|
digest_date DATE,
|
|
published_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
tags TEXT[] NOT NULL DEFAULT '{}'::TEXT[],
|
|
audio_url TEXT,
|
|
audio_duration INTEGER,
|
|
is_published BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_blog_articles_published_at
|
|
ON public.blog_articles (published_at DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_blog_articles_digest_date
|
|
ON public.blog_articles (digest_date DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_blog_articles_tags
|
|
ON public.blog_articles USING GIN (tags);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_blog_articles_audio
|
|
ON public.blog_articles (audio_url)
|
|
WHERE audio_url IS NOT NULL;
|
|
|
|
COMMENT ON TABLE public.blog_articles IS
|
|
'One row per article. digest_date groups rows into a daily digest.';
|
|
|
|
COMMENT ON COLUMN public.blog_articles.summary IS
|
|
'Structured article summary body shown in UI and RSS.';
|
|
|
|
COMMENT ON COLUMN public.blog_articles.digest_date IS
|
|
'Logical daily digest date (YYYY-MM-DD). Multiple articles can share one date.';
|
|
|
|
COMMENT ON COLUMN public.blog_articles.is_published IS
|
|
'Controls public visibility in /api/articles and RSS.';
|