Files
alpenwerk-hr/db/migrations/20260929160000_wiedereintritt_status_cast.sql
Andrei Laas be9ca4758f
Some checks failed
CI / Lint, Typen, Tests, Build (push) Successful in 11m36s
CI / Migrationen auf leerer Datenbank (push) Has been cancelled
Wiedereintritt wieder moeglich, und die Panels lesen die Akte neu
Zwei Befunde aus dem Test vom 29.09., beide Klasse A.

K.01 -- rehire_employee scheitert bei jedem Aufruf: der case-Ausdruck fuer den
Status liefert text, die Spalte ist ein Aufzaehlungstyp. Genau das wurde am
10.08. schon einmal behoben. Vier spaetere Migrationen haben die Funktion neu
erzeugt und den Zusatz nicht mitgenommen -- zwei davon aus einer aelteren
Datei, zwei aus der laufenden Definition. Daraus die Lehre, die vorher nicht
dastand: aus dem laufenden Stand zu erzeugen schuetzt davor, Verhalten zu
verlieren, nicht davor, einen bereits vorhandenen Fehler mitzunehmen. Die
Selbstpruefung benennt deshalb jetzt das Erwartete und nicht nur das Neue.

H.05 -- "Daten aendern" schrieb veraltete Werte zurueck. Die Panels bleiben
eingebunden, damit ihr Ein- und Ausfahren laufen kann, belegen ihre Felder aber
mit useState(employee.…) vor -- und das laeuft nur beim ersten Aufbau. Nach
einer Befoerderung brachte router.refresh() die frische Akte herein, der
Zustand im Panel blieb der von vorhin, und beim naechsten Speichern ging er als
Ganzes an change_employee_data: der eben gesetzte Hay-Grade stand wieder auf
dem alten Wert. Jedes Panel bekommt jetzt einen key aus employees.updated_at,
der sich bei jeder Aenderung an der Zeile bewegt und sonst nie. Der
Wiedereintritts-Assistent daneben macht es seit jeher so.
2026-09-29 18:42:30 +02:00

104 lines
4.3 KiB
SQL

-- Wiedereintritt: der Umwandlungsschritt beim Status, zum zweiten Mal
--
-- rehire_employee scheitert bei jedem Aufruf mit
--
-- column "status" is of type employment_status but expression is of type text
--
-- Der case-Ausdruck liefert `text` (beide Zweige sind Literale ohne Typ), die
-- Spalte ist ein Aufzählungstyp, und Postgres wandelt beim Zuweisen nicht von
-- selbst um. Genau dieser Fehler wurde am 10.08. mit
-- 20260810130000_fix_rehire_status_cast.sql behoben.
--
-- ═══ Warum er wieder da ist ═══════════════════════════════════════
--
-- Vier spätere Migrationen haben rehire_employee neu erzeugt und dabei den
-- Zusatz nicht mitgenommen: 20260917100000 (Austrittsart), 20260917130000
-- (Wiedereintritt mit Stammdaten), 20260923120000 (Firmen-E-Mail) und
-- 20260928100000 (Cornerstone-ID).
--
-- Die ersten beiden haben den Rumpf aus einer älteren Datei kopiert — der
-- Fall, vor dem der Abschnitt „create or replace aus veraltetem Muster" warnt.
-- Die letzten beiden sind aus der **laufenden** Definition erzeugt worden und
-- haben damit getreu weitergetragen, was seit dem 17.09. dort stand. Daraus
-- die Lehre, die vorher nicht dastand: das Erzeugen aus dem laufenden Stand
-- schützt davor, Verhalten zu **verlieren** — nicht davor, einen bereits
-- vorhandenen Fehler **mitzunehmen**. Dagegen hilft nur eine Selbstprüfung,
-- die das Erwartete benennt, statt nur das Neue zu prüfen.
--
-- Deshalb steht unten nicht bloss „der Zusatz ist da", sondern eine Prüfung,
-- die jede künftige Neuerzeugung dieser Funktion mitnehmen kann.
do $migration$
declare
v_alt constant text := $anker$status = case when v_date <= current_date then 'Aktiv' else 'Geplant' end,$anker$;
v_neu constant text := $anker$status = (case when v_date <= current_date then 'Aktiv' else 'Geplant' end)::employment_status,$anker$;
v_def text;
v_anzahl int;
begin
select pg_get_functiondef(p.oid) into v_def
from pg_proc p join pg_namespace n on n.oid = p.pronamespace
where n.nspname = 'public' and p.proname = 'rehire_employee' and p.prokind = 'f';
if v_def is null then
raise exception 'rehire_employee ist nicht vorhanden.';
end if;
-- Schon in Ordnung? Dann nichts tun. Die Migration soll auch auf einer
-- Datenbank durchlaufen, auf der die Funktion aus einer künftigen Datei mit
-- Umwandlung entstanden ist.
if v_def like '%end)::employment_status%' then
raise notice 'rehire_employee wandelt den Status bereits um.';
return;
end if;
v_anzahl := (length(v_def) - length(replace(v_def, v_alt, ''))) / length(v_alt);
if v_anzahl <> 1 then
raise exception 'Die Statuszuweisung kommt % mal vor, erwartet genau einmal.', v_anzahl;
end if;
execute replace(v_def, v_alt, v_neu);
end
$migration$;
-- Selbstprüfung.
--
-- Geprüft wird die Umwandlung **und** alles, was an dieser Funktion schon
-- einmal verlorengegangen ist. Wer sie das nächste Mal neu erzeugt, kopiert
-- diesen Block am besten mit.
do $$
declare
v_def text;
begin
select pg_get_functiondef(p.oid) into v_def
from pg_proc p join pg_namespace n on n.oid = p.pronamespace
where n.nspname = 'public' and p.proname = 'rehire_employee' and p.prokind = 'f';
if v_def not like '%end)::employment_status%' then
raise exception 'rehire_employee wandelt den Status nicht um — der Wiedereintritt scheitert bei jedem Aufruf.';
end if;
if v_def not like '%require_hr_admin()%' then
raise exception 'rehire_employee prueft die Rechte nicht.';
end if;
if v_def not like '%search_path%' then
raise exception 'rehire_employee hat keinen festen search_path.';
end if;
-- Die Stammdaten, die der Wiedereintritt seit 20260917130000 mitschreibt.
-- Ohne sie zeigt der Assistent Felder an und wirft ihre Werte weg.
if v_def not like '%cornerstone_id%' then
raise exception 'rehire_employee hat die Cornerstone-ID verloren.';
end if;
if v_def not like '%company_email%' then
raise exception 'rehire_employee hat die Firmen-E-Mail verloren.';
end if;
if v_def not like '%title_prefix%' then
raise exception 'rehire_employee hat die Titel verloren.';
end if;
if v_def not like '%paygrade%' then
raise exception 'rehire_employee hat den Hay-Grade verloren.';
end if;
raise notice 'rehire_employee: Statusumwandlung und Stammdaten vollstaendig.';
end
$$;