Kein neues Modul. Zwölf Phasen sind fertig, und die Wehr kann ab jetzt echte Daten hineingeben, ohne befürchten zu müssen, sie beim nächsten Update zu verlieren.
Dazu die beiden Dinge, die du angefragt hast: ein Update-Skript für Linux und eine einfache Anleitung.
update.sh
Ein Befehl, ausführbar eingecheckt (100755).
./update.sh --pruefen # nur nachsehen, ändert nichts
./update.sh # einspielen
Der Ablauf ist so gebaut, dass ein Abbruch nie eine halb aktualisierte Anlage hinterlässt:
Nachsehen, ob überhaupt etwas Neues da ist — sonst endet es hier.
Sichern. Vor allem anderen; ein Update ist der häufigste Anlass, eine Sicherung zu brauchen, und der Moment, in dem niemand daran denkt.
Holen und bauen. Schlägt das fehl, läuft die alte Fassung unverändert weiter — es wurde noch nichts umgeschaltet.
Umschalten. Der App-Container spielt dabei die Migrationen ein.
Nachsehen, ob die Anwendung antwortet. Tut sie es nach zweieinhalb Minuten nicht, stehen die letzten Protokollzeilen da und die Befehle, mit denen der vorherige Stand zurückkommt.
Vorher prüft es Docker, git, die .env und dass keine unverbuchten Änderungen im Verzeichnis liegen. --ohne-sicherung gibt es für Testinstallationen, mit Warnung und nicht als Vorgabe.
docs/KURZANLEITUNG.md
Nach Rollen sortiert, 283 Zeilen statt 63 Kapitel: für alle, Gerätewart, Atemschutzgerätewart, Kommandant, Kassier, Serverbetreiber.
Aufgabenorientiert statt nach Modulen — „ein Gerät prüfen", „einen Kontoauszug einlesen", „einen Termin absagen". Und bei jedem heiklen Punkt steht das Warum dabei: warum ein abgeschlossenes Prüfprotokoll nicht änderbar ist, warum gegengebucht statt korrigiert wird, warum der Atemschutzhinweis stehen bleibt. Wer den Grund kennt, sucht nicht nach dem Weg drumherum.
Die große Anleitung bleibt als Nachschlagewerk und verweist oben auf die kurze.
Was 1.0.0 bedeutet — und was nicht
Bedeutet: Funktionsumfang vollständig, Datenbank stabil, Migrationen aufwärtskompatibel, ab hier semantische Versionierung. Ein Update bricht nichts, ohne dass es in der Hauptnummer steht.
Bedeutet nicht: dass keine Fehler mehr da sind.
Die Roadmap hält den Stand jeder Freigabevoraussetzung fest, auch der offenen:
Voraussetzung
Stand
Datenübernahme
entfällt — ihr pflegt von Hand ein
Sicherungskonzept, einmal wiederhergestellt
erledigt (Phase 11)
Löschkonzept nach DSGVO
technisch vollständig, Abnahme steht aus
Schulung
steht aus, Grundlage ist die Kurzanleitung
Atemschutzhinweis
bewusst stehen gelassen — FLORIAN bleibt ergänzend
Die beiden offenen Punkte sind organisatorisch; an der Software hängt nichts davon ab. Sie stehen dort, damit später nachlesbar ist, was zum Zeitpunkt der Freigabe erledigt war — eine Freigabe, die abhakt was nicht geprüft wurde, ist keine.
Nebenbei: die Ursache der Testflackerei gefunden
Sie hat sich durch mehrere Phasen gezogen, und ich habe sie zu lange als Umgebungsrauschen abgetan.
ki-datenbank.test.ts und atemschutz-datenbank.test.ts schalteten beim Aufräumen ihre Trigger mit ALTER TABLE ... DISABLE TRIGGER USER ab. Das ist eine Schemaänderung: sie gilt für die ganze Datenbank und für alle. Vitest fährt die Testdateien parallel — während also die eine Datei abräumte, prüfte die andere gerade, dass genau dieser Trigger greift, und sah keinen.
Rückwirkend erklärt das eine Reihe von Ausfällen, die als „Flackern" abgetan wurden und keines waren. Jetzt SET LOCAL session_replication_role = 'replica': dieselbe Wirkung, aber nur in der eigenen Transaktion.
Dazu räumt mandanten-datenbank.test.ts nicht mehr nur am Ende auf, sondern auch am Anfang — ein abgebrochener Lauf legte sonst den nächsten lahm.
Nachweise
npm run typecheck — ohne Ausgabe
npm run lint — ohne Befund
npm run test — fünfmal hintereinander 601 grün. Das war nach elf Phasen der erste Lauf, bei dem ich das behaupten kann
npm run test:e2e — 268 grün, kein Fehlschlag, kein Flackern. Ebenfalls der erste vollständig saubere Durchlauf
npm run build — sauber
bash -n update.sh, --help, unbekannte Angabe, und der Wächter gegen unverbuchte Änderungen: alle wie vorgesehen
Alle acht Bilder der Kurzanleitung existieren
Zwei Dinge, die ich nicht belegen kann
update.sh ist nicht auf einem Linux-Server gelaufen. Entwickelt unter Windows; geprüft sind Syntax, Hilfe, Argumentbehandlung und die Wächter unter Git Bash. Der eigentliche Ablauf läuft erst dort, wo FLORIAN wirklich steht. Beim ersten Einsatz bitte ./update.sh --pruefen voranstellen — es ändert nichts, zeigt aber, ob Docker, git und die .env gefunden werden.
Die Pipeline aus Phase 11 wartet weiter auf einen act_runner.
Kein neues Modul. Zwölf Phasen sind fertig, und die Wehr kann ab jetzt echte Daten hineingeben, ohne befürchten zu müssen, sie beim nächsten Update zu verlieren.
Dazu die beiden Dinge, die du angefragt hast: ein Update-Skript für Linux und eine einfache Anleitung.
## `update.sh`
Ein Befehl, ausführbar eingecheckt (`100755`).
```bash
./update.sh --pruefen # nur nachsehen, ändert nichts
./update.sh # einspielen
```
Der Ablauf ist so gebaut, dass ein Abbruch nie eine halb aktualisierte Anlage hinterlässt:
1. **Nachsehen**, ob überhaupt etwas Neues da ist — sonst endet es hier.
2. **Sichern.** Vor allem anderen; ein Update ist der häufigste Anlass, eine Sicherung zu brauchen, und der Moment, in dem niemand daran denkt.
3. **Holen und bauen.** Schlägt das fehl, läuft die alte Fassung unverändert weiter — es wurde noch nichts umgeschaltet.
4. **Umschalten.** Der App-Container spielt dabei die Migrationen ein.
5. **Nachsehen**, ob die Anwendung antwortet. Tut sie es nach zweieinhalb Minuten nicht, stehen die letzten Protokollzeilen da und die Befehle, mit denen der vorherige Stand zurückkommt.
Vorher prüft es Docker, git, die `.env` und dass keine unverbuchten Änderungen im Verzeichnis liegen. `--ohne-sicherung` gibt es für Testinstallationen, mit Warnung und nicht als Vorgabe.
## `docs/KURZANLEITUNG.md`
Nach Rollen sortiert, 283 Zeilen statt 63 Kapitel: für alle, Gerätewart, Atemschutzgerätewart, Kommandant, Kassier, Serverbetreiber.
Aufgabenorientiert statt nach Modulen — „ein Gerät prüfen", „einen Kontoauszug einlesen", „einen Termin absagen". Und bei jedem heiklen Punkt steht das **Warum** dabei: warum ein abgeschlossenes Prüfprotokoll nicht änderbar ist, warum gegengebucht statt korrigiert wird, warum der Atemschutzhinweis stehen bleibt. Wer den Grund kennt, sucht nicht nach dem Weg drumherum.
Die große Anleitung bleibt als Nachschlagewerk und verweist oben auf die kurze.
## Was 1.0.0 bedeutet — und was nicht
**Bedeutet:** Funktionsumfang vollständig, Datenbank stabil, Migrationen aufwärtskompatibel, ab hier semantische Versionierung. Ein Update bricht nichts, ohne dass es in der Hauptnummer steht.
**Bedeutet nicht:** dass keine Fehler mehr da sind.
Die Roadmap hält den Stand **jeder** Freigabevoraussetzung fest, auch der offenen:
| Voraussetzung | Stand |
|---|---|
| Datenübernahme | **entfällt** — ihr pflegt von Hand ein |
| Sicherungskonzept, einmal wiederhergestellt | **erledigt** (Phase 11) |
| Löschkonzept nach DSGVO | **technisch vollständig**, Abnahme steht aus |
| Schulung | **steht aus**, Grundlage ist die Kurzanleitung |
| Atemschutzhinweis | **bewusst stehen gelassen** — FLORIAN bleibt ergänzend |
Die beiden offenen Punkte sind organisatorisch; an der Software hängt nichts davon ab. Sie stehen dort, damit später nachlesbar ist, was zum Zeitpunkt der Freigabe erledigt war — eine Freigabe, die abhakt was nicht geprüft wurde, ist keine.
## Nebenbei: die Ursache der Testflackerei gefunden
Sie hat sich durch mehrere Phasen gezogen, und ich habe sie zu lange als Umgebungsrauschen abgetan.
`ki-datenbank.test.ts` und `atemschutz-datenbank.test.ts` schalteten beim Aufräumen ihre Trigger mit `ALTER TABLE ... DISABLE TRIGGER USER` ab. Das ist eine **Schemaänderung**: sie gilt für die ganze Datenbank und für alle. Vitest fährt die Testdateien parallel — während also die eine Datei abräumte, prüfte die andere gerade, dass genau dieser Trigger greift, und sah keinen.
Rückwirkend erklärt das eine Reihe von Ausfällen, die als „Flackern" abgetan wurden und keines waren. Jetzt `SET LOCAL session_replication_role = 'replica'`: dieselbe Wirkung, aber nur in der eigenen Transaktion.
Dazu räumt `mandanten-datenbank.test.ts` nicht mehr nur am Ende auf, sondern auch am Anfang — ein abgebrochener Lauf legte sonst den nächsten lahm.
## Nachweise
- `npm run typecheck` — ohne Ausgabe
- `npm run lint` — ohne Befund
- `npm run test` — **fünfmal hintereinander 601 grün.** Das war nach elf Phasen der erste Lauf, bei dem ich das behaupten kann
- `npm run test:e2e` — **268 grün, kein Fehlschlag, kein Flackern.** Ebenfalls der erste vollständig saubere Durchlauf
- `npm run build` — sauber
- `bash -n update.sh`, `--help`, unbekannte Angabe, und der Wächter gegen unverbuchte Änderungen: alle wie vorgesehen
- Alle acht Bilder der Kurzanleitung existieren
## Zwei Dinge, die ich nicht belegen kann
- **`update.sh` ist nicht auf einem Linux-Server gelaufen.** Entwickelt unter Windows; geprüft sind Syntax, Hilfe, Argumentbehandlung und die Wächter unter Git Bash. Der eigentliche Ablauf läuft erst dort, wo FLORIAN wirklich steht. Beim ersten Einsatz bitte `./update.sh --pruefen` voranstellen — es ändert nichts, zeigt aber, ob Docker, git und die `.env` gefunden werden.
- **Die Pipeline aus Phase 11 wartet weiter auf einen `act_runner`.**
Beides steht so auch im Devlog und im README.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Kein Modul, sondern die drei Software-Voraussetzungen fuer 1.0.0:
Auskunft nach Art. 15 DSGVO, ein geprueftes Sicherungskonzept und eine
Pipeline.
Das Auskunftsrecht war ein Versprechen ohne Umsetzung: `person.export`
stand seit Phase 0 im Katalog und war dem Kommandanten zugewiesen,
implementiert war nichts. Ohne Auskunftsseite ist ein Loeschkonzept nicht
abnehmbar. Jetzt sammelt FLORIAN dreizehn Abschnitte ueber eine Person,
mit dem Zweck ueber jedem - Art. 15 verlangt nicht nur die Daten, sondern
auch Zwecke und Rechte, und eine blosse Liste erfuellt die Pflicht nicht.
Ein Durchgang liefert Anzeige, PDF und JSON nach Art. 20.
Die Trennlinie ist "ueber mich" gegen "von mir": was ueber die Person
gespeichert ist, steht vollstaendig drin, auch das Unangenehme. Was sie
getan hat, steht als Zahl drin - die Pruefprotokolle gehoeren zum
Nachweisbestand der Wehr, und vollstaendig ausgeliefert kaeme jeder ueber
eine Selbstauskunft an die Geraeteakten.
Die Rueckspielprobe hat sich sofort bezahlt gemacht: der erste Versuch
lief sauber durch und hatte dabei saemtliche Unveraenderlichkeitsgarantien
der Datenbank entfernt. Die Vorgabeprivilegierung aus dem Init-Skript gibt
jeder von pg_restore neu angelegten Tabelle wieder alle Rechte, und GRANT
kann nur hinzufuegen. Die Anwendungsrolle durfte danach das Audit-Log
aendern, Wiki-Fassungen loeschen, Kiosk-Vorgaenge umschreiben - und nichts
haette darauf hingewiesen. Gefunden haben es vier Datenbanktests
unmittelbar nach der Probe, also genau die Probe, wegen der 1.0.0 sie
verlangt.
Die Pipeline ist geschrieben, aber NICHT erprobt: in Gitea ist kein
act_runner registriert. Das steht so im README und im Devlog, damit sich
niemand auf eine Pruefung verlaesst, die nicht stattfindet.
601 Unit-Tests gruen; Sicherung und Wiederherstellung einmal vollstaendig
durchgefuehrt und die Tests danach erneut gruen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Kein neues Modul. Zwoelf Phasen sind fertig, und die Wehr kann ab jetzt
echte Daten hineingeben, ohne befuerchten zu muessen, sie beim naechsten
Update zu verlieren.
Neu dazu, weil beides zum Betrieb gehoert:
update.sh aktualisiert auf einem Linux-Server in einem Befehl. Der Ablauf
darf an jeder Stelle abbrechen, ohne eine halb aktualisierte Anlage zu
hinterlassen: erst nachsehen ob es etwas Neues gibt, dann sichern, dann
holen und bauen (schlaegt das fehl, laeuft die alte Fassung unveraendert
weiter), dann umschalten, dann pruefen ob die Anwendung antwortet. Tut sie
es nicht, stehen die Protokollzeilen da und die Befehle fuer den Rueckweg.
docs/KURZANLEITUNG.md ist der Einstieg fuer die Wehr - nach Rollen
sortiert, aufgabenorientiert statt nach Modulen, und bei jedem heiklen
Punkt steht das Warum dabei. Die vollstaendige Anleitung hat 63 Kapitel;
die liest niemand, bevor er das erste Geraet pruefen will.
Die Roadmap haelt den Stand JEDER Freigabevoraussetzung fest, auch der
offenen: Datenuebernahme entfaellt (die Wehr pflegt von Hand ein),
Sicherungskonzept erledigt, Loeschkonzept technisch vollstaendig aber
nicht abgenommen, Schulung steht aus, Atemschutzhinweis bewusst stehen
gelassen. Eine Freigabe, die abhakt was nicht geprueft wurde, ist keine.
Nebenbei die Ursache der Testflackerei gefunden, die sich durch mehrere
Phasen zog: zwei Datenbanktests schalteten beim Aufraeumen ihre Trigger
mit ALTER TABLE ... DISABLE TRIGGER ab - eine Schemaaenderung, die fuer
die ganze Datenbank gilt. Vitest faehrt die Dateien parallel, also pruefte
eine Datei gerade dass ein Trigger greift, waehrend eine andere ihn
abgeraeumt hatte. Jetzt sitzungslokal ueber session_replication_role.
Erstmals in diesem Projekt: fuenf Unit-Testlaeufe hintereinander 601 gruen
und ein E2E-Lauf mit 268 gruen ohne Fehlschlag und ohne Flackern.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Kein neues Modul. Zwölf Phasen sind fertig, und die Wehr kann ab jetzt echte Daten hineingeben, ohne befürchten zu müssen, sie beim nächsten Update zu verlieren.
Dazu die beiden Dinge, die du angefragt hast: ein Update-Skript für Linux und eine einfache Anleitung.
update.shEin Befehl, ausführbar eingecheckt (
100755).Der Ablauf ist so gebaut, dass ein Abbruch nie eine halb aktualisierte Anlage hinterlässt:
Vorher prüft es Docker, git, die
.envund dass keine unverbuchten Änderungen im Verzeichnis liegen.--ohne-sicherunggibt es für Testinstallationen, mit Warnung und nicht als Vorgabe.docs/KURZANLEITUNG.mdNach Rollen sortiert, 283 Zeilen statt 63 Kapitel: für alle, Gerätewart, Atemschutzgerätewart, Kommandant, Kassier, Serverbetreiber.
Aufgabenorientiert statt nach Modulen — „ein Gerät prüfen", „einen Kontoauszug einlesen", „einen Termin absagen". Und bei jedem heiklen Punkt steht das Warum dabei: warum ein abgeschlossenes Prüfprotokoll nicht änderbar ist, warum gegengebucht statt korrigiert wird, warum der Atemschutzhinweis stehen bleibt. Wer den Grund kennt, sucht nicht nach dem Weg drumherum.
Die große Anleitung bleibt als Nachschlagewerk und verweist oben auf die kurze.
Was 1.0.0 bedeutet — und was nicht
Bedeutet: Funktionsumfang vollständig, Datenbank stabil, Migrationen aufwärtskompatibel, ab hier semantische Versionierung. Ein Update bricht nichts, ohne dass es in der Hauptnummer steht.
Bedeutet nicht: dass keine Fehler mehr da sind.
Die Roadmap hält den Stand jeder Freigabevoraussetzung fest, auch der offenen:
Die beiden offenen Punkte sind organisatorisch; an der Software hängt nichts davon ab. Sie stehen dort, damit später nachlesbar ist, was zum Zeitpunkt der Freigabe erledigt war — eine Freigabe, die abhakt was nicht geprüft wurde, ist keine.
Nebenbei: die Ursache der Testflackerei gefunden
Sie hat sich durch mehrere Phasen gezogen, und ich habe sie zu lange als Umgebungsrauschen abgetan.
ki-datenbank.test.tsundatemschutz-datenbank.test.tsschalteten beim Aufräumen ihre Trigger mitALTER TABLE ... DISABLE TRIGGER USERab. Das ist eine Schemaänderung: sie gilt für die ganze Datenbank und für alle. Vitest fährt die Testdateien parallel — während also die eine Datei abräumte, prüfte die andere gerade, dass genau dieser Trigger greift, und sah keinen.Rückwirkend erklärt das eine Reihe von Ausfällen, die als „Flackern" abgetan wurden und keines waren. Jetzt
SET LOCAL session_replication_role = 'replica': dieselbe Wirkung, aber nur in der eigenen Transaktion.Dazu räumt
mandanten-datenbank.test.tsnicht mehr nur am Ende auf, sondern auch am Anfang — ein abgebrochener Lauf legte sonst den nächsten lahm.Nachweise
npm run typecheck— ohne Ausgabenpm run lint— ohne Befundnpm run test— fünfmal hintereinander 601 grün. Das war nach elf Phasen der erste Lauf, bei dem ich das behaupten kannnpm run test:e2e— 268 grün, kein Fehlschlag, kein Flackern. Ebenfalls der erste vollständig saubere Durchlaufnpm run build— sauberbash -n update.sh,--help, unbekannte Angabe, und der Wächter gegen unverbuchte Änderungen: alle wie vorgesehenZwei Dinge, die ich nicht belegen kann
update.shist nicht auf einem Linux-Server gelaufen. Entwickelt unter Windows; geprüft sind Syntax, Hilfe, Argumentbehandlung und die Wächter unter Git Bash. Der eigentliche Ablauf läuft erst dort, wo FLORIAN wirklich steht. Beim ersten Einsatz bitte./update.sh --pruefenvoranstellen — es ändert nichts, zeigt aber, ob Docker, git und die.envgefunden werden.act_runner.Beides steht so auch im Devlog und im README.
🤖 Generated with Claude Code