TeamVis Self-Host-Bundle v0.31.0
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
-- 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;
|
||||
Reference in New Issue
Block a user