Files
lernbar/DEVLOG.md
T
Florian WildeandClaude Opus 5 be2a674c7a Baustein 9: Auswertung, Rahmenplanabdeckung, Feedbackgespraech
Die Abdeckung des Ausbildungsrahmenplans ist die Ansicht, die gegenueber
der IHK zaehlt. Sie unterscheidet vier Lagen statt "erledigt/offen":

  vermittelt   eine abgenommene Aufgabe oder ein abgeschlossener
               Checklisten-Durchlauf, oder zwei gelesene Handouts
  angefangen   etwas erledigt, aber noch nicht genug
  geplant      Inhalt vorhanden, nichts davon bearbeitet
  ohne Inhalt  zu dieser Position gibt es im Lehrgang gar nichts

Die vierte Lage ist die wichtigste: Sie ist keine Luecke beim Azubi,
sondern eine im Lehrgang, und wird getrennt ausgewiesen. Die Regel steht
als reine Funktion in src/lib/auswertung/abdeckung.ts, mit 17 Tests.

Das Feedbackgespraech laesst beide Seiten getrennt bewerten. Wo sie um
zwei Stufen oder mehr auseinanderliegen, wird das hervorgehoben - in der
Ansicht, in der Uebersicht und im PDF, alle drei ueber dieselbe Funktion
liegtWeitAuseinander(). Nach beidseitiger Bestaetigung ist das Gespraech
unveraenderlich und wird nur noch gelesen.

Durchstich in scripts/pruefungen/baustein-9.mjs: alle fuenf Luecken
erkannt, getrennte Spalten, Sperre serverseitig, PDF nur mit Anmeldung,
ein fremder Azubi bekommt 404 - auch auf das PDF.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 14:08:49 +02:00

