-- Schéma pre Modulárny generátor newsletterov (COOP Jednota) -- -- Založenie databázy na novom Supabase projekte: -- Supabase Dashboard → SQL Editor → vložiť celý tento súbor → Run. -- Skript je idempotentný – dá sa spustiť opakovane bez straty dát. -- 1. Tabuľka šablón / konceptov newslettera -- data = { preheader, modules[] } – celý obsah kampane ako JSON CREATE TABLE IF NOT EXISTS templates ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), title TEXT NOT NULL DEFAULT 'Nový newsletter', status TEXT NOT NULL DEFAULT 'draft' CHECK (status IN ('draft', 'ready', 'exported')), data JSONB NOT NULL DEFAULT '{}'::jsonb, brevo_campaign_id INTEGER, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); -- Index pre rýchle zoradenie podľa dátumu úpravy CREATE INDEX IF NOT EXISTS idx_templates_updated_at ON templates(updated_at DESC); -- 2. Tabuľka šablón cenoviek (Badges) -- layers_config = { layers[], width, align, paddingTop, paddingBottom } -- (staršie záznamy môžu mať len pole vrstiev – aplikácia podporuje oba tvary) CREATE TABLE IF NOT EXISTS badges ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, svg_background_url TEXT, svg_raw TEXT, layers_config JSONB NOT NULL DEFAULT '[]'::jsonb, preview_image_url TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); -- 3. Tabuľka uložených profilov mapovania importu (zatiaľ nevyužitá aplikáciou) CREATE TABLE IF NOT EXISTS mapping_presets ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, file_type TEXT NOT NULL CHECK (file_type IN ('csv', 'json', 'xml')), mapping_rules JSONB NOT NULL DEFAULT '{}'::jsonb, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); -- 4. RLS (Row Level Security) – interný nástroj: povolený prístup cez anon kľúč ALTER TABLE templates ENABLE ROW LEVEL SECURITY; ALTER TABLE badges ENABLE ROW LEVEL SECURITY; ALTER TABLE mapping_presets ENABLE ROW LEVEL SECURITY; DROP POLICY IF EXISTS "Allow public all on templates" ON templates; DROP POLICY IF EXISTS "Allow public all on badges" ON badges; DROP POLICY IF EXISTS "Allow public all on mapping_presets" ON mapping_presets; CREATE POLICY "Allow public all on templates" ON templates FOR ALL USING (true) WITH CHECK (true); CREATE POLICY "Allow public all on badges" ON badges FOR ALL USING (true) WITH CHECK (true); CREATE POLICY "Allow public all on mapping_presets" ON mapping_presets FOR ALL USING (true) WITH CHECK (true); -- 5. Úložisko obrázkov (Storage bucket) – verejne čitateľné, aby sa obrázky zobrazili v e-mailoch. -- Nahrávanie ide cez /api/upload so service_role kľúčom (obchádza RLS), ďalšie politiky netreba. INSERT INTO storage.buckets (id, name, public) VALUES ('newsletter-assets', 'newsletter-assets', true) ON CONFLICT (id) DO UPDATE SET public = true; -- 6. Pripomienky k newslettru cez zdieľaný odkaz (rovnaké ako supabase/migrations/002_reviews.sql) -- Odkaz na pripomienky: snímka newslettra v čase vytvorenia / poslednej aktualizácie CREATE TABLE IF NOT EXISTS reviews ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), token TEXT NOT NULL UNIQUE, -- časť odkazu /review/ template_id UUID REFERENCES templates(id) ON DELETE CASCADE, title TEXT NOT NULL DEFAULT '', snapshot JSONB NOT NULL DEFAULT '{}'::jsonb, -- kampaň (moduly) v čase zdieľania created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_reviews_template ON reviews(template_id); -- Pripomienky: komentár (špendlík), text priamo v newslettri, kresba -- Poloha je ukotvená k modulu: x = podiel šírky (0–1), y = px od vrchu modulu CREATE TABLE IF NOT EXISTS review_comments ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), review_id UUID NOT NULL REFERENCES reviews(id) ON DELETE CASCADE, kind TEXT NOT NULL CHECK (kind IN ('comment', 'text', 'drawing')), module_id TEXT NOT NULL, x DOUBLE PRECISION NOT NULL DEFAULT 0, y DOUBLE PRECISION NOT NULL DEFAULT 0, path JSONB, -- kresba: [[x, y], ...] v rovnakých súradniciach text TEXT NOT NULL DEFAULT '', color TEXT NOT NULL DEFAULT '#e2001a', author TEXT NOT NULL DEFAULT '', done BOOLEAN NOT NULL DEFAULT false, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_review_comments_review ON review_comments(review_id, created_at); -- Interný nástroj: prístup cez anon kľúč (rovnako ako ostatné tabuľky) ALTER TABLE reviews ENABLE ROW LEVEL SECURITY; ALTER TABLE review_comments ENABLE ROW LEVEL SECURITY; DROP POLICY IF EXISTS "Allow public all on reviews" ON reviews; DROP POLICY IF EXISTS "Allow public all on review_comments" ON review_comments; CREATE POLICY "Allow public all on reviews" ON reviews FOR ALL USING (true) WITH CHECK (true); CREATE POLICY "Allow public all on review_comments" ON review_comments FOR ALL USING (true) WITH CHECK (true);