Migration 020 renamed paliad.can_see_projekt → can_see_project (and
notiz_is_visible → note_is_visible) via ALTER FUNCTION but never rewrote
the bodies. On production the bodies still queried paliad.projekte /
projekt_teams / fristen / termine / projekt_events — all of which were
dropped or renamed in 018+020. Every RLS-enforced read against the new
English tables exploded with `relation "paliad.projekte" does not exist`,
breaking /api/projects, /api/deadlines, /api/appointments etc.
Same problem for the trigger functions paliad.projekte_sync_path() and
paliad.projekte_rewrite_subtree() — kept their German names and German
bodies; the triggers on paliad.projects still pointed at them.
Migration 021:
* DROP FUNCTION ... CASCADE drops can_see_project / note_is_visible
along with their 21 dependent RLS policies (whose names were still
German on prod: projekte_*, projekt_teams_*, fristen_all, termine_*,
parteien_all, dokumente_all, projekt_events_all, notizen_all,
checklist_instances_*).
* Recreates the two functions with English bodies + English parameter
names and rebuilds every dependent policy under its canonical
English name (matching migration 018).
* Drops the German trigger functions/triggers on paliad.projects and
recreates them as projects_sync_path / projects_rewrite_subtree.
Idempotent on a fresh DB (where everything is already English): the
CASCADE drops the same policies and the recreate produces an identical
end state.
Verified by running the up.sql in BEGIN/ROLLBACK against the actual
youpc prod Postgres — 21 policies dropped, 21 recreated, function
bodies now reference paliad.projects / project_teams / etc.
Refs: tests/smoke-auth-2026-04-25.md (Bug 3, root cause for Bugs 1+2).