Kuendigungsschutz bekommt einen Personenkreis, die Behinderung eigene Felder
Anforderungen 5 und 5a aus dem Workshop. Migration 20260915120000.
Bisher gab es ein Kennzeichen und ein Enddatum. Das beantwortet "darf hier
ohne Weiteres beendet werden?" — nicht aber, *warum* jemand geschuetzt ist,
und davon haengt ab, wer zustimmen muss. Nachzusehen war das nur im
Papierakt, also dort, wo unter Zeitdruck niemand nachsieht.
Zwoelf Personenkreise als CHECK auf text und nicht als Aufzaehlungstyp: die
Liste ist Rechtslage und aendert sich mit dem Gesetz, ein Typ liesse einen
zurueckgenommenen Wert fuer immer stehen. Die Oberflaeche liest dieselbe
Liste aus lib/kuendigungsschutz.ts; ein Test liest die Migration und haelt
beide gegeneinander, damit die begruendete Doppelung keine stille wird.
Die begueenstigte Behinderung bekommt Kennzeichen, Grad, Beginn und Ende —
vier Spalten und nicht eine zusammengesetzte, weil in Excel danach
gefiltert und summiert wird. Datenbankseitig sind sie *nicht* an den
Personenkreis gekettet: eine solche Bedingung scheiterte genau dann, wenn
jemand den Kreis korrigiert und der Grad noch dransteht. Die Oberflaeche
stellt den Zusammenhang her.
Dazu zwei Dinge, die auf dem Weg auffielen:
* Der Nachtlauf wendete bei einer auf spaeter datierten Aenderung nur
Person und Vertrag an — die ganze Gruppe "role" fiel weg. Betriebsrat,
Dienstwagen, Kollektivvertrag, Arbeitstage, Teilzeit und
Kuendigungsschutz wurden erfasst, in der Historie vermerkt, protokolliert
und am Stichtag nicht geschrieben. Sichtbar wurde das nie. Die neuen
Felder haetten den Fehler geerbt; er ist jetzt fuer alle behoben.
* Der Mitarbeiter-Export filterte ohne Stichtag ueber die Spalte `status`,
mit Stichtag ueber die Ableitung. Der Export nach "Ausgetreten" liess
damit genau die Leute aus, die gerade ausgetreten sind.
This commit is contained in:
@@ -18,6 +18,12 @@ const WERT: RoleEmploymentValue = {
|
||||
isCLevel: false,
|
||||
hasKuendigungsschutz: false,
|
||||
kuendigungsschutzBis: "",
|
||||
kuendigungsschutzGrund: "",
|
||||
kuendigungsschutzAb: "",
|
||||
istBeguenstigtBehindert: false,
|
||||
behinderungGrad: "",
|
||||
behinderungAb: "",
|
||||
behinderungBis: "",
|
||||
};
|
||||
|
||||
function feld(teil: Partial<RoleEmploymentValue> = {}) {
|
||||
|
||||
61
tests/unit/kuendigungsschutz.test.ts
Normal file
61
tests/unit/kuendigungsschutz.test.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
BEGUENSTIGUNG_AB_GRAD,
|
||||
GRUND_BEGUENSTIGT_BEHINDERT,
|
||||
KUENDIGUNGSSCHUTZ_GRUENDE,
|
||||
istKuendigungsschutzGrund,
|
||||
} from "@/lib/kuendigungsschutz";
|
||||
|
||||
// Die Liste der Personenkreise steht zweimal: in lib/kuendigungsschutz.ts für
|
||||
// die Oberfläche und als CHECK in der Migration für die Datenbank. Die
|
||||
// Doppelung ist begründet (siehe dort) — aber eine begründete Doppelung ist
|
||||
// immer noch eine, und zwei Listen laufen auseinander. Auffallen würde es
|
||||
// erst beim Speichern: die Oberfläche böte einen Wert an, den die Bedingung
|
||||
// zurückweist, und die Benutzerin sähe einen Fehler aus der Datenbank.
|
||||
//
|
||||
// Deshalb liest dieser Test die Migration und hält die beiden gegeneinander.
|
||||
// Er braucht keine Datenbank — die Datei genügt.
|
||||
|
||||
const MIGRATION = join(
|
||||
process.cwd(),
|
||||
"db/migrations/20260915120000_kuendigungsschutz_personenkreis_und_behinderung.sql"
|
||||
);
|
||||
|
||||
function werteAusDerBedingung(): string[] {
|
||||
const sql = readFileSync(MIGRATION, "utf8");
|
||||
const block = sql.match(/chk_kuendigungsschutz_personenkreis\s+check[\s\S]*?\);/)?.[0];
|
||||
expect(block, "Die Bedingung steht nicht mehr in der Migration").toBeDefined();
|
||||
// Die Werte stehen als einfach zitierte Zeichenketten in der in-Liste.
|
||||
return [...block!.matchAll(/'([^']+)'/g)].map((m) => m[1]);
|
||||
}
|
||||
|
||||
describe("Die Personenkreise", () => {
|
||||
it("stimmen mit der Bedingung in der Datenbank überein", () => {
|
||||
expect(new Set(werteAusDerBedingung())).toEqual(new Set(KUENDIGUNGSSCHUTZ_GRUENDE));
|
||||
});
|
||||
|
||||
it("stehen jeder nur einmal", () => {
|
||||
expect(new Set(KUENDIGUNGSSCHUTZ_GRUENDE).size).toBe(KUENDIGUNGSSCHUTZ_GRUENDE.length);
|
||||
});
|
||||
|
||||
it("enthalten den Kreis, an dem die Angaben zur Behinderung hängen", () => {
|
||||
// Wird er umbenannt, blendet die Akte die Felder nicht mehr auf — und
|
||||
// niemand bemerkt es, weil nichts fehlschlägt.
|
||||
expect(KUENDIGUNGSSCHUTZ_GRUENDE).toContain(GRUND_BEGUENSTIGT_BEHINDERT);
|
||||
});
|
||||
|
||||
it("weisen zurück, was nicht in der Liste steht", () => {
|
||||
expect(istKuendigungsschutzGrund("Eltern")).toBe(true);
|
||||
expect(istKuendigungsschutzGrund("Irgendetwas")).toBe(false);
|
||||
expect(istKuendigungsschutzGrund("")).toBe(false);
|
||||
expect(istKuendigungsschutzGrund(null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Die Grenze der Begünstigung", () => {
|
||||
it("liegt bei 50 Prozent", () => {
|
||||
expect(BEGUENSTIGUNG_AB_GRAD).toBe(50);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user