-- Migration for Advanced Tagging System -- 1. Rename existing 'tasting_tags' to 'tasting_buddies' -- This table currently stores which buddies are part of a tasting. DO $$ BEGIN IF EXISTS (SELECT FROM pg_tables WHERE schemaname = 'public' AND tablename = 'tasting_tags') THEN ALTER TABLE tasting_tags RENAME TO tasting_buddies; END IF; END $$; -- 2. Create 'tags' table CREATE TYPE tag_category AS ENUM ('nose', 'taste', 'finish', 'texture'); CREATE TABLE IF NOT EXISTS tags ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, category tag_category NOT NULL, is_system_default BOOLEAN DEFAULT false, popularity_score INTEGER DEFAULT 3, -- 1 to 5 created_by UUID REFERENCES profiles(id) ON DELETE CASCADE, UNIQUE(name, category) ); -- 3. Create new 'tasting_tags' junction table (for aroma tags) CREATE TABLE IF NOT EXISTS tasting_tags ( tasting_id UUID REFERENCES tastings(id) ON DELETE CASCADE NOT NULL, tag_id UUID REFERENCES tags(id) ON DELETE CASCADE NOT NULL, user_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL, PRIMARY KEY (tasting_id, tag_id) ); -- 4. Enable RLS ALTER TABLE tags ENABLE ROW LEVEL SECURITY; ALTER TABLE tasting_tags ENABLE ROW LEVEL SECURITY; -- 5. Policies for 'tags' -- Everyone can read system default tags and their own custom tags DROP POLICY IF EXISTS "tags_select_policy" ON tags; CREATE POLICY "tags_select_policy" ON tags FOR SELECT USING ( is_system_default = true OR (SELECT auth.uid()) = created_by OR EXISTS (SELECT 1 FROM admin_users WHERE user_id = (SELECT auth.uid())) ); -- Users can insert their own custom tags DROP POLICY IF EXISTS "tags_insert_policy" ON tags; CREATE POLICY "tags_insert_policy" ON tags FOR INSERT WITH CHECK ( (SELECT auth.uid()) = created_by ); -- 6. Policies for 'tasting_tags' (junction) DROP POLICY IF EXISTS "tasting_tags_owner_policy" ON tasting_tags; CREATE POLICY "tasting_tags_owner_policy" ON tasting_tags FOR ALL USING ((SELECT auth.uid()) = user_id); -- 7. Insert Master List of System Tags INSERT INTO tags (name, category, is_system_default) VALUES -- FRUCHTIG (FRUITY) ('Apfel', 'nose', true), ('Apfel', 'taste', true), ('Grüner Apfel', 'nose', true), ('Grüner Apfel', 'taste', true), ('Bratapfel', 'nose', true), ('Bratapfel', 'taste', true), ('Birne', 'nose', true), ('Birne', 'taste', true), ('Zitrone', 'nose', true), ('Zitrone', 'taste', true), ('Zitrus', 'nose', true), ('Zitrus', 'taste', true), ('Orange', 'nose', true), ('Orange', 'taste', true), ('Orangenschale', 'nose', true), ('Orangenschale', 'taste', true), ('Pfirsich', 'nose', true), ('Pfirsich', 'taste', true), ('Aprikose', 'nose', true), ('Aprikose', 'taste', true), ('Banane', 'nose', true), ('Banane', 'taste', true), ('Ananas', 'nose', true), ('Ananas', 'taste', true), ('Tropische Früchte', 'nose', true), ('Tropische Früchte', 'taste', true), ('Kirsche', 'nose', true), ('Kirsche', 'taste', true), ('Beeren', 'nose', true), ('Beeren', 'taste', true), ('Brombeere', 'nose', true), ('Brombeere', 'taste', true), ('Himbeere', 'nose', true), ('Himbeere', 'taste', true), ('Pflaume', 'nose', true), ('Pflaume', 'taste', true), ('Trockenfrüchte', 'nose', true), ('Trockenfrüchte', 'taste', true), ('Rosinen', 'nose', true), ('Rosinen', 'taste', true), ('Datteln', 'nose', true), ('Datteln', 'taste', true), ('Feigen', 'nose', true), ('Feigen', 'taste', true), -- SÜSS & CREMIG (SWEET & CREAMY) ('Vanille', 'nose', true), ('Vanille', 'taste', true), ('Honig', 'nose', true), ('Honig', 'taste', true), ('Karamell', 'nose', true), ('Karamell', 'taste', true), ('Toffee', 'nose', true), ('Toffee', 'taste', true), ('Schokolade', 'nose', true), ('Schokolade', 'taste', true), ('Zartbitterschokolade', 'nose', true), ('Zartbitterschokolade', 'taste', true), ('Milchschokolade', 'nose', true), ('Milchschokolade', 'taste', true), ('Malz', 'nose', true), ('Malz', 'taste', true), ('Müsli', 'nose', true), ('Müsli', 'taste', true), ('Butter', 'nose', true), ('Butter', 'taste', true), ('Butterkeks', 'nose', true), ('Butterkeks', 'taste', true), ('Marzipan', 'nose', true), ('Marzipan', 'taste', true), ('Mandel', 'nose', true), ('Mandel', 'taste', true), ('Sahnebonbon', 'nose', true), ('Sahnebonbon', 'taste', true), -- WÜRZIG & NUSSIG (SPICY & NUTTY) ('Eiche', 'nose', true), ('Eiche', 'taste', true), ('Zimt', 'nose', true), ('Zimt', 'taste', true), ('Pfeffer', 'nose', true), ('Pfeffer', 'taste', true), ('Muskatnuss', 'nose', true), ('Muskatnuss', 'taste', true), ('Ingwer', 'nose', true), ('Ingwer', 'taste', true), ('Nelke', 'nose', true), ('Nelke', 'taste', true), ('Walnuss', 'nose', true), ('Walnuss', 'taste', true), ('Haselnuss', 'nose', true), ('Haselnuss', 'taste', true), ('Geröstete Nüsse', 'nose', true), ('Geröstete Nüsse', 'taste', true), -- RAUCHIG & TORFIG (PEATY & SMOKY) ('Lagerfeuer', 'nose', true), ('Lagerfeuer', 'taste', true), ('Holzkohle', 'nose', true), ('Holzkohle', 'taste', true), ('Torfrauch', 'nose', true), ('Torfrauch', 'taste', true), ('Asche', 'nose', true), ('Asche', 'taste', true), ('Jod', 'nose', true), ('Jod', 'taste', true), ('Medizinisch', 'nose', true), ('Medizinisch', 'taste', true), ('Teer', 'nose', true), ('Teer', 'taste', true), ('Asphalt', 'nose', true), ('Asphalt', 'taste', true), ('Geräucherter Schinken', 'nose', true), ('Geräucherter Schinken', 'taste', true), ('Speck', 'nose', true), ('Speck', 'taste', true), ('Grillfleisch', 'nose', true), ('Grillfleisch', 'taste', true), -- MARITIM & SALZIG (COASTAL) ('Meersalz', 'nose', true), ('Meersalz', 'taste', true), ('Salzlake', 'nose', true), ('Salzlake', 'taste', true), ('Seetang', 'nose', true), ('Seetang', 'taste', true), ('Algen', 'nose', true), ('Algen', 'taste', true), ('Austern', 'nose', true), ('Austern', 'taste', true), ('Meeresbrise', 'nose', true), ('Meeresbrise', 'taste', true), -- FLORAL & KRÄUTER (FLORAL & HERBAL) ('Heidekraut', 'nose', true), ('Heidekraut', 'taste', true), ('Gras', 'nose', true), ('Gras', 'taste', true), ('Heu', 'nose', true), ('Heu', 'taste', true), ('Minze', 'nose', true), ('Minze', 'taste', true), ('Menthol', 'nose', true), ('Menthol', 'taste', true), ('Eukalyptus', 'nose', true), ('Eukalyptus', 'taste', true), ('Tabak', 'nose', true), ('Tabak', 'taste', true), ('Leder', 'nose', true), ('Leder', 'taste', true), ('Tee', 'nose', true), ('Tee', 'taste', true), -- FINISH DAUER ('Kurz & Knackig', 'finish', true), ('Mittellang', 'finish', true), ('Lang anhaltend', 'finish', true), ('Ewig', 'finish', true), -- TEXTUR & GEFÜHL ('Ölig', 'texture', true), ('Viskos', 'texture', true), ('Trocken', 'texture', true), ('Adstringierend', 'texture', true), ('Wärmend', 'texture', true), ('Scharf', 'texture', true), ('Beißend', 'texture', true), ('Weich', 'texture', true), ('Samtig', 'texture', true), ('Wässrig', 'texture', true) ON CONFLICT (name, category) DO NOTHING;