334 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Arbeitstagebuch
Zeiten in Europe/Berlin. Jeder Abschnitt entspricht einem Baustein aus dem
[Fahrplan](ROADMAP.md).
Format: `HH:MM–HH:MM (Dauer) · was gemacht wurde`
---
## 2026-09-11 · Baustein 9 – Auswertung und Feedbackgespräch
| Von | Bis | Dauer | Tätigkeit |
|---|---|---|---|
| 11:10 | 11:25 | 0:15 | Abdeckungsregel als reine Funktion, 17 Tests |
| 11:25 | 11:35 | 0:10 | Datensammlung, Feedback-Vorlage als Inhaltsdatei |
| 11:35 | 11:50 | 0:15 | Datenmodell, Repository, Gesprächsinhalt mit 13 Tests |
| 11:50 | 12:10 | 0:20 | PDF, Auswertungsseite, Gesprächsbogen |
| 12:10 | 12:40 | 0:30 | Prüfen und Durchstich – stark ausgebremst durch die Maschine |
| 12:40 | 13:30 | 0:50 | Durchstichskript, Rechteprüfung mit zweitem Azubikonto |
| 13:30 | 14:15 | 0:45 | Feinschliff am abgeschlossenen Bogen, Abweichung im PDF |
**Summe Baustein 9: rund 3 h**
### Was aufgefallen ist
- Die eigentliche Entscheidung dieses Bausteins ist die Frage, **wann eine
Berufsbildposition als vermittelt gilt.** Eine naive Zählung („Inhalt
vorhanden") wäre wertlos: Dann wäre die Abdeckung von Anfang an voll. Ein
gelesenes Handout allein genügt ebenfalls nicht – sonst wäre sie nach dem
ersten Klick voll. Jetzt zählt eine abgenommene Aufgabe oder ein
abgeschlossener Checklisten-Durchlauf, oder zwei gelesene Handouts.
- Die vierte Lage – **„ohne Inhalt"** – ist die wichtigste und fiel mir erst
beim Schreiben auf. Eine Position, zu der es im ganzen Lehrgang kein Material
gibt, ist keine Lücke beim Azubi, sondern eine im Lehrgang. Ohne eigene
Kennzeichnung würde sie zwischen den unbearbeiteten Positionen verschwinden.
Im Beispielinhalt betrifft das fünf Positionen (A4, A10, C1, C2, C5).
- Beim Feedbackgespräch war die getrennte Bewertung beider Seiten die beste
Entscheidung. Der Wert des Blattes liegt nicht in den Zahlen, sondern in den
Stellen, wo sie auseinandergehen.
- Beim Blick auf den **abgeschlossenen** Bogen fiel auf, dass er wie ein
Formular aussah statt wie ein Dokument: gesperrte Eingabefelder, leere
Bemerkungszeilen mit Platzhaltern, ein zweites Datumsfeld neben dem Datum im
Kopf – und neben „bestätigt" stand ein offener Kreis. Ein Blatt für die Akte
soll nach Abschluss nur noch gelesen werden; jetzt sieht es auch so aus.
- Die Zwei-Stufen-Regel für Abweichungen stand an zwei Stellen und sollte im
PDF eine dritte bekommen. Sie ist jetzt `liegtWeitAuseinander()` in
`src/lib/feedback/inhalt.ts`, mit eigenen Tests – Ansicht, Übersicht und PDF
fragen dieselbe Funktion.
- **Die Maschine war der Engpass, nicht die Arbeit.** Docker Desktop hatte über
fünf Stunden CPU-Zeit verbraucht und der Defender-Echtzeitschutz läuft über
`node_modules`; ein einzelner Testlauf brauchte 4605 Sekunden bei 283 ms
reiner Rechenzeit. Ich habe das Vorgehen umgestellt: erst alles schreiben,
dann **einmal** prüfen, statt nach jedem Schritt.
---
## 2026-09-11 · Baustein 8 – Lernzielkontrollen
| Von | Bis | Dauer | Tätigkeit |
|---|---|---|---|
| 06:25 | 06:35 | 0:10 | Notenschlüssel und Auswertung als reine Rechnung, 15 Tests |
| 06:35 | 06:45 | 0:10 | Sichtbarkeitsschicht für die Musterlösung, 21 Tests |
| 06:45 | 06:55 | 0:10 | Datenmodell, Migration, Repository, Serveraktionen |
| 06:55 | 07:15 | 0:20 | Fragebogen mit Zwischenspeichern, Korrekturansicht, Übersichten |
| 07:15 | 08:50 | 1:35 | Bau und Durchstich – davon über eine Stunde Wartezeit (siehe unten) |
**Summe Baustein 8: rund 2 h 25 min, davon knapp 1 h reine Wartezeit**
### Was aufgefallen ist
- Der Kern dieses Bausteins ist eine einzige Funktion: `sichtbareKontrolle()`
entfernt die Musterlösung, bevor die Daten in die Ausgabe gelangen. Sie nimmt
bewusst den ganzen Betrachter und den Bearbeitungsstand entgegen statt eines
vorberechneten Wahrheitswerts – so kann kein Aufrufer versehentlich `true`
übergeben.
- Beim Lecktest zunächst ein Fehlalarm: Die Prüfung meldete
„Discover, Offer, Request, Acknowledge" im Quelltext. Das war meine **eigene
Testantwort**, die ich zuvor eingetippt hatte. Danach ein sauberer Aufbau,
der die Musterlösungen direkt aus der Inhaltsdatei liest und gegen Text
prüft, den ich nicht selbst eingebe. Ergebnis: vor der Abgabe null Treffer,
nach der Abgabe alle fünf – damit ist auch belegt, dass die Suche überhaupt
finden kann.
- **Eine Stunde an der Umgebung verloren.** Erst hing `next build` endlos, weil
der laufende Server `.next` festhielt und ich ihn mitten im Schreiben
abgeschossen hatte. Nach `Remove-Item .next -Recurse` lief der Bau in acht
Sekunden. Danach brauchte `next start` **2822 Sekunden** bis „Ready" – das
Dateisystem war zu dem Zeitpunkt extrem langsam, vermutlich ein Virenscanner
über dem frisch gebauten Verzeichnis. Lehre: Vor einem Bau immer erst den
Server stoppen, und ein hängender Start ist nicht zwingend ein Codefehler.
- Die laufende Summe beim Korrigieren war nachträglich die beste Idee an der
Oberfläche: Man sieht beim Verteilen der Punkte, auf welcher Note man landet,
statt es hinterher zu erfahren.
---
## 2026-09-10 · Baustein 7 – Berichtsheft
| Von | Bis | Dauer | Tätigkeit |
|---|---|---|---|
| 21:50 | 22:05 | 0:15 | Prüflogik: Stunden, Floskeln, schützenswerte Angaben – mit 31 Tests |
| 22:05 | 22:15 | 0:10 | Vorschläge aus dem System, Formulierungshilfe, 15 Tests |
| 22:15 | 22:25 | 0:10 | Datenmodell, Migration, Repository |
| 22:25 | 22:40 | 0:15 | PDF im IHK-Layout mit Kästen, Stundenspalten und Unterschriften |
| 22:40 | 23:00 | 0:20 | Seiten, Formulare, Abzeichnen, Tagesnotizen |
| 23:00 | 23:15 | 0:15 | Durchstich über den ganzen Weg, zwei Fehler behoben |
**Summe Baustein 7: rund 1 h 25 min**
### Was aufgefallen ist
- Die Floskelprüfung war der kniffligste Teil. „Diverse Arbeiten" ist eine
Floskel, „Diverse Patchkabel konfektioniert und beschriftet" nicht. Gelöst
über zwei Bedingungen: Die Prüfung schlägt an, wenn die Floskel den Eintrag
im Wesentlichen ausmacht **oder** wenn im ganzen Eintrag kein einziges
Tätigkeitsverb vorkommt.
- Bei den Kundennamen hat ein Test einen echten Fehler gefunden: „Beispiel
e. V." wurde nicht erkannt. Ursache war ein `\b` am Ende des Musters – nach
einem Punkt gibt es vor einem Leerzeichen keine Wortgrenze. Ersetzt durch
einen negativen Vorausblick.
- ESLint hat wieder einen echten Bug gefunden: Das Abzeichnen-Formular hatte
gar keine `action`, der Knopf hätte nichts bewirkt. Sichtbar wurde das nur
über die Meldung „Serveraktion zugewiesen, aber nie benutzt".
- Im PDF-Kopffeld liefen die beiden Spalten auseinander, weil ich `dokument.y`
als Bezugspunkt in der Schleife benutzt habe – der Wert wandert aber bei
jedem Schreibvorgang weiter. Wieder etwas, das erst beim Ansehen auffiel.
- Beim Prüfen des PDF-Zugriffs ohne Anmeldung kam zunächst 200. Erst der
zweite Blick mit `maxRedirects: 0` zeigte: 307 auf /anmelden, 0 Byte, kein
PDF. Playwright war der Weiterleitung gefolgt. Merke: Bei
Berechtigungsprüfungen nie den Weiterleitungen folgen lassen.
- Die laufende Nummer eines Wochenblatts richtet sich nach dem Zeitraum, nicht
nach der Reihenfolge des Anlegens. Wer eine Woche nachträgt, soll Nr. 3
bekommen und nicht Nr. 12 – die dahinterliegenden Blätter rücken auf.
---
## 2026-09-10 · Baustein 6 – Checklisten und PDF
| Von | Bis | Dauer | Tätigkeit |
|---|---|---|---|
| 20:35 | 20:42 | 0:07 | Datenmodell, Migration, Schema |
| 20:42 | 20:48 | 0:06 | Gruppenfortschritt als reine Rechnung, 16 Tests |
| 20:48 | 20:52 | 0:04 | PDF-Grundlage und Checklisten-PDF |
| 20:52 | 21:00 | 0:08 | Repository, Aktionen, Seiten, PDF-Route |
| 21:00 | 21:10 | 0:10 | Durchstich; PDF gerendert und den Fußzeilenfehler gefunden |
| 21:10 | 21:20 | 0:10 | Fehler behoben, Regressionstest, Dokumente |
**Summe Baustein 6: rund 45 min**
### Was aufgefallen ist
- **Das PDF hatte sechs Seiten, vier davon leer.** Aufgefallen ist das erst
beim Ansehen – die Prüfung „Status 200, Content-Type application/pdf" war
grün. Ursache: Die Fußzeile wird unterhalb des Satzspiegels gesetzt, und
PDFKit hält das für überlaufenden Text und legt eine neue Seite an. Bei zwei
Seiten mal zwei Textaufrufen macht das vier leere Seiten. Behoben, indem der
untere Rand für die Dauer der Fußzeile auf 0 gesetzt wird. Ein Test zählt
jetzt die Seitenobjekte im PDF und hätte den Fehler gefunden.
- Headless-Chromium rendert keine PDFs. Für den Blick aufs Ergebnis musste
der Browser mit Fenster starten (`headless: false`) – auf diesem Rechner
geht das, auf einem Server nicht. Für die spätere Prüfstrecke heißt das:
Seitenzahl und Inhalt maschinell prüfen, das Aussehen von Hand.
- Titel und Schritttexte werden beim Start des Durchlaufs kopiert statt
verwiesen. Ein Nachweis, der sich rückwirkend ändert, wenn jemand die
Vorlage anfasst, wäre keiner.
- Der Ausbilder darf das PDF abrufen und mitlesen, aber nicht abhaken. Erst
beim Schreiben der Aktion ist mir aufgefallen, dass „darf sehen" und „darf
bearbeiten" hier auseinanderfallen – daher zwei getrennte Prüffunktionen.
---
## 2026-09-10 · Baustein 5 – Praxisaufgaben
| Von | Bis | Dauer | Tätigkeit |
|---|---|---|---|
| 11:55 | 12:05 | 0:10 | Datenmodell für Aufgabenstand und Anhänge, Migration, Schema |
| 12:05 | 12:20 | 0:15 | Dateiregeln (Typen, Größe, Namenssäuberung, Speicherpfad) und 24 Tests dazu |
| 12:20 | 12:35 | 0:15 | Repositories, Serveraktionen, Ausliefer-Route mit Rechteprüfung |
| 12:35 | 13:00 | 0:25 | Aufgabenliste, Aufgabenseite, Bewertungsformular, Abnahme |
| 13:00 | 13:20 | 0:20 | Durchstich – dabei den 1-MB-Deckel gefunden und behoben |
| 13:20 | 13:35 | 0:15 | Fremdzugriff geprüft, Seiten auf 404 umgestellt, Screenshots, Dokumente |
**Summe Baustein 5: rund 1 h 40 min**
### Was aufgefallen ist
- **Der wichtigste Fund des Tages:** Next.js begrenzt Serveraktionen ab Werk auf
1 MB Rumpfgröße. Meine eigene Grenze von 25 MB war damit nie erreichbar –
jedes Handyfoto (2 bis 5 MB) wäre stillschweigend gescheitert, mit einem
Fehler nur im Serverprotokoll. Genau das Abnahmekriterium „eine Praxisaufgabe
mit Foto abgeben" hätte nicht funktioniert. Gefunden hat den Fehler nur der
Durchstich mit einer echten Datei, nicht die Testdatei mit 200 Byte.
Gegenprobe danach: 3,8-MB-Foto hochgeladen, kommt mit 3 987 781 Byte zurück.
- Die eigene Fehlerseite für „kein Zugriff" hat nicht funktioniert, weil
Next.js Fehlermeldungen im Produktionsbetrieb schwärzt – der Text kommt nie
im Browser an. Statt daran herumzubasteln liefern die Seiten jetzt 404. Das
ist ohnehin die bessere Antwort: Ob es die Daten gibt, geht einen Unbefugten
nichts an. Die Anhang-Route machte das von Anfang an so.
- Anhänge hängen an Aufgabe **und** Azubi. Beim ersten Entwurf hätte ein
zweiter Azubi die Fotos des ersten an derselben Aufgabe gesehen.
- Geprüft mit einem eigens angelegten zweiten Ausbilderkonto: fremder Anhang
404, eigener 200, der zuständige Ausbilder 200. Danach wieder gelöscht.
---
## 2026-09-10 · Baustein 4 – Merkkarten
| Von | Bis | Dauer | Tätigkeit |
|---|---|---|---|
| 11:00 | 11:20 | 0:20 | Wiederholungsverfahren: SM-2 auf drei Bewertungsstufen eingedampft, Fächer, Stapelauswahl |
| 11:20 | 11:35 | 0:15 | 29 Tests dazu – einer schlug an, der Test war falsch, nicht der Code (siehe unten) |
| 11:35 | 11:50 | 0:15 | Migration, Schema, Repository, Serveraktion für die Bewertung |
| 11:50 | 12:15 | 0:25 | Lernmodus: Karte, Umdrehen, Wischen, Tastatur; Kartenübersicht mit Fächern |
| 12:15 | 12:30 | 0:15 | Durchstich am Rechner und am Handy, zwei Mängel am Handy behoben |
| 12:30 | 12:40 | 0:10 | Karten in den Wochenfortschritt gehängt, Dokumente nachgezogen |
**Summe Baustein 4: rund 1 h 40 min**
### Was aufgefallen ist
- Ein Test schlug fehl: „gibt einen leeren Stapel zurück, wenn nichts fällig
ist". Der Code lieferte eine nie gelernte Karte zurück – und hatte recht.
Eine Karte ohne Fälligkeitsdatum muss immer fällig sein, sonst käme sie nie
dran. Ich habe die Erwartung korrigiert und den Fall in zwei Tests getrennt.
- „nochmal" muss die Karte **in derselben Sitzung** wiederbringen. Sie nur auf
morgen zu legen, wäre folgenlos gewesen – man drückt „nochmal" ja gerade,
weil man sie jetzt noch einmal sehen will.
- Am Handy legte der Browser beim Antippen eine blaue Fläche über die ganze
Lernkarte. `-webkit-tap-highlight-color: transparent` behebt das; ohne einen
Blick auf ein echtes Gerätemaß wäre es nie aufgefallen.
- Die Kopfzeile brauchte am Handy drei Zeilen und schob die Karte nach unten.
Jetzt: Marke und Bedienung in einer Zeile, Navigation darunter zum Schieben.
- Der Stapel wird bei 20 Karten gedeckelt. Ohne Deckel sitzt jemand nach drei
Wochen Pause vor 52 Karten und macht es gar nicht.
---
## 2026-09-10 · Baustein 3 – Wochenplan
| Von | Bis | Dauer | Tätigkeit |
|---|---|---|---|
| 09:05 | 09:20 | 0:15 | Datenmodell der Wochenplanung, Migration, Drizzle-Schema |
| 09:20 | 09:45 | 0:25 | Planungslogik als reine Funktionen: erzeugen, verschieben, umsortieren, „welche Woche ist dran", Überschneidungen; dazu die Fortschrittsrechnung |
| 09:45 | 09:55 | 0:10 | 36 Tests dafür – liefen beim ersten Anlauf durch |
| 09:55 | 10:10 | 0:15 | Repository-Schicht, Wochensicht aus Inhalt + Planung + Fortschritt |
| 10:10 | 10:35 | 0:25 | Wochenansicht, Startseiten für beide Rollen, Wocheneinzelansicht |
| 10:35 | 10:55 | 0:20 | Wochenplanseite: verlegen, umsortieren mit Ziehen und Tastatur, Zustand, Notizen |
| 10:55 | 11:10 | 0:15 | Durchstich im Browser, Screenshots, Dokumente nachgezogen |
**Summe Baustein 3: rund 2 h 05 min**
### Was aufgefallen ist
- Beim Umsortieren war die erste Idee, die Termine mitzuziehen. Falsch: Dann
entstehen Lücken und Überschneidungen. Richtig ist, die Folge der
Kalenderwochen als festen Rahmen zu behandeln und nur die Zuordnung zu
ändern – der Plan bleibt so immer lückenlos.
- Der Lint-Fehler „azubiId is defined but never used" im Verlegen-Formular war
kein Stilproblem, sondern ein echter Bug: Dem Formular fehlte das versteckte
Feld, das die Serveraktion ausliest. Ein Lauf hätte den Fehler zwar auch
gezeigt, aber erst nach dem Klick.
- Ziehen und Ablegen allein reicht nicht. Wer mit der Tastatur arbeitet, kommt
damit nicht weiter, deshalb tun es die Pfeilknöpfe und Alt + Pfeil genauso.
- Die Erfolgsmeldung nach „Wochen einplanen" ist nicht zu sehen, weil das
Formular danach verschwindet – die erscheinende Planliste ist die
Rückmeldung. Kein Fehler, aber es hat mich im Testskript zunächst gekostet.
---
## 2026-09-10 · Baustein 2 – Inhalte
| Von | Bis | Dauer | Tätigkeit |
|---|---|---|---|
| 07:05 | 07:15 | 0:10 | Remote eingetragen, Push scheitert an fehlenden Zugangsdaten – zurückgestellt, Arbeit läuft weiter |
| 07:15 | 07:25 | 0:10 | Ausbildungsrahmenplan und Lernfelder aus den Quellen geholt statt geraten (FIAusbV Anlage, KMK-Rahmenlehrplan) |
| 07:25 | 07:50 | 0:25 | Beispielinhalte geschrieben: 12 Handouts mit Merkkarten, 4 Wochenpläne, 4 Aufgaben, 4 Checklisten, 2 Lernzielkontrollen, 24 Glossareinträge |
| 07:50 | 08:20 | 0:30 | Inhaltslader: YAML-Dokumentmodell für Zeilennummern, Zod-Schemata, Fehlersammler, Querverweisprüfung |
| 08:20 | 08:35 | 0:15 | Handout-Ansicht, Übersicht nach Blöcken, Volltextsuche, Glossar mit automatischer Verlinkung |
| 08:35 | 08:50 | 0:15 | 39 neue Tests; zwei echte Fehler dabei gefunden (siehe unten) |
| 08:50 | 09:00 | 0:10 | Screenshot-Skript, Bilder aufgenommen, Fahrplan und Änderungsprotokoll nachgezogen |
**Summe Baustein 2: rund 1 h 55 min**
### Was aufgefallen ist
- Die Zeilennummer in der Fehlermeldung war den Aufwand wert. Beim ersten Lauf
gegen die echten Inhalte kam sofort `content/glossar.yaml:8 – Expected string,
received number`: `formen: [169.254]` hatte YAML als Gleitkommazahl gelesen.
Ohne Zeilenangabe hätte ich das in 24 Einträgen gesucht.
- `gray-matter` liefert beim zweiten Einlesen desselben Textes ein Objekt ohne
das Feld `matter` – im Betrieb fällt das nie auf, im Test sofort. Den YAML-Kopf
selbst herauszulösen ist zehn Zeilen Arbeit und beseitigt gleich zwei Probleme.
- Zod-Schemata mit `.default()` haben verschiedene Ein- und Ausgabetypen. Mit
`z.ZodType<T>` erzwingt TypeScript Gleichheit und leitet den falschen Typ ab;
`<S extends z.ZodTypeAny>` mit `z.output<S>` ist die richtige Form.
- Der Auftrag nennt für den Rahmenplan `C1` bis `C4`. Die Verordnung führt in
Abschnitt F aber **fünf** integrativ zu vermittelnde Positionen. Ich habe alle
fünf aufgenommen – sonst fehlt in der Abdeckung ausgerechnet die Position, die
2020 neu dazugekommen ist („Vernetztes Zusammenarbeiten unter Nutzung digitaler
Medien"). Siehe ENTSCHEIDUNGEN.md, E10.
---
## 2026-09-10 · Baustein 1 – Fundament
| Von | Bis | Dauer | Tätigkeit |
|---|---|---|---|
| 00:15 | 00:20 | 0:05 | Auftrag gesichtet, fehlende Stackvorgabe geklärt (Next.js 15 + React 19 + TypeScript), Repository angelegt |
| 00:20 | 00:28 | 0:08 | Abhängigkeiten installiert; `better-sqlite3` auf v12 gehoben, weil es für Node 24 sonst keine fertige Binärdatei gibt und der Bau über Visual Studio scheiterte |
| 00:28 | 00:40 | 0:12 | Datenbankschicht: Drizzle-Schema, eigener Migrationslauf mit Prüfsummen, Verbindung als Prozess-Singleton |
| 00:40 | 00:52 | 0:12 | Zeitrechnung (Europe/Berlin, ISO-Kalenderwochen), Argon2id, serverseitige Sitzungen, Rechteregeln als reine Funktionen |
| 00:52 | 01:10 | 0:18 | Gestaltung: Farbwelt Petrol/Bernstein, helle und dunkle Darstellung, Bedienelemente, Druckansicht |
| 01:10 | 01:25 | 0:15 | Anmeldung, Rahmenlayout, Startseite, Verwaltung (Konto und Ausbildung anlegen, Passwort, Sperren) |
| 01:25 | 01:32 | 0:07 | Erstes Ausbilderkonto über Skript angelegt, Typprüfung und Bau grün, Server geprüft |
| 01:32 | 01:50 | 0:18 | Dockerfile, docker-compose, Lebenszeichen, `update.sh` mit Rückfall, Sicherung und Wiederherstellung |
| 01:50 | 02:05 | 0:15 | Fahrplan, Änderungsprotokoll, Arbeitstagebuch, Entscheidungen, README |
**Summe Baustein 1: rund 1 h 50 min**
### Was aufgefallen ist
- Der Auftrag verweist zweimal auf einen „Kopf des Prompts" (Stack, Anmeldung),
der nicht mitgeliefert wurde. Die Anmeldung war aus den technischen Vorgaben
ableitbar, der Stack nicht – dafür gab es eine Rückfrage.
- `npm` blockiert seit Version 11 Installationsskripte fremder Pakete.
`better-sqlite3`, `esbuild` und `unrs-resolver` mussten einmalig über
`npm approve-scripts` freigegeben werden. Das gehört in die README, sonst
läuft ein Fremder in genau diese Wand.
- Windows und LF: ohne `.gitattributes` hätte Git die Shell-Skripte mit CRLF
ausgecheckt, und der Linux-Container hätte sie nicht mehr gestartet.
---
<!-- Neue Bausteine werden oben angefügt, damit der aktuelle Stand zuerst steht. -->