From b1e41026b6d64c2314be828891688d77fedbc01a Mon Sep 17 00:00:00 2001 From: Florian Wilde Date: Fri, 17 Jul 2026 18:18:44 +0200 Subject: [PATCH] Lokale PostgreSQL-Kopie: Auth/Storage-Stubs, Dumps und Sync-Skript --- scripts/sync-local-db.ps1 | 37 +++ supabase/local/00_stubs.sql | 58 +++++ supabase/local/10_schema.sql | 416 +++++++++++++++++++++++++++++++ supabase/local/15_auth_users.sql | 6 + supabase/local/20_data.sql | 198 +++++++++++++++ 5 files changed, 715 insertions(+) create mode 100644 scripts/sync-local-db.ps1 create mode 100644 supabase/local/00_stubs.sql create mode 100644 supabase/local/10_schema.sql create mode 100644 supabase/local/15_auth_users.sql create mode 100644 supabase/local/20_data.sql diff --git a/scripts/sync-local-db.ps1 b/scripts/sync-local-db.ps1 new file mode 100644 index 0000000..c4a3923 --- /dev/null +++ b/scripts/sync-local-db.ps1 @@ -0,0 +1,37 @@ +# Synchronisiert die lokale PostgreSQL-Kopie mit der Supabase-Datenbank. +# Voraussetzungen: +# - PostgreSQL 17 lokal installiert (Standardpfad, Dienst läuft) +# - Umgebungsvariablen: +# SUPABASE_DB_PASSWORD = Datenbank-Passwort des Supabase-Projekts +# LOCAL_PG_PASSWORD = Passwort des lokalen postgres-Benutzers +# Aufruf: powershell -File scripts\sync-local-db.ps1 + +$ErrorActionPreference = "Stop" + +$PgBin = "C:\Program Files\PostgreSQL\17\bin" +$RemoteHost = "aws-0-eu-central-1.pooler.supabase.com" +$RemoteUser = "postgres.hvzikwjoyhoakedlywhj" +$LocalDir = Join-Path $PSScriptRoot "..\supabase\local" + +if (-not $env:SUPABASE_DB_PASSWORD) { throw "SUPABASE_DB_PASSWORD ist nicht gesetzt." } +if (-not $env:LOCAL_PG_PASSWORD) { throw "LOCAL_PG_PASSWORD ist nicht gesetzt." } + +# 1. Aktuellen Stand aus Supabase ziehen (Session-Pooler, Port 5432) +$env:PGPASSWORD = $env:SUPABASE_DB_PASSWORD +& "$PgBin\pg_dump" -h $RemoteHost -p 5432 -U $RemoteUser -d postgres ` + --schema=public --schema-only --no-owner --no-privileges ` + -f (Join-Path $LocalDir "10_schema.sql") +& "$PgBin\pg_dump" -h $RemoteHost -p 5432 -U $RemoteUser -d postgres ` + --schema=public --data-only --no-owner --disable-triggers ` + -f (Join-Path $LocalDir "20_data.sql") + +# 2. Lokale Datenbank neu aufbauen +$env:PGPASSWORD = $env:LOCAL_PG_PASSWORD +& "$PgBin\psql" -h localhost -U postgres -c "drop database if exists speisekarte;" +& "$PgBin\psql" -h localhost -U postgres -c "create database speisekarte;" + +foreach ($file in @("00_stubs.sql", "10_schema.sql", "15_auth_users.sql", "20_data.sql")) { + & "$PgBin\psql" -h localhost -U postgres -d speisekarte -q -f (Join-Path $LocalDir $file) +} + +Write-Host "Lokale Datenbank 'speisekarte' wurde aktualisiert." diff --git a/supabase/local/00_stubs.sql b/supabase/local/00_stubs.sql new file mode 100644 index 0000000..def1d2d --- /dev/null +++ b/supabase/local/00_stubs.sql @@ -0,0 +1,58 @@ +-- ============================================================= +-- Stubs für die LOKALE PostgreSQL-Kopie (ohne Supabase-Stack). +-- Stellt die minimalen Supabase-Objekte bereit, die das public- +-- Schema referenziert (auth.users, auth.uid(), Rollen, storage). +-- Reihenfolge: 00_stubs.sql -> Schema-Dump -> Daten-Dump +-- ============================================================= + +-- Rollen, die in den RLS-Policies referenziert werden +do $$ +begin + if not exists (select from pg_roles where rolname = 'anon') then + create role anon nologin; + end if; + if not exists (select from pg_roles where rolname = 'authenticated') then + create role authenticated nologin; + end if; + if not exists (select from pg_roles where rolname = 'service_role') then + create role service_role nologin bypassrls; + end if; +end +$$; + +-- ---------- auth-Schema (Minimal-Stub) ---------- +create schema if not exists auth; + +create table if not exists auth.users ( + id uuid primary key, + email text, + raw_user_meta_data jsonb not null default '{}'::jsonb, + created_at timestamptz not null default now() +); + +-- Entspricht supabase auth.uid(); liefert lokal null, +-- sofern kein JWT-Claim gesetzt ist. +create or replace function auth.uid() +returns uuid +language sql +stable +as $$ + select nullif(current_setting('request.jwt.claim.sub', true), '')::uuid +$$; + +-- ---------- storage-Schema (Minimal-Stub) ---------- +create schema if not exists storage; + +create table if not exists storage.buckets ( + id text primary key, + name text not null, + public boolean not null default false +); + +create table if not exists storage.objects ( + id uuid primary key default gen_random_uuid(), + bucket_id text references storage.buckets (id), + name text, + owner uuid, + created_at timestamptz not null default now() +); diff --git a/supabase/local/10_schema.sql b/supabase/local/10_schema.sql new file mode 100644 index 0000000..feaabfe --- /dev/null +++ b/supabase/local/10_schema.sql @@ -0,0 +1,416 @@ +-- +-- PostgreSQL database dump +-- + +\restrict 0Sx6NoZQaGnfPJIJyJfoBWP8AEmM74wz3Ic4g8Y4DFplRk7HfQrhCEYG288Lc2B + +-- Dumped from database version 17.6 +-- Dumped by pg_dump version 17.10 + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET transaction_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +-- +-- Name: public; Type: SCHEMA; Schema: -; Owner: - +-- + +CREATE SCHEMA public; + + +-- +-- Name: SCHEMA public; Type: COMMENT; Schema: -; Owner: - +-- + +COMMENT ON SCHEMA public IS 'standard public schema'; + + +-- +-- Name: app_role(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.app_role() RETURNS text + LANGUAGE sql STABLE SECURITY DEFINER + SET search_path TO 'public' + AS $$ + select role from public.profiles where id = auth.uid() +$$; + + +-- +-- Name: handle_new_user(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.handle_new_user() RETURNS trigger + LANGUAGE plpgsql SECURITY DEFINER + SET search_path TO 'public' + AS $$ +begin + insert into public.profiles (id, email, full_name, role) + values ( + new.id, + new.email, + coalesce(new.raw_user_meta_data ->> 'full_name', ''), + coalesce(new.raw_user_meta_data ->> 'role', 'staff') + ) + on conflict (id) do nothing; + return new; +end; +$$; + + +-- +-- Name: touch_updated_at(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.touch_updated_at() RETURNS trigger + LANGUAGE plpgsql + AS $$ +begin + new.updated_at := now(); + return new; +end; +$$; + + +SET default_tablespace = ''; + +SET default_table_access_method = heap; + +-- +-- Name: additives; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.additives ( + code text NOT NULL, + name text NOT NULL, + sort integer DEFAULT 0 NOT NULL +); + + +-- +-- Name: allergens; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.allergens ( + code text NOT NULL, + name text NOT NULL, + sort integer DEFAULT 0 NOT NULL +); + + +-- +-- Name: dishes; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.dishes ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + name text NOT NULL, + price numeric(6,2) DEFAULT 0 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL +); + + +-- +-- Name: menu_entries; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.menu_entries ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + menu_date date NOT NULL, + section_key text NOT NULL, + dish_id uuid NOT NULL, + "position" integer DEFAULT 0 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL +); + + +-- +-- Name: profiles; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.profiles ( + id uuid NOT NULL, + email text NOT NULL, + full_name text DEFAULT ''::text NOT NULL, + role text DEFAULT 'staff'::text NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT profiles_role_check CHECK ((role = ANY (ARRAY['admin'::text, 'staff'::text]))) +); + + +-- +-- Name: sections; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.sections ( + key text NOT NULL, + label text NOT NULL, + time_range text NOT NULL, + sort integer NOT NULL +); + + +-- +-- Name: settings; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.settings ( + id integer NOT NULL, + colors jsonb DEFAULT '{}'::jsonb NOT NULL, + logo_path text, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT settings_id_check CHECK ((id = 1)) +); + + +-- +-- Name: additives additives_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.additives + ADD CONSTRAINT additives_pkey PRIMARY KEY (code); + + +-- +-- Name: allergens allergens_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.allergens + ADD CONSTRAINT allergens_pkey PRIMARY KEY (code); + + +-- +-- Name: dishes dishes_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.dishes + ADD CONSTRAINT dishes_pkey PRIMARY KEY (id); + + +-- +-- Name: menu_entries menu_entries_menu_date_section_key_dish_id_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.menu_entries + ADD CONSTRAINT menu_entries_menu_date_section_key_dish_id_key UNIQUE (menu_date, section_key, dish_id); + + +-- +-- Name: menu_entries menu_entries_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.menu_entries + ADD CONSTRAINT menu_entries_pkey PRIMARY KEY (id); + + +-- +-- Name: profiles profiles_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.profiles + ADD CONSTRAINT profiles_pkey PRIMARY KEY (id); + + +-- +-- Name: sections sections_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.sections + ADD CONSTRAINT sections_pkey PRIMARY KEY (key); + + +-- +-- Name: settings settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.settings + ADD CONSTRAINT settings_pkey PRIMARY KEY (id); + + +-- +-- Name: menu_entries_date_idx; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX menu_entries_date_idx ON public.menu_entries USING btree (menu_date); + + +-- +-- Name: dishes dishes_touch_updated_at; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER dishes_touch_updated_at BEFORE UPDATE ON public.dishes FOR EACH ROW EXECUTE FUNCTION public.touch_updated_at(); + + +-- +-- Name: settings settings_touch_updated_at; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER settings_touch_updated_at BEFORE UPDATE ON public.settings FOR EACH ROW EXECUTE FUNCTION public.touch_updated_at(); + + +-- +-- Name: menu_entries menu_entries_dish_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.menu_entries + ADD CONSTRAINT menu_entries_dish_id_fkey FOREIGN KEY (dish_id) REFERENCES public.dishes(id) ON DELETE CASCADE; + + +-- +-- Name: menu_entries menu_entries_section_key_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.menu_entries + ADD CONSTRAINT menu_entries_section_key_fkey FOREIGN KEY (section_key) REFERENCES public.sections(key); + + +-- +-- Name: profiles profiles_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.profiles + ADD CONSTRAINT profiles_id_fkey FOREIGN KEY (id) REFERENCES auth.users(id) ON DELETE CASCADE; + + +-- +-- Name: additives; Type: ROW SECURITY; Schema: public; Owner: - +-- + +ALTER TABLE public.additives ENABLE ROW LEVEL SECURITY; + +-- +-- Name: additives additives_public_read; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY additives_public_read ON public.additives FOR SELECT TO authenticated, anon USING (true); + + +-- +-- Name: additives additives_staff_write; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY additives_staff_write ON public.additives TO authenticated USING ((public.app_role() = ANY (ARRAY['staff'::text, 'admin'::text]))) WITH CHECK ((public.app_role() = ANY (ARRAY['staff'::text, 'admin'::text]))); + + +-- +-- Name: allergens; Type: ROW SECURITY; Schema: public; Owner: - +-- + +ALTER TABLE public.allergens ENABLE ROW LEVEL SECURITY; + +-- +-- Name: allergens allergens_public_read; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY allergens_public_read ON public.allergens FOR SELECT TO authenticated, anon USING (true); + + +-- +-- Name: allergens allergens_staff_write; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY allergens_staff_write ON public.allergens TO authenticated USING ((public.app_role() = ANY (ARRAY['staff'::text, 'admin'::text]))) WITH CHECK ((public.app_role() = ANY (ARRAY['staff'::text, 'admin'::text]))); + + +-- +-- Name: dishes; Type: ROW SECURITY; Schema: public; Owner: - +-- + +ALTER TABLE public.dishes ENABLE ROW LEVEL SECURITY; + +-- +-- Name: dishes dishes_public_read; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY dishes_public_read ON public.dishes FOR SELECT TO authenticated, anon USING (true); + + +-- +-- Name: dishes dishes_staff_write; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY dishes_staff_write ON public.dishes TO authenticated USING ((public.app_role() = ANY (ARRAY['staff'::text, 'admin'::text]))) WITH CHECK ((public.app_role() = ANY (ARRAY['staff'::text, 'admin'::text]))); + + +-- +-- Name: menu_entries; Type: ROW SECURITY; Schema: public; Owner: - +-- + +ALTER TABLE public.menu_entries ENABLE ROW LEVEL SECURITY; + +-- +-- Name: menu_entries menu_entries_public_read; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY menu_entries_public_read ON public.menu_entries FOR SELECT TO authenticated, anon USING (true); + + +-- +-- Name: menu_entries menu_entries_staff_write; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY menu_entries_staff_write ON public.menu_entries TO authenticated USING ((public.app_role() = ANY (ARRAY['staff'::text, 'admin'::text]))) WITH CHECK ((public.app_role() = ANY (ARRAY['staff'::text, 'admin'::text]))); + + +-- +-- Name: profiles; Type: ROW SECURITY; Schema: public; Owner: - +-- + +ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY; + +-- +-- Name: profiles profiles_select_own_or_admin; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY profiles_select_own_or_admin ON public.profiles FOR SELECT TO authenticated USING (((id = ( SELECT auth.uid() AS uid)) OR (public.app_role() = 'admin'::text))); + + +-- +-- Name: sections; Type: ROW SECURITY; Schema: public; Owner: - +-- + +ALTER TABLE public.sections ENABLE ROW LEVEL SECURITY; + +-- +-- Name: sections sections_public_read; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY sections_public_read ON public.sections FOR SELECT TO authenticated, anon USING (true); + + +-- +-- Name: settings; Type: ROW SECURITY; Schema: public; Owner: - +-- + +ALTER TABLE public.settings ENABLE ROW LEVEL SECURITY; + +-- +-- Name: settings settings_admin_update; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY settings_admin_update ON public.settings FOR UPDATE TO authenticated USING ((public.app_role() = 'admin'::text)) WITH CHECK ((public.app_role() = 'admin'::text)); + + +-- +-- Name: settings settings_public_read; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY settings_public_read ON public.settings FOR SELECT TO authenticated, anon USING (true); + + +-- +-- PostgreSQL database dump complete +-- + +\unrestrict 0Sx6NoZQaGnfPJIJyJfoBWP8AEmM74wz3Ic4g8Y4DFplRk7HfQrhCEYG288Lc2B + diff --git a/supabase/local/15_auth_users.sql b/supabase/local/15_auth_users.sql new file mode 100644 index 0000000..aea0c70 --- /dev/null +++ b/supabase/local/15_auth_users.sql @@ -0,0 +1,6 @@ +-- Benutzer-Stammdaten für die lokale Kopie (ohne Passwort-Hashes – +-- Login ist nur gegen die Supabase-Instanz möglich). +insert into auth.users (id, email, raw_user_meta_data) values + ('cee4160a-ab3a-4109-b706-b9f27d515596', 'fw@wildeflorian.de', '{"full_name": "Florian Wilde", "role": "admin"}'), + ('102d405c-b010-41f6-9409-244004a3c567', 'kantine@example.com', '{"full_name": "Kantinen-Team", "role": "staff"}') +on conflict (id) do nothing; diff --git a/supabase/local/20_data.sql b/supabase/local/20_data.sql new file mode 100644 index 0000000..4b1f20c --- /dev/null +++ b/supabase/local/20_data.sql @@ -0,0 +1,198 @@ +-- +-- PostgreSQL database dump +-- + +\restrict HfcGijNcMcy9jPlPpFachgl8LfchhPK39kzgfhc84Q6jsOJpHN3jqf6T368FXri + +-- Dumped from database version 17.6 +-- Dumped by pg_dump version 17.10 + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET transaction_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +-- +-- Data for Name: additives; Type: TABLE DATA; Schema: public; Owner: - +-- + +SET SESSION AUTHORIZATION DEFAULT; + +ALTER TABLE public.additives DISABLE TRIGGER ALL; + +COPY public.additives (code, name, sort) FROM stdin; +1 mit Farbstoff 1 +2 mit Konservierungsstoff 2 +3 mit Antioxidationsmittel 3 +4 mit Geschmacksverstärker 4 +5 geschwefelt 5 +6 geschwärzt 6 +7 gewachst 7 +8 mit Phosphat 8 +9 mit Süßungsmittel(n) 9 +10 enthält eine Phenylalaninquelle 10 +11 koffeinhaltig 11 +\. + + +ALTER TABLE public.additives ENABLE TRIGGER ALL; + +-- +-- Data for Name: allergens; Type: TABLE DATA; Schema: public; Owner: - +-- + +ALTER TABLE public.allergens DISABLE TRIGGER ALL; + +COPY public.allergens (code, name, sort) FROM stdin; +A Glutenhaltiges Getreide 1 +B Krebstiere 2 +C Eier 3 +D Fisch 4 +E Erdnüsse 5 +F Sojabohnen 6 +G Milch (einschließlich Laktose) 7 +H Schalenfrüchte (Nüsse) 8 +I Sellerie 9 +J Senf 10 +K Sesamsamen 11 +L Schwefeldioxid und Sulfite 12 +M Lupinen 13 +N Weichtiere 14 +\. + + +ALTER TABLE public.allergens ENABLE TRIGGER ALL; + +-- +-- Data for Name: dishes; Type: TABLE DATA; Schema: public; Owner: - +-- + +ALTER TABLE public.dishes DISABLE TRIGGER ALL; + +COPY public.dishes (id, name, price, created_at, updated_at) FROM stdin; +2b136266-a80d-4c76-8520-38001c92a634 1 Stk. Rindskäsewurst mit Brötchen 2.30 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +bf612ae7-8cdd-4149-8b21-f651631ccc02 Hackfleischbaguette 3.20 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +81c58cc6-7298-4d4a-9997-71d17df5aedf Knusperhähnchen Wrap 3.70 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +cc7fb9d9-a9ab-4c4c-a376-a8fae0e801c9 Leberkäse im Brötchen 2.30 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +a987c96f-25a0-4e5e-b8a8-aab683a01feb Chili con Carne mit Brötchen 3.90 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +14ef6893-93a7-4649-afe3-d6b6bdf5903c Schnitzel Baguette 3.50 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +ec3c5e37-9cbc-4c92-ab05-1e3fb942c504 Penne mit Grünen Spargel und Garnelenspieße 5.90 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +dbe5ee6e-8b04-4bf7-99bb-f936f6564217 Bratkartoffel Gemüse Pfanne mit Hähnchenbrust und Dip 5.90 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +c0613fe7-e5c6-489e-afe5-6da2533b2bd4 Schweinefilet im Speckmantel dazu Rahmsoße und Butterspätzle 5.90 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +c5cfa5b4-e502-4b56-b579-b9fbbf817f25 Penne mit Grünen Spargel, get. Tomaten und Cherrytomaten 5.30 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +f8ba1844-1f23-4b23-9e03-f59148f8b2ed Spaghetti mit fruchtiger Tomatensauce und Parmesan 5.30 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +7a6fed05-e0f5-4e97-bdd4-a46c5ef1376a Gebackener Feta mit griechischen Bauernsalat und Baguette 5.30 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +ff40ea65-63bc-4d01-b626-e0c9e5d2acb3 Gemüse-Curry mit Basmatireis 4.90 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +ea26f18b-ddf3-4899-95e7-5dbd0878d90c Kartoffelcremesuppe 1.50 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +6222d5f4-05e3-4af4-a41c-3f8b4c9c5c78 Gulaschsuppe 2.50 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +3c8cf0c2-b0a9-43e3-8233-723d5718a157 Tomatensuppe mit Croutons 1.80 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +2dd85835-5425-4271-9fc0-e5215bbce476 Kürbiscremesuppe 1.80 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +06df753a-65ed-4bd0-a325-d32c78ec88fa Linseneintopf mit Würstchen 2.20 2026-07-17 15:17:02.979184+00 2026-07-17 15:17:02.979184+00 +\. + + +ALTER TABLE public.dishes ENABLE TRIGGER ALL; + +-- +-- Data for Name: sections; Type: TABLE DATA; Schema: public; Owner: - +-- + +ALTER TABLE public.sections DISABLE TRIGGER ALL; + +COPY public.sections (key, label, time_range, sort) FROM stdin; +brotzeit Brotzeit 09:00 - 10:00 1 +mittagessen Mittagessen 11:30 - 13:30 2 +mittagessen_veg Mittagessen vegetarisch 11:30 - 13:30 3 +suppe Suppe 11:30 - 13:30 4 +\. + + +ALTER TABLE public.sections ENABLE TRIGGER ALL; + +-- +-- Data for Name: menu_entries; Type: TABLE DATA; Schema: public; Owner: - +-- + +ALTER TABLE public.menu_entries DISABLE TRIGGER ALL; + +COPY public.menu_entries (id, menu_date, section_key, dish_id, "position", created_at) FROM stdin; +5d1ea849-61b3-48ac-b1e9-48b6b2c7d8c1 2026-07-13 brotzeit 2b136266-a80d-4c76-8520-38001c92a634 0 2026-07-17 15:17:02.979184+00 +70469091-417b-47ed-aab5-747ff97e4ad4 2026-07-14 brotzeit bf612ae7-8cdd-4149-8b21-f651631ccc02 0 2026-07-17 15:17:02.979184+00 +1e1f9b4e-75e7-413f-a747-c2884675d9f7 2026-07-15 brotzeit 81c58cc6-7298-4d4a-9997-71d17df5aedf 0 2026-07-17 15:17:02.979184+00 +7b2089f7-7c01-4d6a-9e68-ebfa594bb713 2026-07-16 brotzeit cc7fb9d9-a9ab-4c4c-a376-a8fae0e801c9 0 2026-07-17 15:17:02.979184+00 +d6e24a0d-cc32-438d-9d91-e39ecbb82d5d 2026-07-17 brotzeit a987c96f-25a0-4e5e-b8a8-aab683a01feb 0 2026-07-17 15:17:02.979184+00 +c165765a-1eb3-4d7e-9566-3768e9007793 2026-07-13 mittagessen 14ef6893-93a7-4649-afe3-d6b6bdf5903c 0 2026-07-17 15:17:02.979184+00 +78be0a94-1b31-47ef-af62-40548d75aa4e 2026-07-14 mittagessen ec3c5e37-9cbc-4c92-ab05-1e3fb942c504 0 2026-07-17 15:17:02.979184+00 +0635198c-6aa9-4811-a8fd-67e31174eb73 2026-07-15 mittagessen dbe5ee6e-8b04-4bf7-99bb-f936f6564217 0 2026-07-17 15:17:02.979184+00 +f02305b6-7650-4b52-b440-3df7045e17a7 2026-07-16 mittagessen c0613fe7-e5c6-489e-afe5-6da2533b2bd4 0 2026-07-17 15:17:02.979184+00 +b838a6a4-1a58-469e-9201-af686c7a780a 2026-07-14 mittagessen_veg c5cfa5b4-e502-4b56-b579-b9fbbf817f25 0 2026-07-17 15:17:02.979184+00 +4886ee1a-f8fd-4548-8483-893a0f2dd9aa 2026-07-15 mittagessen_veg f8ba1844-1f23-4b23-9e03-f59148f8b2ed 0 2026-07-17 15:17:02.979184+00 +1f6400bb-0b9a-444c-b793-e1cbd96ec215 2026-07-16 mittagessen_veg 7a6fed05-e0f5-4e97-bdd4-a46c5ef1376a 0 2026-07-17 15:17:02.979184+00 +7df88a12-6fb8-457e-8cf8-5ddc43e06583 2026-07-13 suppe ea26f18b-ddf3-4899-95e7-5dbd0878d90c 0 2026-07-17 15:17:02.979184+00 +e2bfe62e-12c4-4f68-a7e7-ca1ee30a6039 2026-07-14 suppe 6222d5f4-05e3-4af4-a41c-3f8b4c9c5c78 0 2026-07-17 15:17:02.979184+00 +662902e0-bb5e-4268-b977-cef2ac20dc35 2026-07-15 suppe 3c8cf0c2-b0a9-43e3-8233-723d5718a157 0 2026-07-17 15:17:02.979184+00 +6083a3f3-a54e-40c5-be1f-c96e474eb8a0 2026-07-16 suppe 2dd85835-5425-4271-9fc0-e5215bbce476 0 2026-07-17 15:17:02.979184+00 +36279cd1-b0e2-46a8-b46c-c23f9f5dbb1b 2026-07-17 suppe 06df753a-65ed-4bd0-a325-d32c78ec88fa 0 2026-07-17 15:17:02.979184+00 +ae3f7ced-23b1-42a9-a5d4-2bfab6c333b7 2026-07-22 brotzeit 2b136266-a80d-4c76-8520-38001c92a634 0 2026-07-17 15:17:02.979184+00 +bfa36cb8-82d6-466c-b954-bf82c6a67b95 2026-07-23 brotzeit bf612ae7-8cdd-4149-8b21-f651631ccc02 0 2026-07-17 15:17:02.979184+00 +b86caf93-34eb-46a3-bbe4-3a67dcf79be0 2026-07-21 brotzeit 81c58cc6-7298-4d4a-9997-71d17df5aedf 0 2026-07-17 15:17:02.979184+00 +d8a962cd-f1cf-4f87-95fb-f5af79cbd0a5 2026-07-20 brotzeit cc7fb9d9-a9ab-4c4c-a376-a8fae0e801c9 0 2026-07-17 15:17:02.979184+00 +c800ef28-70ba-4439-8f1d-e5dcec3ce1c6 2026-07-24 brotzeit a987c96f-25a0-4e5e-b8a8-aab683a01feb 0 2026-07-17 15:17:02.979184+00 +a5c54296-1667-4d5d-a62d-3983e1643959 2026-07-22 mittagessen 14ef6893-93a7-4649-afe3-d6b6bdf5903c 0 2026-07-17 15:17:02.979184+00 +4a06dd6c-7de8-4628-b491-3dafd409f344 2026-07-23 mittagessen ec3c5e37-9cbc-4c92-ab05-1e3fb942c504 0 2026-07-17 15:17:02.979184+00 +ea9a2936-95bf-4cbd-a013-db7ba995efce 2026-07-20 mittagessen dbe5ee6e-8b04-4bf7-99bb-f936f6564217 0 2026-07-17 15:17:02.979184+00 +64bc501f-dbcd-474c-b47b-1e99670a3c3e 2026-07-21 mittagessen c0613fe7-e5c6-489e-afe5-6da2533b2bd4 0 2026-07-17 15:17:02.979184+00 +dd4105b4-76b8-4ea1-8ee0-6db663a1ffa8 2026-07-23 mittagessen_veg c5cfa5b4-e502-4b56-b579-b9fbbf817f25 0 2026-07-17 15:17:02.979184+00 +bac80cc9-ad0e-4cee-81ae-8aa405cad1b9 2026-07-21 mittagessen_veg f8ba1844-1f23-4b23-9e03-f59148f8b2ed 0 2026-07-17 15:17:02.979184+00 +62bbb0f9-88e2-4b9f-a7e5-c0dab5ff54c8 2026-07-22 mittagessen_veg 7a6fed05-e0f5-4e97-bdd4-a46c5ef1376a 0 2026-07-17 15:17:02.979184+00 +167e0869-126d-4ab7-8e74-051e5c782865 2026-07-20 mittagessen_veg ff40ea65-63bc-4d01-b626-e0c9e5d2acb3 0 2026-07-17 15:17:02.979184+00 +34031197-4c3a-4b7e-bc05-7ad7254e8348 2026-07-21 suppe ea26f18b-ddf3-4899-95e7-5dbd0878d90c 0 2026-07-17 15:17:02.979184+00 +a6f66639-7a0a-4129-bcea-c6ac9cbccac3 2026-07-20 suppe 6222d5f4-05e3-4af4-a41c-3f8b4c9c5c78 0 2026-07-17 15:17:02.979184+00 +b0dbf487-c704-4ab2-af67-082addc88039 2026-07-23 suppe 3c8cf0c2-b0a9-43e3-8233-723d5718a157 0 2026-07-17 15:17:02.979184+00 +d7b5d414-85c2-495a-9945-2ffc10de32ea 2026-07-24 suppe 2dd85835-5425-4271-9fc0-e5215bbce476 0 2026-07-17 15:17:02.979184+00 +7a025e66-44b7-43e7-a51b-5564ab8150b1 2026-07-22 suppe 06df753a-65ed-4bd0-a325-d32c78ec88fa 0 2026-07-17 15:17:02.979184+00 +\. + + +ALTER TABLE public.menu_entries ENABLE TRIGGER ALL; + +-- +-- Data for Name: profiles; Type: TABLE DATA; Schema: public; Owner: - +-- + +ALTER TABLE public.profiles DISABLE TRIGGER ALL; + +COPY public.profiles (id, email, full_name, role, created_at) FROM stdin; +cee4160a-ab3a-4109-b706-b9f27d515596 fw@wildeflorian.de Florian Wilde admin 2026-07-17 15:17:33.46696+00 +102d405c-b010-41f6-9409-244004a3c567 kantine@example.com Kantinen-Team staff 2026-07-17 15:17:34.233848+00 +\. + + +ALTER TABLE public.profiles ENABLE TRIGGER ALL; + +-- +-- Data for Name: settings; Type: TABLE DATA; Schema: public; Owner: - +-- + +ALTER TABLE public.settings DISABLE TRIGGER ALL; + +COPY public.settings (id, colors, logo_path, updated_at) FROM stdin; +1 {"rowBg": "#e3e4f1", "accent": "#ff6900", "addBtn": "#6da54c", "primary": "#003388", "rowBgAlt": "#f4f4fa", "deleteBtn": "#e2371d", "headerText": "#ffffff", "primaryDark": "#0d315c"} \N 2026-07-17 15:39:01.866456+00 +\. + + +ALTER TABLE public.settings ENABLE TRIGGER ALL; + +-- +-- PostgreSQL database dump complete +-- + +\unrestrict HfcGijNcMcy9jPlPpFachgl8LfchhPK39kzgfhc84Q6jsOJpHN3jqf6T368FXri +