Zwei Fehler, beide erst im Betrieb sichtbar. 1. Schritt 3 der Ersteinrichtung meldete "Bitte pruefe die markierten Felder" - und markierte keines. Man kam dort nicht weiter. Das kurze Formular schickt neun Felder, das vollstaendige unter Stammdaten alle. Beide gehen durch dasselbe Schema, und die optionalen Felder waren zwar nullable, aber nicht optional: Ein Feld, das gar nicht abgeschickt wurde, ist undefined, nicht null. Beanstandet wurden also zwei Dutzend Felder, die auf dem Bildschirm nie standen. Damit das nicht wiederkommt, unterscheidet die Aktion jetzt zwischen Eingabefehler und Formular-Schema-Bruch: Beanstandet die Pruefung ein Feld, das nicht abgeschickt wurde, sagt sie das ausdruecklich und schreibt es ins Serverlog, statt es dem Nutzer als Eingabefehler unterzuschieben, den er nirgends finden kann. 2. Eine betreute Person liess sich nicht endgueltig loeschen. Postgres setzt beim Loeschen den Verweis im Audit-Log auf NULL, und genau dieses UPDATE hat der Unveraenderlichkeits-Trigger abgewiesen. Damit scheiterte auch das Leeren des Papierkorbs nach 30 Tagen. Der Trigger erlaubt jetzt genau eine Ausnahme: das Nullen der beiden Fremdschluessel. Jede andere Aenderung bleibt verboten, auch das Setzen eines Fremdschluessels auf einen anderen Wert. Der Nachweis bleibt vollstaendig - es verschwindet nur der Verweis auf einen Datensatz, den es nicht mehr gibt. Geprueft: sieben neue Tests gegen die tatsaechlichen Formularinhalte, der Ablauf einmal komplett im Browser bis zum Dashboard, und der Trigger gegen eine laufende Datenbank - Loeschen gelingt, Faelschen scheitert. Etappe: 8 Phase: Haertung
138 lines
5.3 KiB
TypeScript
138 lines
5.3 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { BetreuteSchema, formularLesen } from '@/lib/validierung/betreute'
|
|
|
|
/**
|
|
* Eingabepruefung der Stammdaten.
|
|
*
|
|
* Anlass für diese Datei war ein Fehler im Betrieb: Die Ersteinrichtung
|
|
* ließ sich nicht abschließen. Das Formular meldete „Bitte prüfe die
|
|
* markierten Felder", markierte aber keines — weil die Meldungen zu
|
|
* Feldern gehörten, die dort gar nicht stehen.
|
|
*
|
|
* Ursache: Das kurze Formular der Ersteinrichtung schickt neun Felder,
|
|
* das vollständige unter Stammdaten alle. Beide gehen durch dasselbe
|
|
* Schema, und die optionalen Felder waren zwar `nullable`, aber nicht
|
|
* `optional` — ein fehlendes Feld ist `undefined`, nicht `null`.
|
|
*/
|
|
|
|
/** Die Felder, die das kurze Formular der Ersteinrichtung tatsächlich schickt. */
|
|
function ersteinrichtungsFormular(): FormData {
|
|
const f = new FormData()
|
|
f.set('vorname', 'Franziska')
|
|
f.set('nachname', 'Wilde')
|
|
f.set('geburtsdatum', '1963-09-23')
|
|
f.set('betreuungsgericht', 'Lichtenfels')
|
|
f.set('aktenzeichenGericht', 'XVII 355/25')
|
|
f.set('bestellungAm', '2025-11-07')
|
|
f.append('aufgabenkreise', 'VERMOEGENSSORGE')
|
|
f.append('aufgabenkreise', 'GESUNDHEITSSORGE')
|
|
f.set('befreiterBetreuer', 'on')
|
|
f.set('ehrenamtlich', 'on')
|
|
return f
|
|
}
|
|
|
|
describe('Ersteinrichtung', () => {
|
|
it('nimmt das kurze Formular an, obwohl es die meisten Felder nicht schickt', () => {
|
|
const gelesen = BetreuteSchema.safeParse(formularLesen(ersteinrichtungsFormular()))
|
|
|
|
if (!gelesen.success) {
|
|
const felder = Object.keys(gelesen.error.flatten().fieldErrors).join(', ')
|
|
throw new Error(`Abgelehnt wegen: ${felder}`)
|
|
}
|
|
|
|
expect(gelesen.data.vorname).toBe('Franziska')
|
|
expect(gelesen.data.nachname).toBe('Wilde')
|
|
expect(gelesen.data.geburtsdatum.toISOString()).toBe('1963-09-23T00:00:00.000Z')
|
|
expect(gelesen.data.bestellungAm?.toISOString()).toBe('2025-11-07T00:00:00.000Z')
|
|
expect(gelesen.data.aufgabenkreise).toEqual(['VERMOEGENSSORGE', 'GESUNDHEITSSORGE'])
|
|
expect(gelesen.data.befreiterBetreuer).toBe(true)
|
|
expect(gelesen.data.ehrenamtlich).toBe(true)
|
|
})
|
|
|
|
it('macht aus nicht gesendeten Feldern null, nicht undefined', () => {
|
|
const gelesen = BetreuteSchema.parse(formularLesen(ersteinrichtungsFormular()))
|
|
|
|
// Diese Felder standen nie auf dem Bildschirm. Sie muessen als null in
|
|
// der Datenbank landen, sonst schreibt Prisma sie gar nicht.
|
|
expect(gelesen.heimName).toBeNull()
|
|
expect(gelesen.diagnosen).toBeNull()
|
|
expect(gelesen.geburtsname).toBeNull()
|
|
expect(gelesen.heimEinzugAm).toBeNull()
|
|
expect(gelesen.bestellungBis).toBeNull()
|
|
expect(gelesen.aktenzeichenBezirk).toBeNull()
|
|
expect(gelesen.pflegegrad).toBeNull()
|
|
expect(gelesen.schwerbehinderungGdB).toBeNull()
|
|
})
|
|
|
|
it('haelt auch das vollstaendige Formular aus', () => {
|
|
const f = ersteinrichtungsFormular()
|
|
// So kommt es aus dem Bearbeitungsformular: alle Felder da, viele leer.
|
|
for (const feld of [
|
|
'anrede', 'geburtsname', 'geburtsort',
|
|
'heimName', 'heimStrasse', 'heimPlz', 'heimOrt', 'heimZimmer', 'heimTelefon',
|
|
'fruehereStrasse', 'frueherePlz', 'fruehererOrt',
|
|
'krankenkasse', 'krankenversichertennummer', 'pflegekasse',
|
|
'schwerbehinderungMerkzeichen', 'diagnosen', 'ermittelterWille',
|
|
'aufgabenkreiseFreitext', 'aktenzeichenBezirk', 'aktenzeichenSozialamt',
|
|
'rentenversicherungsnummer', 'steuerId', 'notizen',
|
|
]) {
|
|
f.set(feld, '')
|
|
}
|
|
for (const feld of ['heimEinzugAm', 'pflegegradSeit', 'pflegegradBescheidVom', 'bestellungBis']) {
|
|
f.set(feld, '')
|
|
}
|
|
f.set('pflegegrad', '')
|
|
f.set('schwerbehinderungGdB', '')
|
|
|
|
const gelesen = BetreuteSchema.safeParse(formularLesen(f))
|
|
expect(gelesen.success, 'Leere Felder duerfen nicht abgelehnt werden').toBe(true)
|
|
})
|
|
|
|
it('nimmt ausgefuellte Angaben unveraendert an', () => {
|
|
const f = ersteinrichtungsFormular()
|
|
f.set('heimName', ' Seniorenzentrum St. Katharina ')
|
|
f.set('pflegegrad', '3')
|
|
f.set('diagnosen', 'COPD GOLD III')
|
|
|
|
const gelesen = BetreuteSchema.parse(formularLesen(f))
|
|
// Fuehrende und nachlaufende Leerzeichen fliegen raus.
|
|
expect(gelesen.heimName).toBe('Seniorenzentrum St. Katharina')
|
|
expect(gelesen.pflegegrad).toBe(3)
|
|
expect(gelesen.diagnosen).toBe('COPD GOLD III')
|
|
})
|
|
|
|
it('besteht weiterhin auf Vorname, Nachname und Geburtsdatum', () => {
|
|
const f = new FormData()
|
|
f.set('vorname', '')
|
|
f.set('nachname', '')
|
|
f.set('geburtsdatum', '')
|
|
|
|
const gelesen = BetreuteSchema.safeParse(formularLesen(f))
|
|
expect(gelesen.success).toBe(false)
|
|
|
|
if (!gelesen.success) {
|
|
const felder = gelesen.error.flatten().fieldErrors
|
|
expect(Object.keys(felder).sort()).toEqual(['geburtsdatum', 'nachname', 'vorname'])
|
|
}
|
|
})
|
|
|
|
it('weist ein Geburtsdatum in der Zukunft ab', () => {
|
|
const f = ersteinrichtungsFormular()
|
|
f.set('geburtsdatum', '2099-01-01')
|
|
|
|
const gelesen = BetreuteSchema.safeParse(formularLesen(f))
|
|
expect(gelesen.success).toBe(false)
|
|
if (!gelesen.success) {
|
|
expect(gelesen.error.flatten().fieldErrors.geburtsdatum?.[0]).toMatch(/Zukunft/)
|
|
}
|
|
})
|
|
|
|
it('weist ein unfertiges Datum ab, statt es stillschweigend zu verwerfen', () => {
|
|
const f = ersteinrichtungsFormular()
|
|
f.set('bestellungAm', '2025-11')
|
|
|
|
const gelesen = BetreuteSchema.safeParse(formularLesen(f))
|
|
expect(gelesen.success).toBe(false)
|
|
})
|
|
})
|