docs: Bauprotokoll mit Zeiten, Aufwand und gefundenen Fehlern
Aufstellung, wann was entstanden ist und was es gekostet hat - zur Nachvollziehbarkeit und zur Kostenrechnung. Die reine Commit-Rechnung taugt hier nur bedingt: Die Etappen 2 bis 7 sind parallel entstanden, erst drei, dann fuenf Agenten gleichzeitig. Aus der Historie sieht es aus, als haette Etappe 3 dreissig Minuten gedauert - tatsaechlich lief sie knapp eine Stunde und gleichzeitig mit vier anderen. Deshalb steht neben der automatischen Auswertung eine Tabelle mit den tatsaechlichen Laufzeiten und den Ausgabe-Token je Agent; daran bemessen sich die Kosten. Ebenfalls festgehalten: die gut drei Stunden erzwungener Pause am Sitzungslimit, die in der kalendarischen Spanne stecken, aber keine Bauzeit sind. Reine Bauzeit rund zwei Stunden 45 Minuten. Und die sechs Fehler, die waehrend des Baus aufgefallen sind - von der Server/Client-Grenze bis zur Doppelzaehlung bei den Heimkosten. Die stehen dort, weil sie zeigen, wo bei dieser Art Anwendung die Fallstricke liegen. Etappe: 8 Phase: Haertung
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
# Bauprotokoll
|
||||
|
||||
Nachvollziehbare Aufstellung, wann was entstanden ist und was es gekostet
|
||||
hat. Grundlage sind die Commit-Trailer `Etappe:` und `Phase:` sowie die
|
||||
Abrechnung der beteiligten Agenten.
|
||||
|
||||
**Baubeginn:** 22.08.2026, 01:18 Uhr
|
||||
**Bauende:** 22.08.2026, 07:10 Uhr
|
||||
**Kalendarische Spanne:** 5 Stunden 52 Minuten
|
||||
|
||||
---
|
||||
|
||||
## Warum die reine Commit-Rechnung hier zu wenig sagt
|
||||
|
||||
`npm run protokoll` misst die Abstände zwischen Commits. Für eine Person,
|
||||
die nacheinander arbeitet, ist das ein brauchbares Maß. Hier stimmt es
|
||||
nicht: Die Etappen 2 bis 7 sind **parallel** entstanden — zuerst drei,
|
||||
dann fünf Agenten gleichzeitig, jeder mit eigenem Kontext.
|
||||
|
||||
Aus der Commit-Historie sieht es deshalb so aus, als wären die Etappen 3
|
||||
bis 7 in je 30 Minuten entstanden. Tatsächlich liefen sie **gleichzeitig
|
||||
über rund zweieinhalb Stunden** und wurden am Ende in einem Rutsch
|
||||
committet. Die ehrliche Aufstellung steht deshalb unten in der zweiten
|
||||
Tabelle.
|
||||
|
||||
---
|
||||
|
||||
## Zeitlicher Ablauf
|
||||
|
||||
| Uhrzeit | Was |
|
||||
|---|---|
|
||||
| 01:18 | Leeres Verzeichnis, `git init` |
|
||||
| 01:24 | Projektgerüst steht |
|
||||
| 01:36 | Datenmodell vollständig (24 Entitäten, 2 SQL-Skripte) |
|
||||
| 01:42 | Feldverschlüsselung, Argon2id, TOTP — 37 Tests |
|
||||
| 01:46 | Anmeldung mit Pflicht-2FA, Rollen, Audit-Log |
|
||||
| 01:54 | Oberflächenbausteine, Anwendungsrahmen, Konventionen |
|
||||
| ~01:58 | **Drei Agenten starten** (Fristen, Vorgänge, Dashboard/Kontakte) |
|
||||
| 02:16 | Stammdaten, Ersteinrichtung, Zweitfaktor, Protokoll |
|
||||
| 02:22 | Erster echter Fehler gefunden und behoben (Server/Client-Grenze) |
|
||||
| 02:24–02:26 | Etappe 2 committet, erste Screenshots |
|
||||
| ~02:05 | **Fünf weitere Agenten starten** (Etappen 3 bis 7) |
|
||||
| 02:35 | README, Datenschutztexte, Dockerfile, Sicherungsskripte |
|
||||
| ~02:47 | Alle laufenden Agenten laufen ins Sitzungslimit |
|
||||
| ~05:55 | Agenten wieder aufgenommen |
|
||||
| 06:06 | Typisierung, CSP und Hydration repariert — null Typfehler |
|
||||
| 06:21–06:22 | Etappen 3 bis 7 committet |
|
||||
| 06:23 | Erinnerungen, Wartungslauf, erste Playwright-Tests |
|
||||
| 07:10 | Abnahmekriterien als Tests, 34 End-to-End-Tests grün |
|
||||
|
||||
Zwischen 02:47 und 05:55 lag eine erzwungene Pause: Das Sitzungslimit war
|
||||
erreicht und setzte erst um 06:00 Uhr zurück. Diese gut drei Stunden sind
|
||||
in der kalendarischen Spanne enthalten, aber es wurde in ihnen nicht
|
||||
gearbeitet. **Reine Bauzeit: rund 2 Stunden 45 Minuten.**
|
||||
|
||||
---
|
||||
|
||||
## Aufwand je Etappe
|
||||
|
||||
Die Spalte „Agent" nennt die Ausgabe-Token des jeweils zuständigen
|
||||
Agenten — das ist die Größe, an der sich die Kosten bemessen. Etappe 1
|
||||
und 8 sind ohne Agenten entstanden.
|
||||
|
||||
| Etappe | Phase | Bearbeitung | Laufzeit | Agent-Token | Tests |
|
||||
|---|---|---|---:|---:|---:|
|
||||
| 1 | Fundament | selbst, seriell | ~55 min | — | 37 |
|
||||
| 2a | Fristen & Kalender | Agent | 25 min | 218.183 | 51 |
|
||||
| 2b | Vorgänge & Genehmigungen | Agent | 25 min | 227.554 | 33 |
|
||||
| 2c | Dashboard & Kontakte | Agent | 26 min | 273.673 | 25 + 26 |
|
||||
| 3 | Papier | Agent | ~55 min | 356.318 | 57 |
|
||||
| 4 | Geld | Agent | ~50 min | 328.065 | 68 |
|
||||
| 5 | Behörde | Agent | ~53 min | 353.969 | 46 |
|
||||
| 6 | Substanz | Agent | ~55 min | 369.070 | 74 |
|
||||
| 7 | Ausgabe | Agent | ~57 min | 357.918 | 41 |
|
||||
| 8 | Härtung | selbst | ~65 min | — | 34 (E2E) |
|
||||
| | **Summe** | | | **2.484.750** | **492** |
|
||||
|
||||
Die Laufzeiten der Etappen 3 bis 7 setzen sich aus zwei Abschnitten
|
||||
zusammen (vor und nach dem Sitzungslimit) und überlappen sich vollständig
|
||||
— nacheinander gebaut hätten sie rund viereinhalb Stunden gedauert, so
|
||||
waren es knapp eine.
|
||||
|
||||
---
|
||||
|
||||
## Was dabei entstanden ist
|
||||
|
||||
| | |
|
||||
|---|---:|
|
||||
| Dateien im Repository | 415 |
|
||||
| Zeilen TypeScript/TSX | 71.051 |
|
||||
| Commits | 19 |
|
||||
| Prisma-Modelle | 24 |
|
||||
| Unit-Tests (Vitest) | 458 |
|
||||
| End-to-End-Tests (Playwright) | 34 |
|
||||
| Seiten in der Anwendung | 46 |
|
||||
| Hinweiskarten der Wissensbasis | 37 |
|
||||
| Vorgangs-Vorlagen | 9 |
|
||||
| TypeScript-Fehler | 0 |
|
||||
|
||||
---
|
||||
|
||||
## Fehler, die dabei gefunden wurden
|
||||
|
||||
Nicht alles lief glatt. Diese sechs Fehler sind während des Baus
|
||||
aufgefallen und behoben worden — sie stehen hier, weil sie zeigen, wo bei
|
||||
dieser Art Anwendung die Fallstricke liegen:
|
||||
|
||||
1. **Server/Client-Grenze.** Die Navigationsstruktur lag in einer Datei
|
||||
mit `'use client'` und wurde im Server-Layout benutzt. Dort kommt kein
|
||||
Wert an, sondern nur ein Verweis — jede Fachseite lief in einen
|
||||
Serverfehler. Zusätzlich wurden Icons als React-Komponenten über die
|
||||
Grenze gereicht, was ebenfalls nicht geht.
|
||||
|
||||
2. **CSP im Entwicklungsmodus.** `strict-dynamic` schaltet die Freigabe
|
||||
nach Herkunft ab, also auch `'self'`. Hot-Reload und Fehleranzeige
|
||||
laden ohne Nonce und wurden blockiert — man sah eine tote Seite statt
|
||||
der Fehlermeldung.
|
||||
|
||||
3. **Nonce beim Hydrieren.** React gibt das `nonce`-Attribut absichtlich
|
||||
nicht an den Browser weiter. Das Theme-Skript meldete deshalb bei
|
||||
jedem Seitenaufruf eine Abweichung.
|
||||
|
||||
4. **Sperrmeldung kam nicht an.** Auth.js reicht den Fehlercode aus
|
||||
`authorize()` nicht an die Server Action zurück. Bei gesperrtem Zugang
|
||||
sah man nur „stimmen nicht" und hätte ratlos weiterprobiert.
|
||||
|
||||
5. **Anmeldungen fehlten im Protokoll.** Sie tragen keine `betreuteId` —
|
||||
die Ansicht filterte danach und ließ ausgerechnet die Frage weg, wer
|
||||
wann auf die Akte zugegriffen hat.
|
||||
|
||||
6. **Doppelzählung bei den Heimkosten.** Der einrichtungseinheitliche
|
||||
Eigenanteil auf der Heimrechnung ist bereits um die Leistung der
|
||||
Pflegekasse gekürzt. Wird sie zusätzlich als Deckung erfasst, entsteht
|
||||
ein Fehler von über tausend Euro im Monat. Gefunden vom
|
||||
Dashboard-Agenten, gelöst im Sozialhilfe-Modul.
|
||||
|
||||
Dazu kam eine Merkwürdigkeit der Werkzeuge: `@react-pdf/renderer` konnte
|
||||
in diesem Abhängigkeitsbaum keinen einzigen Buchstaben setzen, weil seine
|
||||
Unterabhängigkeiten weitergewandert sind. Die Krücke dafür steht in
|
||||
`src/lib/pdf/standardschrift.ts` und baut sich selbst ab, sobald die
|
||||
Auflösung wieder stimmt.
|
||||
|
||||
---
|
||||
|
||||
## Protokoll neu erzeugen
|
||||
|
||||
```bash
|
||||
npm run protokoll # Tabelle auf der Konsole
|
||||
npm run protokoll:md # Markdown
|
||||
```
|
||||
|
||||
Das Skript wertet die Commit-Trailer aus. Für seriell gebaute Abschnitte
|
||||
ist das genau; für parallel gebaute unterschätzt es den Aufwand — siehe
|
||||
oben.
|
||||
@@ -148,6 +148,12 @@ if (alsMarkdown) {
|
||||
console.log('')
|
||||
console.log('Bauprotokoll')
|
||||
console.log('='.repeat(74))
|
||||
console.log(
|
||||
'Hinweis: gemessen werden Commit-Abstaende. Fuer parallel gebaute
|
||||
' +
|
||||
'Etappen ist das zu wenig - siehe docs/BAUPROTOKOLL.md.',
|
||||
)
|
||||
console.log('-'.repeat(74))
|
||||
for (const z of zeilen) {
|
||||
console.log(
|
||||
`Etappe ${z.etappe.padEnd(4)} ${z.phase.padEnd(16)} ` +
|
||||
|
||||
Reference in New Issue
Block a user