Commit Graph
3 Commits
Author SHA1 Message Date
Florian Wilde 0cdd4edfdc feat: Fristen, Pflichtfristen aus dem Bestellungsdatum und ICS-Feed
Die gesetzlichen Fristen entstehen von selbst, sobald das
Bestellungsdatum in den Stammdaten steht - Vermoegensverzeichnis und
Anfangsbericht nach drei Monaten, Jahresbericht und Vermoegensuebersicht
zum Ende jedes Betreuungsjahres, Aufwandspauschale, Landespflegegeld,
Zuzahlungsbefreiung, Rueckkaufswerte.

Zwei Punkte, an denen es sonst schiefgeht:

Das Betreuungsjahr endet am Tag VOR dem Jahrestag (§ 188 Abs. 2 BGB),
bei Bestellung am 29. Februar am 28. (§ 188 Abs. 3). Ohne diese Regel
verrutscht die ganze Kette um einen Tag.

Faellt eine Frist auf Samstag, Sonntag oder Feiertag, wird sie NICHT
verschoben. § 193 BGB verschiebt zwar den Ablauf, aber als Betreuer will
ich frueher fertig sein, nicht spaeter. Stattdessen steht ein Hinweis in
der Beschreibung. Bayerische Feiertage inklusive, ueber die Osterformel
berechnet.

Pflichtfristen tragen bewusst keine RRULE: sonst entstuende beim
Erledigen eine Dublette neben der ohnehin abgeleiteten Folgefrist. Beim
erneuten Ableiten werden nur offene Fristen nachgezogen, Erledigtes
bleibt unangetastet.

Der ICS-Feed kommt ohne Token-Feld im Schema aus - die Signatur ist ein
HMAC ueber betreuteId und userId. VALARM je Vorwarnstufe, Zeilenfaltung
nach RFC 5545.

51 Tests.

Etappe: 2
Phase: Alltag
2026-08-22 02:24:32 +02:00
Florian Wilde 1217725076 feat: Vorgaenge als Fallakte mit Genehmigungskette und Vorlagen
Jeder Vorgang ist eine kleine Akte: Kopfdaten, Aufgabenliste zum
Abhaken, Genehmigungsstufen und ein Zeitstrahl, der Dokumente,
Kontaktprotokolle, Fristen, Buchungen und Statuswechsel zusammenfuehrt.

Die abnahmerelevante Regel: Ein genehmigungspflichtiger Vorgang laesst
sich nicht auf VOLLZOGEN setzen, solange kein Beschlussdokument
hinterlegt ist. Geprueft wird in darfStatusWechseln() UND in der Server
Action - nicht nur im UI, wo das Auswahlfeld die Stufe ohnehin gar nicht
erst anbietet. Hintergrund ist § 1858 BGB: die Genehmigung muss vor dem
Rechtsgeschaeft vorliegen, nicht danach.

Neun Vorlagen mit durchdachter Aufgabenreihenfolge. Bei Wohnungs-
aufloesung und Hausverkauf erzwingen sie die Kette Mitteilung ->
Genehmigung -> Rechtsgeschaeft; ein Test prueft das.

Kanban ohne Drag-and-Drop: Statuswechsel laufen ueber Auswahlfeld und
Knopf. Am Handy ist das verlaesslicher, und am Schreibtisch kostet es
einen Klick mehr statt einer verlorenen Karte.

Zeitzonen: alsTag() bildet den oertlichen Kalendertag auf Mitternacht
UTC ab. Ohne das rutscht in Deutschland jede Faelligkeit einen Tag
zurueck.

33 Tests.

Etappe: 2
Phase: Alltag
2026-08-22 02:24:16 +02:00
Florian Wilde c49810d092 feat: Feldverschluesselung, Argon2id und TOTP-Zweitfaktor
Die Sicherheitsschicht, auf der alles Weitere aufsetzt.

Feldverschluesselung (AES-256-GCM):
- Umschlagformat bc1.<version>.<iv>.<tag>.<ct>. Die Schluesselversion
  erlaubt Rotation, ohne alte Daten unlesbar zu machen.
- Der Feldname wird als AAD mitauthentifiziert. Ein Geheimtext laesst
  sich damit nicht von diagnosen nach notizen umhaengen.
- Leere Werte werden zu NULL statt zu einem Umschlag - sonst verriete
  die Datenbank, dass ueberhaupt etwas eingetragen war.
- VERSCHLUESSELTE_FELDER ist der einzige Ort, an dem steht, was
  verschluesselt gehoert. sealen()/oeffnen() arbeiten darauf.

Argon2id nach OWASP-Empfehlung (19 MiB, t=2, p=1), mit hashVeraltet()
fuer spaetere Parametererhoehung ohne Migration.

Blindindex per HMAC-SHA256 mit eigenem Schluessel: erlaubt die Frage
"kenne ich diese IBAN schon?", ohne sie im Klartext zu halten.
Derselbe Mechanismus pseudonymisiert IP-Adressen fuers Audit-Log.

TOTP mit otpauth, QR-Code serverseitig als Data-URI - kein externer
QR-Dienst, kein CDN. Wiederherstellungscodes aus einem Alphabet ohne
0/O und 1/I, einzeln Argon2id-gehasht, Pruefung ohne fruehen Abbruch.

37 Tests decken Rundlauf, Manipulation, Feldbindung, Rotation,
Salzung und Normalisierung ab.

Etappe: 1
Phase: Fundament
2026-08-22 01:42:13 +02:00