84 lines
3.0 KiB
SQL
84 lines
3.0 KiB
SQL
-- Mehrere Visitenkarten pro Person.
|
|
-- ====================================================================
|
|
-- Use-Case: Geschäftsführer Felix Zösch hat eine Karte als „GF
|
|
-- Stadtwerk", eine zweite als „BDEW-Ausschuss-Vertreter", eine dritte
|
|
-- als „VKU-Delegierter". Alle Karten haben eigenen Slug, eigene
|
|
-- Position, eigene Kontaktdaten — referenzieren aber dieselbe Person
|
|
-- (gleicher Name, gleiches Foto, gleicher akademischer Titel).
|
|
--
|
|
-- Migration:
|
|
-- 1. persons-Tabelle anlegen
|
|
-- 2. employees.person_id (nullable FK) ergänzen
|
|
-- 3. Backfill: pro existierendem Employee eine Person anlegen +
|
|
-- verknüpfen (id-mäßig 1:1, semantisch erstmal eindeutig)
|
|
-- 4. Spätere Mehrfach-Karten setzen denselben person_id auf weiteren
|
|
-- employees-Zeilen
|
|
--
|
|
-- Für die Rückwärtskompatibilität bleiben die name- und photo-Felder
|
|
-- in employees erhalten — sie sind die maßgeblichen Daten für die
|
|
-- jeweilige Karte. Person-Felder werden für „Person-Übersicht" im
|
|
-- Verzeichnis genutzt und können in v2 als Default-Quelle für neue
|
|
-- Karten dienen.
|
|
|
|
create table if not exists public.persons (
|
|
id uuid primary key default gen_random_uuid(),
|
|
academic_title text,
|
|
first_name text not null,
|
|
last_name text not null,
|
|
photo_url text,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now()
|
|
);
|
|
|
|
create index if not exists persons_last_name_idx
|
|
on public.persons (last_name, first_name);
|
|
|
|
drop trigger if exists trg_persons_updated_at on public.persons;
|
|
create trigger trg_persons_updated_at
|
|
before update on public.persons
|
|
for each row execute function public.set_updated_at();
|
|
|
|
alter table public.employees
|
|
add column if not exists person_id uuid
|
|
references public.persons(id) on delete set null;
|
|
|
|
create index if not exists employees_person_id_idx
|
|
on public.employees (person_id);
|
|
|
|
-- Backfill: für jeden Employee ohne person_id eine Person anlegen
|
|
-- und verknüpfen.
|
|
do $$
|
|
declare
|
|
e record;
|
|
new_person_id uuid;
|
|
begin
|
|
for e in
|
|
select id, academic_title, first_name, last_name, photo_url
|
|
from public.employees
|
|
where person_id is null
|
|
loop
|
|
insert into public.persons (academic_title, first_name, last_name, photo_url)
|
|
values (e.academic_title, e.first_name, e.last_name, e.photo_url)
|
|
returning id into new_person_id;
|
|
update public.employees
|
|
set person_id = new_person_id
|
|
where id = e.id;
|
|
end loop;
|
|
end $$;
|
|
|
|
-- Anon-Zugriff: person_id darf gelesen werden, damit
|
|
-- "weitere Karten dieser Person"-Liste auf öffentlicher Seite
|
|
-- möglich ist.
|
|
grant select (person_id) on public.employees to anon;
|
|
|
|
-- persons-Tabelle: anon darf basics (name, foto) lesen — wird auf
|
|
-- der "weitere Karten"-Liste der öffentlichen Karte angezeigt.
|
|
alter table public.persons enable row level security;
|
|
create policy "public_read_persons"
|
|
on public.persons for select
|
|
to anon using (true);
|
|
revoke all on public.persons from anon;
|
|
grant select
|
|
(id, academic_title, first_name, last_name, photo_url)
|
|
on public.persons to anon;
|