diff --git a/docs/ANLEITUNG.md b/docs/ANLEITUNG.md new file mode 100644 index 0000000..5ad204e --- /dev/null +++ b/docs/ANLEITUNG.md @@ -0,0 +1,430 @@ +# Bedienungsanleitung + +Für dich als ehrenamtlichen Betreuer. Kein Handbuch zum Durchlesen — +sondern eine Sammlung der Handgriffe, die du tatsächlich brauchst, in der +Reihenfolge, in der sie im Alltag vorkommen. + +> Diese Anwendung ist ein **Arbeits- und Dokumentationswerkzeug**. Sie +> rechnet Fristen aus und sortiert Unterlagen. Sie erteilt **keine +> Rechtsberatung** und kennt deinen Einzelfall nicht. Wo ein Paragraph +> steht, steht daneben der Hinweis, dass er die Rückfrage bei Gericht, +> Bezirk oder Anwalt nicht ersetzt. Nimm den ernst. + +--- + +## Der Grundgedanke in drei Sätzen + +Du trägst einmal ein, was passiert ist — ein Schreiben, ein Besuch, eine +Überweisung. Die Anwendung merkt sich, wann daraus etwas folgt, und +erinnert dich rechtzeitig. Am Ende des Betreuungsjahres erzeugt sie aus +demselben Bestand die Berichte, die Gericht und Bezirk von dir wollen. + +Das heißt umgekehrt: **Was du nicht einträgst, steht später nicht im +Bericht.** Der Aufwand liegt vorn, der Gewinn hinten. + +--- + +## Der erste Tag + +Beim allerersten Aufruf führt dich ein Assistent durch drei Schritte. + +**Schritt 1 — Dein Zugang.** Name, E-Mail, Passwort. Nimm vier zufällige +Wörter statt eines kurzen Kunstworts: *Kastanie-Waschbär-Turm-Grün* ist +leichter zu merken und deutlich schwerer zu knacken. Noch besser ist ein +Passwortmanager. + +**Schritt 2 — Der zweite Faktor.** Installiere eine Authenticator-App — +**Aegis** (Android) oder **2FAS** (iOS) sind quelloffen und brauchen kein +Konto. Scanne den Code, tippe die sechs Ziffern ein. + +Danach bekommst du **acht Wiederherstellungscodes**. Die sind der einzige +Weg zurück, wenn dein Handy verloren geht. Druck sie aus und leg sie zu +deinen Betreuungsunterlagen — **nicht** auf dasselbe Gerät wie die App. +Sie werden dir nie wieder angezeigt. + +**Schritt 3 — Die betreute Person.** Nur das Nötigste. Ein Feld ist dabei +wichtiger als alle anderen: + +> **Das Bestellungsdatum.** Es steht in deiner Bestellungsurkunde. Daraus +> berechnet die Anwendung dein Betreuungsjahr — und damit, wann +> Anfangsbericht, Vermögensverzeichnis, Jahresbericht und die +> Aufwandspauschale fällig sind. Ist es falsch, ist alles falsch. + +Alles Weitere trägst du später unter **Stammdaten → Bearbeiten** in Ruhe +nach. Das lohnt sich: Was dort steht, taucht in jedem Bericht und in jedem +Anschreiben wieder auf. + +**Zum Schluss:** Geh auf **Fristen** und klicke einmal auf +*Pflichtfristen ableiten*. Danach stehen deine gesetzlichen Termine drin. + +--- + +## Der Morgen: die Seite „Heute" + +Diese eine Seite beantwortet die Frage, was ansteht. Von oben nach unten: + +| Kachel | Was sie dir sagt | +|---|---| +| **Fristen** | Was überfällig ist (rot), was diese Woche fällig wird (orange), was diesen Monat (gelb) | +| **Wartet auf andere** | Vorgänge, bei denen die Gegenstelle am Zug ist — mit Tagen seit dem letzten Kontakt | +| **Nachforderungen des Trägers** | Was der Bezirk noch von dir will, mit Fortschrittsbalken | +| **Ungeprüfter Posteingang** | Neu hochgeladene Schreiben, die noch niemand zugeordnet hat | +| **Unverbuchte Belege** | Rechnungen ohne Buchung und Buchungen ohne Beleg | +| **Wo stehen wir?** | Vermögen zum letzten Stichtag, Heimkosten gegen Deckung, Tage bis zum Jahresbericht | + +Jede Kachel endet in einer Handlung. Wenn irgendwo nichts steht, ist dort +auch nichts zu tun. + +**Ist eine Kachel leer, obwohl du Daten erwartest?** Dann fehlt meist ein +Eintrag: keine Fristen ohne Bestellungsdatum, keine Deckungslücke ohne +erfassten Heimkostenmonat. + +--- + +## Die zwölf häufigsten Handgriffe + +### 1. Ein Behördenschreiben aufnehmen + +**Dokumente → Aufnehmen**, oder unterwegs über den runden Knopf unten +rechts → *Beleg fotografieren*. + +1. Foto machen oder PDF wählen — mehrere auf einmal sind ausdrücklich + erwünscht. +2. Warten, bis die Datei angenommen ist. Geprüft wird der **Inhalt**, nicht + die Endung: eine Datei, die sich nur als PDF ausgibt, wird abgelehnt. +3. Titel eintragen (oder leer lassen — die Erkennung schlägt einen vor). +4. **Eingangsdatum** setzen. Das ist wichtiger, als es aussieht: Bei + Bescheiden läuft die Widerspruchsfrist ab dem Zugang, nicht ab dem + Datum auf dem Brief. +5. Vorgang auswählen. +6. *In die Akte übernehmen*. + +Danach liest der Server den Text (Texterkennung auf Deutsch) und schlägt +dir **Absender, Datum, Aktenzeichen, Dokumentart und eine im Text genannte +Frist** vor. Die Textstelle steht daneben — prüf sie, bevor du übernimmst. +Nichts davon wird automatisch angelegt. + +**Trag ein, wo das Papier liegt.** Es gibt ein Feld für Ordner und +Register. Wenn der Rechtspfleger das Original sehen will, findest du es +dann in zehn Sekunden. + +### 2. Aus einem Schreiben eine Frist machen + +Öffne das Dokument. Steht unter den Vorschlägen eine erkannte Frist, +genügt ein Klick auf *Als Frist übernehmen*. Sonst: **Fristen → Neu**, +Datum eintragen, Vorgang zuordnen. + +Setz bei behördlichen Fristen die Vorwarnung großzügig. Der Standard ist +60/30/7/1 Tage vorher. + +### 3. Einen Besuch festhalten — in zwanzig Sekunden + +Runder Knopf unten rechts → *Notiz / Kontakt festhalten*. + +Datum ist auf heute vorbelegt, die Art wählst du aus einer Knopfreihe, die +Dauer per Schnellwahl. Ein Freitextfeld, fertig. + +Zwei Felder lohnen die zusätzlichen Sekunden: + +- **„Persönlicher Kontakt zur betreuten Person"** — dieses Häkchen zählt + direkt in den Jahresbericht. Es ist bewusst **nicht** vorbelegt: ein + versehentlich gesetztes Häkchen wäre eine falsche Angabe gegenüber dem + Gericht. +- **Geäußerte Wünsche** — seit der Reform 2023 ist der Wille der betreuten + Person die Leitschnur deines Handelns (§ 1821 BGB). Was du hier + festhältst, landet im Jahresbericht und trägt deine Entscheidungen. + +Das ist der Handgriff, der sich am meisten auszahlt. Ein Jahresbericht aus +vierzig kurzen Notizen schreibt sich fast von selbst; einer aus der +Erinnerung ist eine Qual. + +### 4. Eine Buchung erfassen + +**Vermögen & Kasse → Buchungen → Neu**, oder über den runden Knopf. + +Wichtig ist die Trennung: **Betrifft die Buchung die betreute Person oder +ist es deine eigene Auslage?** Läuft eine Buchung auf ein als privat +markiertes Konto und ist trotzdem als „betrifft die Betreute" +gekennzeichnet, warnt die Anwendung. Das ist der Fehler, der einem in der +Rechnungslegung um die Ohren fliegt. + +**Belege.** Eine Buchung ohne Beleg wird in der Liste markiert. Das ist +kein Verbot — manchmal gibt es keinen. Dann trag eine Begründung ein, dann +ist die Zeile sauber und du weißt später noch, warum. + +### 5. Einen Vorgang anlegen + +**Vorgänge → Neuer Vorgang.** Nimm eine Vorlage, wenn eine passt: + +Heimeinzug · Antrag Hilfe zur Pflege · Wohnungsauflösung · Hausverkauf · +Darlehen § 91 SGB XII · Versicherungsverwertung · Pflegegrad-Höherstufung · +Steuererklärung · Widerspruch gegen Bescheid + +Jede bringt eine durchdachte Aufgabenliste in der richtigen Reihenfolge +mit. Bei den genehmigungspflichtigen erzwingt sie die Reihenfolge +**Mitteilung → Genehmigung → Rechtsgeschäft**. + +Ein Feld solltest du immer pflegen: **Nächster Schritt.** Es steht auf dem +Dashboard und beantwortet dir in vier Wochen die Frage, was du dir dabei +gedacht hast. + +### 6. Ein genehmigungspflichtiges Geschäft + +Hausverkauf, Wohnungskündigung, Kreditaufnahme, Verwertung einer +Lebensversicherung — dafür brauchst du das Betreuungsgericht. + +Markiere den Vorgang als genehmigungspflichtig und wähle die +Rechtsgrundlage. Die Anwendung zeigt dann eine feste Stufenfolge: + +**Mitteilung ans Gericht → Antrag gestellt → Anhörung → Beschluss → +Rechtskraft → Vollzug** + +> Die Stufe **Vollzug lässt sich erst setzen, wenn ein Beschlussdokument +> hinterlegt ist.** Das ist Absicht: Nach § 1858 BGB muss die Genehmigung +> **vor** dem Rechtsgeschäft vorliegen. Ein Vertrag, den du vorher +> unterschreibst, ist schwebend unwirksam. + +Sprich vorher mit dem Rechtspfleger. Die Anwendung ersetzt das Gespräch +nicht, sie erinnert dich nur daran. + +### 7. Eine Nachforderung des Bezirks abarbeiten + +**Sozialhilfe → Akte öffnen.** Jede angeforderte Unterlage steht als +eigene Zeile mit Status und Frist. Der Fortschrittsbalken zeigt „x von y +Unterlagen geliefert". + +Beim Anlegen des Antrags kannst du die **Checkliste der Standardunterlagen** +übernehmen — Rentenbescheide, Kontoauszüge, Versicherungsunterlagen, +notarielle Übertragungsverträge, Pflegegradbescheid, Heimvertrag, +Grundbuchauszug. Zu jeder steht dabei, **warum** der Träger sie will. Das +erspart Rückfragen. + +Gibt es eine Unterlage nicht, setz den Status auf *nicht vorhanden* und +schreib eine Begründung dazu. Die geht später mit ins Unterlagenpaket — +besser als kommentarloses Schweigen. + +Wenn alles beisammen ist: **Berichte → Unterlagenpaket**. Das macht aus +den markierten Dokumenten **eine** PDF mit Anschreiben, laufender Nummer +und Inhaltsverzeichnis. + +### 8. Einen Bescheid prüfen + +**Sozialhilfe → Akte → Bescheide → Neu.** + +Trag das **Zugangsdatum** ein, nicht das Datum auf dem Bescheid. Die +Widerspruchsfrist läuft ab Bekanntgabe. + +Die Anwendung rechnet die Frist aus — mit Wochenende, bayerischen +Feiertagen und dem Sonderfall, dass bei fehlender oder falscher +Rechtsbehelfsbelehrung ein Jahr statt eines Monats gilt (§ 66 SGG). Der +Rechenweg wird ausgegeben, damit du ihn nachvollziehen kannst. Aus dem +Ergebnis entsteht automatisch die Frist *Widerspruch möglich bis*. + +**Rechne im Zweifel nach oder frag beim Bezirk.** Eine verstrichene +Widerspruchsfrist bekommst du nicht zurück. + +### 9. Einen Rückkaufswert anfordern + +**Verträge → Vertrag öffnen → Rückkaufswert anfordern.** Es entsteht ein +Anschreiben zum Kopieren, und die Anwendung legt eine **Wiedervorlage in +vier Wochen** an. Versicherer antworten selten von selbst. + +### 10. Einen Vertrag kündigen + +**Verträge → Vertrag öffnen → Kündigen.** + +Der Rechner nennt dir den **spätesten Absendetag**, nicht den Fristablauf — +eine Kündigung wirkt mit dem Zugang, nicht mit dem Abschicken. Drei Tage +Postlauf sind eingerechnet. + +Der Assistent fragt dich nach der Genehmigung. Er beantwortet die Frage +nicht, und das soll er auch nicht: Ob die Verwertung einer +Lebensversicherung genehmigungspflichtig ist, entscheidet der +Rechtspfleger. Der **Versandnachweis** (Einschreiben, Faxprotokoll) ist +Pflichtfeld — ohne ihn geht die Kündigung nicht durch. + +### 11. Einen Wertstand nachtragen + +**Vermögen & Kasse → Vermögen → Posten öffnen → Wert eintragen.** + +Stichtag, Betrag und **Wertquelle** — letztere ist Pflicht. „Eigene +Schätzung" ist eine zulässige Antwort, „keine Angabe" nicht: Im +Vermögensverzeichnis steht die Quelle mit dabei, und das Gericht darf +wissen, woher die Zahl kommt. + +Alte Werte werden **nie überschrieben**. Jede Vermögensübersicht bleibt +später reproduzierbar. + +### 12. Etwas versehentlich Gelöschtes zurückholen + +**Einstellungen → Papierkorb.** Gelöschtes bleibt 30 Tage liegen und lässt +sich mit einem Klick zurückholen. Erst danach ist es wirklich weg. + +Endgültiges Löschen verlangt eine erneute Anmeldung. + +--- + +## Das Betreuungsjahr + +Dein Jahr läuft **ab dem Tag der Bestellung**, nicht ab dem 1. Januar. Wer +am 14. Februar bestellt wurde, hat sein erstes Betreuungsjahr bis zum +13. Februar des Folgejahres. + +| Wann | Was | Grundlage | +|---|---|---| +| 3 Monate nach Bestellung | Vermögensverzeichnis und Anfangsbericht | §§ 1835, 1863 BGB | +| Zum Ende jedes Betreuungsjahres | Jahresbericht und Vermögensübersicht | §§ 1859, 1863 BGB | +| Bis 6 Monate danach | **Aufwandspauschale beantragen** | § 1878 BGB | +| Jährlich bis 31.12. | Bayerisches Landespflegegeld | BayLPflGG | +| Jährlich | Zuzahlungsbefreiung der Krankenkasse | § 62 SGB V | +| Jährlich | Rückkaufswerte aller Versicherungen aktualisieren | — | + +> **Die Aufwandspauschale ist eine Ausschlussfrist.** Läuft sie ab, ist +> der Anspruch ersatzlos weg — keine Nachsicht, keine Wiedereinsetzung. +> Die Anwendung warnt deshalb schon 90 Tage vorher und markiert sie rot. + +--- + +## Die Berichte + +Alle unter **Berichte**, die beiden Finanzberichte unter **Vermögen & +Kasse → Berichte**. Jeder trägt Kopf mit Aktenzeichen, Fußzeile mit +Seitenzahl und ein Unterschriftenfeld. + +**Vermögensverzeichnis (§ 1835 BGB).** Stichtag wählen, Knopf drücken. +Aktiva nach Gruppen, Passiva, laufende Einnahmen und Ausgaben, +Belegverweise. Hat ein Posten zum Stichtag keinen Wert, erscheint er als +**Lücke** — nicht als 0,00 €. Das ist ehrlicher und fällt dir auf. + +**Vermögensübersicht / Rechnungslegung (§§ 1859, 1865 BGB).** +Betreuungsjahr wählen. Anfangsbestand, geordnete Einnahmen und Ausgaben, +Endbestand, Belegliste. + +Zwei Varianten: die knappe Übersicht für **befreite Betreuer** (§ 1859 BGB +— als Angehöriger bist du das in der Regel) und die vollständige +Rechnungslegung. + +> Geht die Rechenprobe nicht auf, wird die **Differenz im Bericht +> ausgewiesen** und jeder fehlende Saldostand benannt. Das ist Absicht. +> Eine still geglättete Rechnungslegung ist gegenüber dem Gericht wertlos — +> und meistens fehlt einfach ein Kontoauszug. + +**Jahresbericht (§ 1863 BGB).** Die Anwendung erzeugt einen **Entwurf** aus +deinen Kontaktprotokollen, Gesundheitsereignissen und Vorgängen, gegliedert +nach dem, was das Gericht sehen will. Du überarbeitest ihn im Browser +(wird automatisch zwischengespeichert) und gibst ihn dann als PDF oder DOCX +aus. + +> Es ist ein Entwurf, kein fertiger Bericht. Lies ihn durch, bevor du ihn +> abgibst. Was dort steht, verantwortest du. + +**Belegmappe.** Alle Dokumente eines Vorgangs oder Zeitraums als eine +chronologisch sortierte, paginierte PDF mit Deckblatt und +Inhaltsverzeichnis. Genau das, was Gericht und Bezirk haben wollen. + +**Vollexport.** Ein ZIP mit allen Originaldateien, allen Daten als +lesbarem JSON, den Berichten und Prüfsummen. Damit kannst du diese +Anwendung jederzeit verlassen. Verlangt eine erneute Anmeldung. + +--- + +## Am Handy + +Die Anwendung ist am Telefon vollwertig bedienbar — sie ist dafür gebaut, +nicht dafür angepasst. + +- Menü über das Symbol links oben, schließt mit Wischen oder Escape. +- Der **runde Knopf unten rechts** ist immer erreichbar: Beleg + fotografieren, Notiz festhalten, Frist anlegen, Buchung erfassen. +- Tabellen scrollen in ihrem eigenen Rahmen, nie die ganze Seite. +- Zoomen ist erlaubt und abgeschaltet wird es nie. + +Der typische Fall: Du sitzt im Heim, fotografierst die Heimrechnung, +ordnest sie dem Vorgang zu, hältst den Besuch fest — drei Minuten, und +abends musst du nichts nacharbeiten. + +--- + +## Wenn etwas schiefgeht + +**Ich habe mein Handy mit der Authenticator-App verloren.** +Melde dich mit einem deiner Wiederherstellungscodes an — statt der sechs +Ziffern gibst du den Code im Format `XXXX-XXXX-XXXX` ein. Jeder +funktioniert einmal. Danach unter **Konto → Zweiter Faktor** neu +einrichten und **neue Codes erzeugen**. + +**Ich habe auch die Wiederherstellungscodes verloren.** +Dann kommt nur noch jemand mit Zugriff auf den Server weiter, indem er den +zweiten Faktor in der Datenbank zurücksetzt. Genau deshalb: Codes +ausdrucken. + +**Der Code wird nicht angenommen.** +Fast immer geht die Uhr des Telefons falsch. TOTP-Codes hängen an der +Uhrzeit. Stell die automatische Zeitsynchronisierung ein. + +**„Zu viele Fehlversuche."** +Nach fünf Fehlversuchen wird für eine Viertelstunde gesperrt. Warte ab — +das gilt auch dann, wenn du selbst es warst. + +**Ich habe mein Passwort geändert und bin überall abgemeldet.** +So gewollt. Ein Passwortwechsel beendet alle Sitzungen, auch auf Geräten, +an denen du gerade nicht sitzt. + +**Eine Frist stimmt nicht.** +Prüf zuerst das Bestellungsdatum unter **Stammdaten**. Änderst du es, +werden die Pflichtfristen neu berechnet. Erledigte Fristen bleiben dabei +unangetastet. + +**Ein Bericht zeigt eine Differenz.** +Meistens fehlt ein Saldostand. Der Bericht sagt dir, welcher. Trag ihn +unter **Vermögen & Kasse → Konten** nach und erzeuge neu. + +**Die Texterkennung findet nichts.** +Sie braucht Tesseract auf dem Server. Fehlt es, funktioniert der Upload +trotzdem — nur ohne Volltextsuche. Titel und Absender kannst du von Hand +eintragen. + +--- + +## Was diese Anwendung nicht tut + +Damit du dich nicht darauf verlässt: + +- **Sie berät dich nicht.** Sie rechnet Fristen und schlägt Einordnungen + vor. Ob dein Fall eine Ausnahme ist, weiß sie nicht. +- **Sie entscheidet nicht, was Schonvermögen ist.** Sie gibt dir + Argumentationshilfen zu § 90 SGB XII zum Übernehmen. Entscheiden tun der + Träger und notfalls das Sozialgericht. +- **Sie schätzt keine Bewilligungschancen.** +- **Sie holt keine Kontoauszüge ab.** Kontobewegungen kommen per + CSV-Import oder von Hand. +- **Sie verschickt nichts.** Anschreiben entstehen als Text zum Kopieren, + Berichte als PDF. Absenden musst du selbst — und den Versandnachweis + hochladen. +- **Sie ersetzt deine Papierablage nicht.** Originale bleiben Originale. + Deshalb gibt es das Feld für den Ablageort. + +--- + +## Zwei Gewohnheiten, die sich lohnen + +**Jeden Kontakt festhalten, sofort.** Auch das kurze Telefonat. Zwanzig +Sekunden jetzt sparen dir im Januar einen halben Tag. + +**Einmal im Jahr die Wiederherstellung üben.** Ein Backup, das nie +zurückgespielt wurde, ist kein Backup. Die Anleitung steht in der README +unter *Sicherung und Wiederherstellung*. Zwanzig Minuten, einmal im Jahr. + +--- + +## Wo du weiterkommst + +- **Hinweise** in der Anwendung — 37 Karten zu den häufigen Fallstricken, + jede mit Rechtsgrundlage und Link zum Gesetzestext. +- **Protokoll** — jede Änderung, lückenlos und unveränderlich. Dein + Nachweis gegenüber Gericht und möglichen Miterben. +- Dein **Rechtspfleger** beim Betreuungsgericht. Er ist zuständig und + antwortet. Bei allem, was genehmigungspflichtig sein könnte: vorher + fragen, nicht nachher. +- Die örtliche **Betreuungsbehörde** und die Betreuungsvereine beraten + ehrenamtliche Betreuer kostenlos. diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md new file mode 100644 index 0000000..0acb80c --- /dev/null +++ b/docs/ROADMAP.md @@ -0,0 +1,261 @@ +# Roadmap + +Was als Nächstes drankommt, und warum in dieser Reihenfolge. + +**Maßstab ist der Alltag, nicht die Vollständigkeit.** Ein Punkt steht +weit oben, wenn er entweder etwas Falsches richtigstellt oder jeden Monat +Zeit spart. Er steht weit unten, wenn er nur schön wäre. + +Diese Datei ist eine Absichtserklärung, kein Vertrag. Was sich im Betrieb +als wichtiger herausstellt, rutscht nach oben. + +Stand: 22.08.2026 · Aktuelle Fassung: **1.0.0** ([CHANGELOG](../CHANGELOG.md)) + +--- + +## Woher die Punkte kommen + +Beim Bauen sind **44 Schema-Wünsche** aufgelaufen — Stellen, an denen das +Datenmodell etwas nicht abbildet, was die Fachlogik gebraucht hätte. Sie +liegen einzeln und begründet in [`schema-wuensche/`](schema-wuensche/), +nach Modul getrennt. Diese Roadmap sortiert sie nach Dringlichkeit und +bündelt sie zu Releases, die sich in einem Rutsch migrieren lassen. + +Dazu kommen die bekannten Einschränkungen aus dem Changelog und das, was +sich im Betrieb noch zeigen wird. + +--- + +## 1.1 — Was heute noch falsch sein kann + +**Ziel:** Kein Wert in der Anwendung soll unter ungünstigen Umständen +falsch sein, ohne dass man es merkt. Das ist die einzige Art von Fehler, +die man einem Betreuungsgericht nicht erklären kann. + +### Kostenkonto der Immobilie richtigstellen + +`Buchung` hat kein `immobilieId`. Das Kostenkonto wertet deshalb über +Buchungskategorien aus — bei **einem** Grundstück richtig, bei einem +zweiten still falsch. Die Oberfläche sagt das derzeit an der Auswertung +dazu; das ist ein Pflaster, keine Lösung. + +*Aufwand: klein. Migration: ein Feld, ein Index.* + +### Umbuchungen kennen ihr Gegenkonto + +Eine Umbuchung zwischen zwei Konten erscheint heute als zwei unverbundene +Buchungen. In der Rechnungslegung sieht das aus wie eine Ausgabe und eine +Einnahme — und wer nachrechnet, fragt zu Recht nach. + +*Aufwand: klein. Migration: ein selbstbezüglicher Fremdschlüssel.* + +### Dublettenschutz beim Import ohne Konto + +Der Schutz vor Doppelbuchungen greift über `(kontoId, importReferenz)`. +Ist kein Konto zugeordnet, greift er nicht — ein zweimal eingelesener +Auszug erzeugt dann doppelte Buchungen. + +*Aufwand: klein. Migration: partieller eindeutiger Index.* + +### Rückkaufswert am Vertrag + +Der Wert hängt heute am Vermögensposten. In der Vertragsübersicht steht +deshalb kein Betrag — ausgerechnet dort, wo man ihn beim Telefonat mit dem +Versicherer braucht. + +*Aufwand: klein.* + +### Genau eine Zielspalte je Dokumentverknüpfung + +`DokumentVerknuepfung` hat zwölf mögliche Zielspalten; dass genau eine +gesetzt ist, erzwingt bisher nur die Anwendung. Ein CHECK-Constraint macht +daraus eine Zusage, die auch bei direktem Datenbankzugriff hält. + +*Aufwand: klein. Migration: ein Constraint.* + +### Papierkorb für Saldo- und Wertstände + +Beide Modelle haben kein `geloeschtAm`. Ein versehentlich eingetragener +Kontostand lässt sich nur endgültig löschen — was der Zusage widerspricht, +dass Löschen 30 Tage rückgängig zu machen ist. + +*Aufwand: klein.* + +### Aufgaben aus Vorlagen entfernen können + +Passt eine Aufgabe aus einer Vorgangs-Vorlage im Einzelfall nicht, bleibt +sie dauerhaft offen stehen und verfälscht jede Fortschrittsanzeige. + +*Aufwand: klein.* + +--- + +## 1.2 — Weniger tippen + +**Ziel:** Die Handgriffe, die sich jeden Monat wiederholen, kürzer machen. + +### Nachforderungen mit stabilem Schlüssel + +Der Dublettenschutz beim Übernehmen der Standardcheckliste läuft über die +Bezeichnung. Wer eine Zeile umbenennt, bekommt sie beim nächsten Mal +doppelt. + +### Bescheid und Frist verbinden + +Aus einem Bescheid entsteht die Widerspruchsfrist heute über einen +Textschlüssel statt über einen Fremdschlüssel. Ändert sich das +Zugangsdatum, wandert die Frist nicht mit. + +### Statuswechsel eines Vorgangs als eigene Tabelle + +Der Zeitstrahl liest Statuswechsel aus dem entschlüsselten Audit-Log. Das +funktioniert, ist aber langsam und hängt an einem Format, das eigentlich +nur Nachweis sein soll. + +### Wer hat was erfasst + +Fristen, Saldo- und Wertstände tragen kein Feld für den erfassenden +Benutzer. Bei einer Betreuung zu zweit ist das die erste Frage. + +### Ansprechpartner am Vorgang + +Die Sachstandsanfrage kann namentlich anreden, bekommt den Ansprechpartner +mangels Feld aber nicht übergeben. + +### Inventarliste als eigenes Modell + +Wertgegenstände hängen heute an Freitext und Fotos. Für die +Wohnungsauflösung wäre eine Liste mit Bezeichnung, Raum, geschätztem Wert +und Verbleib das richtige Werkzeug. + +### Pflegegrad-Historie + +Der Pflegegrad steht als einzelnes Feld in den Stammdaten. Frühere Grade +mit ihren Zeiträumen gehören in eine Historie — sie werden im +Jahresbericht und bei einer Höherstufung gebraucht. + +--- + +## 1.3 — Belastbarkeit + +**Ziel:** Die Stellen absichern, die bisher nur unter Laborbedingungen +geprüft sind. + +### Texterkennung gegen echtes Tesseract + +Bisher ist nur der Weg „nicht verfügbar, Upload funktioniert trotzdem" +getestet. Ein Test im Container gegen echte Schreiben — auch schlechte +Handyfotos, auch mehrseitige Bescheide — fehlt. + +### CAMT.053 gegen einen echten Bankauszug + +Der Leser ist gegen selbst gebaute Beispiele geprüft. Ein echter Auszug +der Sparkasse ist der eigentliche Test. + +### Suche und Belegmappe gegen Postgres + +Beide sind nur in Einzelteilen geprüft, nicht end-to-end gegen die +Datenbank mit einigen hundert Dokumenten. + +### Wiederherstellung als Test + +Die Anleitung dafür steht in der README. Ein Skript, das sie einmal im +Monat automatisch durchspielt — Sicherung zurückspielen, Diagnosen im +Klartext prüfen, Testdatenbank verwerfen — wäre der Beweis statt der +Absichtserklärung. + +### Barrierefreiheits-Durchgang mit einem Screenreader + +Semantik, Fokusreihenfolge und Kontraste sind beim Bauen beachtet und in +Teilen getestet. Ein Durchgang mit NVDA oder VoiceOver ist etwas anderes +als eine Testzusicherung. + +### `@react-pdf/renderer` ohne Krücke + +`src/lib/pdf/standardschrift.ts` gleicht aus, dass die Unterabhängigkeiten +für Standardschriften kein Schriftobjekt mehr liefern. Ein `overrides`- +Eintrag in der `package.json` oder eine neuere Fassung macht die Datei +überflüssig — sie baut sich dann selbst ab. + +--- + +## 2.0 — Mehr als eine Betreuung + +**Ziel:** Was sich nur mit einem Bruch lösen lässt. Deshalb eine eigene +Hauptversion — und deshalb nicht vorher. + +### Zweite betreute Person im Alltag erprobt + +Das Datenmodell trägt es von Anfang an: Alles hängt an einer `betreuteId`, +der Zugriff wird gegen sie geprüft, die Auswahl steht in der Seitenleiste. +**Gelaufen ist es bisher nur mit einer.** Was fehlt, ist Erfahrung — und +vermutlich ein Dashboard, das über beide hinwegsieht. + +### Heimkostenmodell entwirren + +Der einrichtungseinheitliche Eigenanteil auf der Heimrechnung ist bereits +um die Leistung der Pflegekasse gekürzt. Das Modul rechnet deshalb +ausdrücklich nach der Lesart `EIGENANTEIL_NETTO` und warnt, wenn die +Pflegekassenleistung zusätzlich erfasst wird. + +Sauberer wäre, die beiden Lesarten im Modell zu trennen, statt sie im Kopf +auseinanderzuhalten. Das ändert bestehende Datensätze — also 2.0. + +### Mehrere Fassungen je Bericht + +Heute verdrängt die DOCX-Ausgabe die abgegebene PDF-Fassung. Was einmal +beim Gericht lag, sollte unverändert nachweisbar bleiben. + +### Verschlüsselte Ablage auch bei S3 + +Beim Dateitreiber liegen Dokumente zusätzlich AES-256-GCM-verschlüsselt. +Bei S3 geht das nicht, weil signierte URLs am Server vorbei ausgeliefert +werden. Der Ausweg wäre, Dateien durch die Anwendung zu reichen — das +kostet Durchsatz und ist eine bewusste Abwägung, keine Selbstverständlichkeit. + +--- + +## Später, ohne Datum + +Sinnvoll, aber nicht dringend: + +- **Kalendarische Wiedervorlage per E-Mail als Wochenübersicht** statt + einzelner Erinnerungen. +- **Vorlagen für eigene Anschreiben**, über die mitgelieferten hinaus. +- **Import eines Grundbuchauszugs** als strukturierte Daten statt als PDF. +- **Mehrere Betreuungsgerichte** je betreuter Person (bei Umzug). +- **Zwei-Personen-Prinzip** für besonders sensible Aktionen — technisch + vorbereitet durch die erneute Anmeldung, fachlich noch nicht gebraucht. +- **Statistik über mehrere Betreuungsjahre** für den eigenen Überblick. + +--- + +## Bewusst nicht geplant + +Damit klar ist, worauf niemand warten muss: + +| Was | Warum nicht | +|---|---| +| **Automatische Rechtsberatung** | Die Anwendung kennt den Einzelfall nicht. Sie rechnet und dokumentiert; entscheiden tun Gericht, Träger und im Zweifel das Sozialgericht. | +| **Prognosen zu Bewilligungschancen** | Eine Zahl, die niemand belegen kann, wird trotzdem geglaubt. Das ist schlimmer als keine Zahl. | +| **Direkte Bankanbindung** | Ein dauerhafter Kontozugriff ist ein Risiko, das der Bequemlichkeit nicht wert ist. CSV und CAMT reichen. | +| **Mehrmandantenfähigkeit für fremde Betreuungen** | Sobald mehrere Betreuer mit fremden Fällen auf derselben Installation arbeiten, ändert sich die datenschutzrechtliche Lage grundlegend. Mehrere Betreute **einer** Person bleiben möglich. | +| **Native App für Handy und Tablet** | Die Web-Anwendung ist am Telefon vollwertig bedienbar. Eine zweite Oberfläche wäre eine zweite Oberfläche, die veraltet. | +| **Cloud-Angebot für andere Betreuer** | Dann wäre ich Auftragsverarbeiter für fremde Gesundheitsdaten. Eine andere Aufgabe als die, für die das hier gebaut wurde. | +| **KI-Auswertung der Akte** | Gesundheitsdaten einer nicht entscheidungsfähigen Person verlassen diesen Server nicht. Die Texterkennung läuft lokal, und dabei bleibt es. | + +--- + +## Wie hier priorisiert wird + +Drei Fragen, in dieser Reihenfolge: + +1. **Kann daraus ein falscher Wert in einem Bericht ans Gericht werden?** + Dann sofort — auch wenn es unbequem ist. +2. **Kostet es jeden Monat Zeit?** Dann bald. +3. **Wäre es schön?** Dann irgendwann, und ehrlich gesagt vielleicht nie. + +Fällt ein Punkt in Kategorie 1 und wird trotzdem nicht sofort behoben, +steht der Grund dabei — und die Oberfläche sagt an der betroffenen Stelle, +worauf man achten muss. Ein stillschweigend falscher Wert ist das +Schlimmste, was diese Anwendung produzieren kann. diff --git a/next.config.mjs b/next.config.mjs index bf43217..3182a72 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -6,6 +6,16 @@ const nextConfig = { poweredByHeader: false, // Argon2 ist eine native Bibliothek und darf nicht gebundelt werden. serverExternalPackages: ['@node-rs/argon2'], + + // Zwei Seiten lesen zur Laufzeit eine Markdown-Datei aus docs/: + // die Datenschutzhinweise und die Bedienungsanleitung. Der Pfad wird + // erst zur Laufzeit gebaut, die Dateiverfolgung von Next.js kann ihn + // also nicht erkennen - ohne diesen Eintrag fehlten beide Dateien im + // Standalone-Build, und im Behaelter waeren die Seiten leer. + outputFileTracingIncludes: { + '/datenschutz': ['./docs/datenschutzhinweise.md'], + '/anleitung': ['./docs/ANLEITUNG.md'], + }, eslint: { ignoreDuringBuilds: false, }, diff --git a/src/app/(app)/anleitung/page.tsx b/src/app/(app)/anleitung/page.tsx new file mode 100644 index 0000000..204894b --- /dev/null +++ b/src/app/(app)/anleitung/page.tsx @@ -0,0 +1,55 @@ +import type { Metadata } from 'next' +import { readFile } from 'node:fs/promises' +import path from 'node:path' +import { BookOpen } from 'lucide-react' +import { Alert, AlertDescription } from '@/components/ui/alert' +import { SeitenKopf } from '@/components/seiten-kopf' +import { MarkdownSeite } from '@/components/markdown-seite' +import { DruckKnopf } from '@/components/druck-knopf' +import { erfordereBenutzer } from '@/lib/auth/sitzung' + +export const metadata: Metadata = { title: 'Anleitung' } +export const dynamic = 'force-dynamic' + +/** + * Die Bedienungsanleitung, gelesen aus docs/ANLEITUNG.md. + * + * Dieselbe Datei, die auch im Repository liegt und sich ausdrucken laesst - + * zwei Fassungen desselben Textes waeren zwei Fassungen, die auseinander- + * laufen. Wer im Heim steht und nicht weiterweiss, hat sie damit auf dem + * Telefon dabei. + */ +export default async function AnleitungSeite() { + await erfordereBenutzer() + + const pfad = path.join(process.cwd(), 'docs', 'ANLEITUNG.md') + let inhalt: string + + try { + inhalt = await readFile(pfad, 'utf8') + } catch { + inhalt = '' + } + + return ( +
docs/ANLEITUNG.md.
+ - {absatz.join(' ')} -
, - ) - absatz = [] - } - - zeilen.forEach((zeile, i) => { - const roh = zeile.trim() - - // Der Hinweisblock fuer den Ausfuellenden gehoert nicht auf die Seite. - if (roh.startsWith('>')) return - - if (roh === '' || roh === '---') { - absatzSchliessen(i) - return - } - if (roh.startsWith('## ')) { - absatzSchliessen(i) - bloecke.push( -nach Art. 13 und 14 DSGVO
+ +
+ Der Text konnte nicht geladen werden. Er liegt im Projekt unter{' '}
+ docs/datenschutzhinweise.md.
+
diff --git a/src/components/benutzer-menue.tsx b/src/components/benutzer-menue.tsx
index fe2c3a2..792f66a 100644
--- a/src/components/benutzer-menue.tsx
+++ b/src/components/benutzer-menue.tsx
@@ -3,7 +3,16 @@
import * as React from 'react'
import Link from 'next/link'
import { signOut } from 'next-auth/react'
-import { LogOut, Monitor, Moon, Settings, ShieldCheck, Sun, User as UserIcon } from 'lucide-react'
+import {
+ BookOpen,
+ LogOut,
+ Monitor,
+ Moon,
+ Settings,
+ ShieldCheck,
+ Sun,
+ User as UserIcon,
+} from 'lucide-react'
import {
DropdownMenu,
DropdownMenuContent,
@@ -96,6 +105,12 @@ export function BenutzerMenue({
Einstellungen
+
+ {inline(block.text, String(i))}
+
+ {inline(zeile, `${i}-${j}`)}
+
+ {stueck.slice(1, -1)}
+ ,
+ )
+ } else if (stueck.startsWith('**')) {
+ teile.push(
+
+ {stueck.slice(2, -2)}
+ ,
+ )
+ } else {
+ const beschriftung = stueck.slice(1, stueck.indexOf(']'))
+ const ziel = stueck.slice(stueck.indexOf('](') + 2, -1)
+ const extern = /^https?:\/\//.test(ziel)
+ teile.push(
+
+ {beschriftung}
+ ,
+ )
+ }
+
+ letzte = treffer.index + stueck.length
+ }
+
+ if (letzte < text.length) teile.push(text.slice(letzte))
+ return teile
+}
+
+function zerlegen(markdown: string, ohneTitel: boolean): Block[] {
+ const zeilen = markdown.split(/\r?\n/)
+ const bloecke: Block[] = []
+ let absatz: string[] = []
+
+ const absatzSchliessen = () => {
+ if (absatz.length === 0) return
+ bloecke.push({ art: 'absatz', text: absatz.join(' ') })
+ absatz = []
+ }
+
+ for (let i = 0; i < zeilen.length; i++) {
+ const roh = zeilen[i] ?? ''
+ const zeile = roh.trimEnd()
+ const gekuerzt = zeile.trim()
+
+ // --- Codeblock ---------------------------------------------------------
+ if (gekuerzt.startsWith('```')) {
+ absatzSchliessen()
+ const inhalt: string[] = []
+ i += 1
+ while (i < zeilen.length && !(zeilen[i] ?? '').trim().startsWith('```')) {
+ inhalt.push(zeilen[i] ?? '')
+ i += 1
+ }
+ bloecke.push({ art: 'code', zeilen: inhalt })
+ continue
+ }
+
+ if (gekuerzt === '') {
+ absatzSchliessen()
+ continue
+ }
+
+ if (/^-{3,}$/.test(gekuerzt) || /^\*{3,}$/.test(gekuerzt)) {
+ absatzSchliessen()
+ bloecke.push({ art: 'trenner' })
+ continue
+ }
+
+ // --- Ueberschriften ----------------------------------------------------
+ const ueberschrift = gekuerzt.match(/^(#{1,4})\s+(.*)$/)
+ if (ueberschrift) {
+ absatzSchliessen()
+ const ebene = ueberschrift[1]!.length
+ // Die H1 ist der Dokumenttitel - den setzt die Seite selbst.
+ if (ebene === 1 && ohneTitel) continue
+ bloecke.push({
+ art: 'ueberschrift',
+ ebene: (Math.min(Math.max(ebene, 2), 4) as 2 | 3 | 4),
+ text: ueberschrift[2]!,
+ })
+ continue
+ }
+
+ // --- Zitatblock --------------------------------------------------------
+ if (gekuerzt.startsWith('>')) {
+ absatzSchliessen()
+ const inhalt: string[] = []
+ while (i < zeilen.length && (zeilen[i] ?? '').trim().startsWith('>')) {
+ inhalt.push((zeilen[i] ?? '').trim().replace(/^>\s?/, ''))
+ i += 1
+ }
+ i -= 1
+ bloecke.push({ art: 'zitat', zeilen: [inhalt.join(' ')] })
+ continue
+ }
+
+ // --- Tabelle -----------------------------------------------------------
+ if (gekuerzt.startsWith('|')) {
+ absatzSchliessen()
+ const spalten = (z: string) =>
+ z
+ .trim()
+ .replace(/^\|/, '')
+ .replace(/\|$/, '')
+ .split('|')
+ .map((s) => s.trim())
+
+ const kopf = spalten(gekuerzt)
+ i += 1 // Trennzeile ueberspringen
+ const zeilenInhalt: string[][] = []
+ while (i + 1 < zeilen.length && (zeilen[i + 1] ?? '').trim().startsWith('|')) {
+ i += 1
+ zeilenInhalt.push(spalten(zeilen[i] ?? ''))
+ }
+ bloecke.push({ art: 'tabelle', kopf, zeilen: zeilenInhalt })
+ continue
+ }
+
+ // --- Aufzaehlung -------------------------------------------------------
+ const punkt = gekuerzt.match(/^(?:[-*]|\d+\.)\s+(.*)$/)
+ if (punkt) {
+ absatzSchliessen()
+ const nummeriert = /^\d+\./.test(gekuerzt)
+ const punkte: string[] = [punkt[1]!]
+
+ while (i + 1 < zeilen.length) {
+ const naechste = (zeilen[i + 1] ?? '').trim()
+ const weiterer = naechste.match(/^(?:[-*]|\d+\.)\s+(.*)$/)
+ if (weiterer && /^\d+\./.test(naechste) === nummeriert) {
+ punkte.push(weiterer[1]!)
+ i += 1
+ continue
+ }
+ // Eingerueckte Fortsetzung gehoert zum letzten Punkt.
+ if (naechste !== '' && /^\s{2,}\S/.test(zeilen[i + 1] ?? '')) {
+ punkte[punkte.length - 1] += ` ${naechste}`
+ i += 1
+ continue
+ }
+ break
+ }
+
+ bloecke.push({ art: 'liste', nummeriert, punkte })
+ continue
+ }
+
+ absatz.push(gekuerzt)
+ }
+
+ absatzSchliessen()
+ return bloecke
+}
+
+export function MarkdownSeite({
+ inhalt,
+ ohneTitel = true,
+ className,
+}: {
+ inhalt: string
+ /** Die erste H1 weglassen - die Seite setzt ihre Ueberschrift selbst. */
+ ohneTitel?: boolean
+ className?: string
+}) {
+ const bloecke = zerlegen(inhalt, ohneTitel)
+
+ return (
+
+
+
+
+ {block.kopf.map((spalte, j) => (
+
+
+
+ {block.zeilen.map((zeile, j) => (
+
+ {inline(spalte, `${i}-k-${j}`)}
+
+ ))}
+
+ {zeile.map((zelle, k) => (
+
+ ))}
+
+
+ {inline(zelle, `${i}-${j}-${k}`)}
+
+ ))}
+
+ {block.zeilen.map((zeile, j) => (
+
+ )
+
+ case 'code':
+ return (
+
+
+ )
+
+ case 'trenner':
+ return {block.zeilen.join('\n')}
+
+ }
+ })}
+