bmc_hub/migrations/161_manual_module.sql

74 lines
3.1 KiB
MySQL
Raw Normal View History

-- 161_manual_module.sql
-- Manual module: articles, steps and contextual relations
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE TABLE IF NOT EXISTS manual_articles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title VARCHAR(255) NOT NULL,
slug VARCHAR(255) NOT NULL UNIQUE,
content TEXT NOT NULL,
summary TEXT,
module VARCHAR(80) NOT NULL,
tags JSONB NOT NULL DEFAULT '[]'::jsonb,
difficulty VARCHAR(20) NOT NULL DEFAULT 'beginner' CHECK (difficulty IN ('beginner', 'advanced')),
use_count INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP WITH TIME ZONE DEFAULT NULL
);
CREATE TABLE IF NOT EXISTS manual_steps (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
manual_id UUID NOT NULL REFERENCES manual_articles(id) ON DELETE CASCADE,
step_number INTEGER NOT NULL CHECK (step_number > 0),
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
image_url TEXT,
video_url TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
UNIQUE (manual_id, step_number)
);
CREATE TABLE IF NOT EXISTS manual_relations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
manual_id UUID NOT NULL REFERENCES manual_articles(id) ON DELETE CASCADE,
related_module VARCHAR(80),
related_tag VARCHAR(120),
related_sag_type VARCHAR(120),
related_manual_id UUID REFERENCES manual_articles(id) ON DELETE SET NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_manual_articles_module ON manual_articles(module);
CREATE INDEX IF NOT EXISTS idx_manual_articles_difficulty ON manual_articles(difficulty);
CREATE INDEX IF NOT EXISTS idx_manual_articles_deleted_at ON manual_articles(deleted_at);
CREATE INDEX IF NOT EXISTS idx_manual_articles_use_count ON manual_articles(use_count DESC);
CREATE INDEX IF NOT EXISTS idx_manual_steps_manual_id_step ON manual_steps(manual_id, step_number);
CREATE INDEX IF NOT EXISTS idx_manual_relations_manual_id ON manual_relations(manual_id);
CREATE INDEX IF NOT EXISTS idx_manual_relations_related_module ON manual_relations(related_module);
CREATE INDEX IF NOT EXISTS idx_manual_relations_related_tag ON manual_relations(related_tag);
CREATE INDEX IF NOT EXISTS idx_manual_relations_related_sag_type ON manual_relations(related_sag_type);
-- Keep article updated_at fresh on content changes.
CREATE OR REPLACE FUNCTION bump_manual_article_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS trg_manual_articles_updated_at ON manual_articles;
CREATE TRIGGER trg_manual_articles_updated_at
BEFORE UPDATE ON manual_articles
FOR EACH ROW
EXECUTE FUNCTION bump_manual_article_updated_at();
DROP TRIGGER IF EXISTS trg_manual_steps_updated_at ON manual_steps;
CREATE TRIGGER trg_manual_steps_updated_at
BEFORE UPDATE ON manual_steps
FOR EACH ROW
EXECUTE FUNCTION bump_manual_article_updated_at();