116 lines
6.2 KiB
SQL
116 lines
6.2 KiB
SQL
-- ARK 資料庫 initial schema
|
||
|
||
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
||
|
||
CREATE TABLE admins (
|
||
id SERIAL PRIMARY KEY,
|
||
email TEXT UNIQUE NOT NULL,
|
||
password_hash TEXT NOT NULL,
|
||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||
);
|
||
|
||
CREATE TABLE categories (
|
||
id SERIAL PRIMARY KEY,
|
||
slug TEXT UNIQUE NOT NULL,
|
||
name_zh_tw TEXT NOT NULL,
|
||
name_zh_cn TEXT,
|
||
name_en TEXT,
|
||
description_zh_tw TEXT,
|
||
icon_key TEXT DEFAULT 'folder',
|
||
sort_order INT NOT NULL DEFAULT 0,
|
||
is_visible BOOLEAN NOT NULL DEFAULT TRUE,
|
||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||
);
|
||
|
||
CREATE TABLE tags (
|
||
id SERIAL PRIMARY KEY,
|
||
name TEXT UNIQUE NOT NULL,
|
||
slug TEXT UNIQUE NOT NULL
|
||
);
|
||
|
||
CREATE TABLE resources (
|
||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
category_id INT NOT NULL REFERENCES categories(id),
|
||
title TEXT NOT NULL,
|
||
description TEXT,
|
||
type TEXT NOT NULL,
|
||
language TEXT NOT NULL DEFAULT 'zh-TW',
|
||
cover_image TEXT,
|
||
file_url TEXT,
|
||
preview_url TEXT,
|
||
external_url TEXT,
|
||
body_text TEXT,
|
||
badge_label TEXT,
|
||
is_public BOOLEAN NOT NULL DEFAULT TRUE,
|
||
is_downloadable BOOLEAN NOT NULL DEFAULT TRUE,
|
||
is_recommended BOOLEAN NOT NULL DEFAULT FALSE,
|
||
sort_order INT NOT NULL DEFAULT 0,
|
||
status TEXT NOT NULL DEFAULT 'draft',
|
||
published_at TIMESTAMPTZ,
|
||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
view_count INT NOT NULL DEFAULT 0,
|
||
download_count INT NOT NULL DEFAULT 0,
|
||
favorite_count INT NOT NULL DEFAULT 0,
|
||
share_count INT NOT NULL DEFAULT 0
|
||
);
|
||
|
||
CREATE INDEX idx_resources_category ON resources(category_id);
|
||
CREATE INDEX idx_resources_status_public ON resources(status, is_public);
|
||
CREATE INDEX idx_resources_published ON resources(published_at DESC NULLS LAST);
|
||
CREATE INDEX idx_resources_recommended ON resources(is_recommended) WHERE is_recommended = TRUE;
|
||
|
||
CREATE TABLE resource_tags (
|
||
resource_id UUID NOT NULL REFERENCES resources(id) ON DELETE CASCADE,
|
||
tag_id INT NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
|
||
PRIMARY KEY (resource_id, tag_id)
|
||
);
|
||
|
||
CREATE TABLE search_logs (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
query TEXT NOT NULL,
|
||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||
);
|
||
|
||
-- Seed categories (from 文案)
|
||
INSERT INTO categories (slug, name_zh_tw, name_zh_cn, name_en, description_zh_tw, icon_key, sort_order) VALUES
|
||
('project-ppt', '項目資料(PPT)', '项目资料(PPT)', 'Project (PPT)', 'ARK 項目介紹、簡報與對外展示資料', 'folder', 1),
|
||
('daily-class', '每日課堂(空課)', '每日课堂(空课)', 'Daily class', '每日課堂、夜聊、培訓與回放', 'calendar', 2),
|
||
('official-announcement', '官方公告(推特)', '官方公告(推特)', 'Official news', '官方公告、推文與重要通知', 'megaphone', 3),
|
||
('academy-materials', '學堂教育(教材)', '学堂教育(教材)', 'Academy materials', '學堂教材、版書與培訓文檔', 'graduation', 4),
|
||
('global-evangelism', '全球布道(影片)', '全球布道(影片)', 'Global outreach', '布道與活動影片', 'globe', 5),
|
||
('daily-poster', '每日海報', '每日海报', 'Daily posters', '每日宣傳與活動海報', 'image', 6),
|
||
('community-tweets', '社群動向(推文)', '社群动向(推文)', 'Community', '社群推文與推廣文案', 'chat', 7),
|
||
('video-hub', '視頻匯總(影片)', '视频汇总(影片)', 'Video hub', '影片資料匯總', 'film', 8),
|
||
('subsidy-policy', '補貼政策(活動)', '补贴政策(活动)', 'Campaigns', '補貼、活動規則與激勵方案', 'gift', 9),
|
||
('how-to', '操作指南(教程)', '操作指南(教程)', 'Tutorials', '操作教學與使用流程', 'book', 10),
|
||
('official-assets', '官方物料(物料)', '官方物料(物料)', 'Brand assets', 'Logo、模板與品牌素材', 'palette', 11),
|
||
('media-coverage', '媒體收錄(新聞)', '媒体收录(新闻)', 'Press', '外部媒體與新聞報導', 'newspaper', 12),
|
||
('academy-video', '學堂教育(影片)', '学堂教育(影片)', 'Academy video', '學堂課程與培訓影片', 'play', 13),
|
||
('general', 'General', 'General', 'General', '綜合或未分類資料', 'hash', 14);
|
||
|
||
INSERT INTO tags (name, slug) VALUES
|
||
('官方推薦', 'official'),
|
||
('新人必看', 'newcomer'),
|
||
('可下載', 'downloadable'),
|
||
('公告', 'announcement'),
|
||
('教程', 'tutorial'),
|
||
('海報', 'poster');
|
||
|
||
-- Demo resources (published)
|
||
INSERT INTO resources (category_id, title, description, type, language, cover_image, file_url, is_public, is_downloadable, is_recommended, status, published_at, badge_label, sort_order)
|
||
SELECT c.id, 'ARK 項目介紹簡報(示例)', '適合線下宣講與新人培訓。', 'ppt', 'zh-TW', '/uploads/placeholder-cover.svg', '/uploads/placeholder-cover.svg', TRUE, TRUE, TRUE, 'published', NOW() - INTERVAL '2 days', '新人必看', 10
|
||
FROM categories c WHERE c.slug = 'project-ppt' LIMIT 1;
|
||
|
||
INSERT INTO resources (category_id, title, description, type, language, cover_image, preview_url, is_public, is_downloadable, is_recommended, status, published_at, badge_label, sort_order)
|
||
SELECT c.id, '每日海報 | 示例', '適合每日社群推廣轉發。', 'image', 'zh-TW', '/uploads/placeholder-cover.svg', '/uploads/placeholder-cover.svg', TRUE, TRUE, TRUE, 'published', NOW() - INTERVAL '1 day', '最新公告', 20
|
||
FROM categories c WHERE c.slug = 'daily-poster' LIMIT 1;
|
||
|
||
INSERT INTO resources (category_id, title, description, type, language, external_url, is_public, is_downloadable, is_recommended, status, published_at, sort_order)
|
||
SELECT c.id, '外部報導連結(示例)', '第三方媒體文章(示例)。', 'link', 'zh-TW', 'https://example.com', TRUE, FALSE, FALSE, 'published', NOW() - INTERVAL '3 hours', 5
|
||
FROM categories c WHERE c.slug = 'media-coverage' LIMIT 1;
|
||
|
||
INSERT INTO resources (category_id, title, description, type, language, cover_image, file_url, is_public, is_downloadable, status, published_at, sort_order)
|
||
SELECT c.id, '全球布道影片(示例)', '活動精華剪輯。', 'video', 'zh-TW', '/uploads/placeholder-cover.svg', 'https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4', TRUE, TRUE, 'published', NOW() - INTERVAL '5 days', 8
|
||
FROM categories c WHERE c.slug = 'global-evangelism' LIMIT 1;
|