Zwei Mängel, die erst in den aufgenommenen Bildern auffielen. Auf Handybreite brach die Kopfleiste um und drängte den Namen der Anwendung in die zweite Zeile, mitten zwischen die Menüpunkte. Sie bleibt jetzt auf allen Breiten einzeilig; wird es eng, scrollt die Navigation waagerecht. Das Tagesdatum auf der Startseite wird serverseitig gerendert, weshalb Playwrights Uhr nicht griff — die Bilder hätten sich täglich geändert. In der Screenshot-Instanz (DEMO_MODUS=true) steht die Uhr jetzt fest. Reine Funktionen bekommen den Zeitpunkt weiterhin als Parameter; src/server/ zeitgeber.ts ist die eine Stelle, an der er entsteht. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
6.9 KiB
Entwicklungstagebuch
Neuester Eintrag oben. Die Dauer je Sitzung stammt aus devlog/zeiten.csv,
die Übersicht aus scripts/zeit.sh summe.
Zeit je Meilenstein
| Meilenstein | Art | Minuten | Stunden |
|---|---|---|---|
| M1 | claude | (wird beim Abschluss eingetragen) |
2026-09-10 – M1: Fundament
Ziel der Sitzung: Das Projekt von Grund auf aufsetzen: Gerüst, Datenbank, Anmeldung, Rollen, Audit, Instanzsteuerung, Betrieb und Dokumentation.
Erledigt
- Projektgerüst mit Next 16, React 19, TypeScript strict, Tailwind 4, alle Versionen exakt gepinnt
npm run pruefenals Sammelprüfung: Prettier, ESLint,tsc, Vitest, ShellCheck- Datenmodell und erste Migration: Benutzer mit Rolle, OIDC-Konten, Passkeys, WebAuthn-Herausforderungen, Bereiche, Audit
- Anmeldung über OIDC, Passkey und Passwort, je Instanz zuschaltbar
- Rollenprüfung in Seite und Server Action, Audit je Schreibaktion
- Instanzsteuerung mit 404 statt Hinweis
- Bereiche verwalten, Protokollseite, Startseite, Einstellungen
/api/health, Dockerfile, Compose-Stapel mit Migrationsdienstbackup.sh,update.sh,scripts/release.sh,scripts/zeit.sh- Unit-, Integrations-, Migrations- und E2E-Tests
- Screenshot-Kette mit eigener Wegwerf-Instanz
- README, Schnellstart, Handbuch, ROADMAP, CHANGELOG
Entscheidungen mit Begründung
Prisma 7.10.0 statt der notierten Fassung 6. Fassung 6 ist überholt,
Fassung 8 liegt nur als RC auf latest. Prisma 7 nimmt die Verbindung
nicht mehr im Schema entgegen — sie steht in prisma.config.ts, der
Client bekommt den pg-Treiberadapter.
TypeScript 6.0.3 statt 7.0.2. TS 7 ist zwar latest, aber
typescript-eslint@8.70 verlangt typescript >=4.8.4 <6.1.0. Mit TS 7
wäre die Lint-Kette kaputt gewesen.
ESLint 9.39.5 statt 10. Das in eslint-config-next@16 gebündelte
eslint-plugin-react ruft noch context.getFilename(), das ESLint 10
entfernt hat. Der Lint-Lauf brach reproduzierbar ab.
Eigener Auth.js-Adapter. Der mitgelieferte @auth/prisma-adapter
greift fest auf prisma.user und prisma.account zu; unsere Modelle
heißen Benutzer und Konto. Der Adapter ist schmal und ersparte es,
die Fachbegriffe der Konvention zu opfern.
Passkeys direkt über SimpleWebAuthn 14. Der WebAuthn-Provider von
Auth.js ist als experimentell markiert und auf SimpleWebAuthn 9
festgelegt. Direkt angebunden bleibt die Fassung aktuell und der Ablauf
nachvollziehbar. Für die npm-Auflösung brauchte es overrides, weil
next-auth die älteren Fassungen als optionale Peers deklariert.
Sitzungen als JWT, Rolle trotzdem aus der Datenbank. Credentials-
Provider verlangen JWT. Damit eine Sperre nicht bis zum Ablauf des Tokens
wirkungslos bleibt, liest der session-Callback Rolle und Status bei
jeder Anfrage frisch. Die Tabellen sitzung und verifizierungs_token
wären damit tot und wurden wieder entfernt, solange es nur eine einzige
Migration gab.
Migrationen als eigener Compose-Dienst. Der Versuch, nur die
Prisma-CLI ins schlanke Laufzeitabbild zu kopieren, scheiterte an ihren
transitiven Modulen (effect über @prisma/config). Alle mitzunehmen
hätte das Abbild aufgebläht. Ein Einmaldienst aus der Bau-Stufe läuft vor
der App und muss sauber durchlaufen.
Aufgabe, Zeitblock und Kalenderkonto bewusst nicht modelliert. Sie kommen mit M2, M4 und M3 — dann mit den Feldern, die der jeweilige Provider wirklich braucht, statt heute geraten.
Probleme und Lösungen
| Problem | Lösung |
|---|---|
prisma validate lehnte url im Schema ab |
Prisma 7 erwartet die Verbindung in prisma.config.ts und einen Treiberadapter im Client. |
| Integrationstest brach nach der ersten erwarteten Verletzung ab | In PostgreSQL bricht ein fehlgeschlagener Befehl die ganze Transaktion ab. Der Test läuft jetzt ohne Sammeltransaktion; alle Testdaten tragen eine Kennung und werden am Ende entfernt. |
prisma migrate diff kannte --from-url nicht |
In Prisma 7 heißen die Flaggen anders. Der Test vergleicht jetzt die eingespielte Wegwerf-Datenbank über --from-config-datasource gegen das Schema — und braucht damit keine Schattendatenbank. |
| Nach der Anmeldung ging es nicht zum ursprünglichen Ziel zurück | Das Layout leitet um, bevor die Seite drankommt, und kennt seinen Pfad nicht. Ein schlanker Proxy reicht ihn als Kopfzeile durch — ohne Anmeldelogik, weil er im Edge-Umfeld läuft. |
| Der Docker-Bau brach beim Sammeln der Seitendaten ab | Prisma-Client und Auth.js-Konfiguration wurden beim Laden des Moduls ausgewertet und brauchten Umgebungsvariablen, die es zur Bauzeit nicht gibt. Beide entstehen jetzt faul. |
Ein Typfehler in scripts/screenshots.ts blockierte den Abbild-Bau |
Entwicklungsskripte gehören nicht in den Docker-Kontext. .dockerignore schließt sie aus; geprüft werden sie von npm run pruefen. |
ESLint beanstandete setState im Effekt |
Der Hydratations-Trick im Farbschema-Knopf war unnötig: next-themes setzt die dark-Klasse vor der Hydratation, das erledigt CSS ohne Zustand. |
Eigene Fehler, die ich korrigiert habe
- Die ersten vier Commits lagen direkt auf
mainstatt auf einem Meilenstein-Zweig und ohne Attributionszeile. Historie umgebaut:mainträgt nur noch einen leeren Wurzel-Commit, die Arbeit liegt aufm1-fundament. - Ein
git add -Azog die Proxy-Umbenennung in den Doku-Commit. Wieder getrennt. scripts/screenshots.tswurde geschrieben, ohne danachnpm run pruefenlaufen zu lassen; der Typfehler fiel erst im Docker-Bau auf.
Offene Punkte
- Die
origin-URL fehlt noch. Push und Merge stehen ohnehin erst nach der Freigabe an. - Der Schnellstart endet beim Passkey statt beim ersten Kalenderkonto und der ersten Aufgabe — beides gibt es erst mit M3 und M2.
- Der Demo-Seed enthält noch keine erfundenen Termine; einen Demo-Kalenderprovider gibt es erst mit M3.
- Lokal weichen die Ports ab (Datenbank 5435, App 3001), weil 5432 und
3000 auf diesem Rechner belegt sind. In
.env.examplestehen die üblichen Werte.
Commits
Siehe git log --oneline main..m1-fundament.