Ask for a residence permit only where one is needed
Employees from outside the EU, the EEA and Switzerland need a residence permit, and HR needs to know when it expires — about eighty people in the current data, across Türkei, Serbien and Bosnien. Two columns, the same shape as the dismissal protection: a flag and a date that only means anything with it. The date is optional, because an open-ended permit has none and a mandatory field would force an invented one. The nationality coupling deliberately stays out of the database. Putting it there would mean keeping the country list in two places — SQL and lib/countries.ts, where the picker needs it anyway — so an EU accession would become a migration instead of a line in a list. Worse, correcting somebody's nationality would fail the constraint while the old permit was still attached, which is exactly the moment someone is fixing a mistake. The UI decides whether the fields appear, and clears them when the nationality moves into the free-movement area. So the list is the load-bearing part, and it is tested: 31 entries, all of them values the picker can actually produce, no duplicates, no third countries. A missing nationality reads as "no permit required" — an unanswered question is a reason to record it, not to demand papers. The permit shows on the Stammdaten tab only for the nationalities it applies to. A line reading "Aufenthaltstitel: Nein" under an Austrian citizenship would look like information rather than a question that does not arise. Filter by it and by when it expires — the question behind that being "whose permit runs out next quarter" — plus columns in the export. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,8 @@ function mitarbeiter(teil: Partial<EmployeeRow> = {}): EmployeeRow {
|
||||
birth_date: "1990-04-01",
|
||||
sv_nummer: null,
|
||||
nationality: "Österreich",
|
||||
hat_aufenthaltstitel: false,
|
||||
aufenthaltstitel_bis: null,
|
||||
address: null,
|
||||
address_country: null,
|
||||
postal_code: null,
|
||||
|
||||
@@ -21,6 +21,8 @@ function mitarbeiter(teil: Partial<EmployeeRow> = {}): EmployeeRow {
|
||||
birth_date: "1990-04-01",
|
||||
sv_nummer: null,
|
||||
nationality: "Österreich",
|
||||
hat_aufenthaltstitel: false,
|
||||
aufenthaltstitel_bis: null,
|
||||
address: null,
|
||||
address_country: null,
|
||||
postal_code: null,
|
||||
|
||||
59
tests/unit/countries.test.ts
Normal file
59
tests/unit/countries.test.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { brauchtAufenthaltstitel, FREIZUEGIGKEIT, UN_COUNTRIES } from "@/lib/countries";
|
||||
|
||||
// Wer keinen Aufenthaltstitel braucht, soll auch nicht danach gefragt werden.
|
||||
// Die Liste entscheidet darüber, ob die Felder im Formular überhaupt
|
||||
// erscheinen und ob sie beim Wechsel der Staatsbürgerschaft geleert werden —
|
||||
// die Datenbank prüft diese Kopplung bewusst nicht.
|
||||
|
||||
describe("FREIZUEGIGKEIT", () => {
|
||||
it("umfasst EU, EWR und die Schweiz", () => {
|
||||
expect(FREIZUEGIGKEIT).toHaveLength(31); // 27 + Island/Liechtenstein/Norwegen + Schweiz
|
||||
for (const land of ["Österreich", "Deutschland", "Kroatien", "Zypern", "Island", "Liechtenstein", "Norwegen", "Schweiz"]) {
|
||||
expect(FREIZUEGIGKEIT).toContain(land);
|
||||
}
|
||||
});
|
||||
|
||||
it("nennt nur Länder, die es im Auswahlfeld auch gibt", () => {
|
||||
// Sonst stünde ein Land auf der Liste, das niemand auswählen kann — die
|
||||
// Regel liefe für einen Wert, der nie vorkommt.
|
||||
for (const land of FREIZUEGIGKEIT) expect(UN_COUNTRIES).toContain(land);
|
||||
});
|
||||
|
||||
it("führt kein Land doppelt", () => {
|
||||
expect(new Set(FREIZUEGIGKEIT).size).toBe(FREIZUEGIGKEIT.length);
|
||||
});
|
||||
|
||||
it("hält Drittstaaten heraus", () => {
|
||||
for (const land of ["Türkei", "Serbien", "Bosnien und Herzegowina", "Vereinigtes Königreich"]) {
|
||||
expect(FREIZUEGIGKEIT).not.toContain(land);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("brauchtAufenthaltstitel", () => {
|
||||
it("verneint bei Freizügigkeit", () => {
|
||||
for (const land of ["Österreich", "Deutschland", "Schweiz", "Norwegen"]) {
|
||||
expect(brauchtAufenthaltstitel(land)).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
it("bejaht bei Drittstaaten", () => {
|
||||
// Diese drei stellen im Bestand rund achtzig Personen.
|
||||
for (const land of ["Türkei", "Serbien", "Bosnien"]) {
|
||||
expect(brauchtAufenthaltstitel(land)).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("verneint bei fehlender Angabe", () => {
|
||||
// Eine fehlende Staatsbürgerschaft ist kein Anlass, einen Titel zu
|
||||
// verlangen — sie ist ein Anlass, sie zu erfassen.
|
||||
for (const leer of ["", " ", null, undefined]) {
|
||||
expect(brauchtAufenthaltstitel(leer)).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
it("stört sich nicht an Leerzeichen am Rand", () => {
|
||||
expect(brauchtAufenthaltstitel(" Österreich ")).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user