-- ==================================================================== -- 0052_appointment_requests — Terminanfragen (Booking Phase 0) -- ==================================================================== -- Native Terminanfrage über die Visitenkarte: Gast schlägt Wunschtermine -- vor → landet als Anfrage beim Mitarbeiter (E-Mail + Portal-Inbox). -- KEINE Kalenderanbindung (das ist Phase 1, Microsoft Graph). Siehe -- docs/booking-modul.md. -- Opt-in pro Mitarbeiter: nur wer das aktiviert, zeigt „Termin anfragen". alter table public.employees add column if not exists accept_appointments boolean not null default false; comment on column public.employees.accept_appointments is 'Wenn true, zeigt die öffentliche Karte ein „Termin anfragen"-Formular.'; create table if not exists public.appointment_requests ( id uuid primary key default gen_random_uuid(), employee_id uuid not null references public.employees(id) on delete cascade, guest_name text not null, guest_email text, guest_phone text, company text, subject text, message text, -- Wunschtermine: [{ "date": "2026-07-01", "period": "vormittags" }] (max 3) preferred_slots jsonb not null default '[]'::jsonb, meeting_type text, -- 'vor_ort' | 'telefon' | 'video' | null status text not null default 'new', -- 'new' | 'confirmed' | 'declined' | 'cancelled' consent_given boolean not null default false, source_url text, read_at timestamptz, notes text, -- interne Notiz des Mitarbeiters created_at timestamptz not null default now() ); create index if not exists appointment_requests_employee_idx on public.appointment_requests (employee_id, created_at desc); -- RLS: admin-only (Default deny, kein anon-Grant). Öffentliche Inserts -- laufen ausschließlich über die Service-Role-Action (wie card_leads). alter table public.appointment_requests enable row level security; grant select, insert, update, delete on public.appointment_requests to service_role;