Files
lernbar/ENTSCHEIDUNGEN.md
T
Florian WildeandClaude Opus 5 bb592ad2bd Baustein 4: Merkkarten mit Wiederholung nach Zeitabstand
- Abgespecktes SM-2 mit drei Bewertungsstufen statt sechs
- Abstaende 1, 3, dann Abstand mal Leichtigkeit; gedeckelt bei 180 Tagen
- "nochmal" bringt die Karte in derselben Sitzung wieder
- Taeglicher Stapel, gedeckelt auf 20 Karten, ueberfaellige zuerst
- Fuenf Faecher zur Anzeige, abgeleitet aus dem Abstand
- Filter nach Themenblock fuer gezieltes Ueben
- Lernmodus fuers Handy: grosse Flaechen, Antippen, Wischen, kein Hover;
  am Rechner zusaetzlich Leertaste und Tasten 1/2/3
- Tabellen karte und karten_verlauf, jede Bewertung wird mitgeschrieben
- Merkkarten zaehlen im Wochenfortschritt mit, gelernt ab Fach 4
- Kopfzeile am Handy einzeilig, Tipp-Hervorhebung abgeschaltet
- 29 neue Tests, insgesamt 133

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 11:16:40 +02:00

167 lines
7.5 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.
# Entscheidungen
Kurze Notizen zu Festlegungen, die im Auftrag offen waren. Jede Notiz nennt
die Lage, die Wahl und den Grund.
---
## E1 · Stack: Next.js 15 mit App Router
Der Auftrag verweist auf eine Stackvorgabe im „Kopf des Prompts", die nicht
mitgeliefert wurde. Auf Rückfrage: **Next.js 15 (App Router), React 19,
TypeScript**. Datenzugriff über Drizzle ORM auf better-sqlite3.
Serveraktionen ersetzen eine eigene REST-Schicht. Das hält die Rechteprüfung
dort, wo die Daten geholt werden, statt sie über eine API zu verteilen.
## E2 · Zeitstempel als ISO-8601 in UTC
Der Auftrag verlangt „alle Zeitstempel mit Zeitzone". Gespeichert wird
`2026-09-10T07:15:00.000Z`, also ein eindeutiger Zeitpunkt in UTC. Angezeigt
wird durchgehend in Europe/Berlin.
Grund: UTC-Strings sortieren sich lexikografisch richtig, was bei SQLite ohne
echten Zeitstempeltyp entscheidend ist. Ein gespeicherter Ortsversatz
(`+02:00`) würde beim Wechsel zwischen Sommer- und Winterzeit falsch sortieren.
Reine Kalenderdaten – Berichtszeitraum, Tagesnotiz, Ausbildungsbeginn – sind
`YYYY-MM-DD` ohne Uhrzeit, weil sie auch keine haben.
## E3 · Eigener Migrationslauf statt drizzle-kit
Migrationen sind handgeschriebene SQL-Dateien unter
`src/lib/db/migrationen/`, die beim Start der Reihe nach genau einmal
angewendet und mit SHA-256-Prüfsumme vermerkt werden.
Grund: volle Kontrolle über Indizes und `CHECK`-Bedingungen (Statuswerte sind
Aufzählungen, keine freien Zeichenketten), und beim Start ist im Protokoll
sichtbar, was passiert ist. Wird eine bereits angewendete Datei nachträglich
verändert, bricht der Start mit klarer Meldung ab.
Der Preis: das Drizzle-Schema muss von Hand zu den SQL-Dateien passen. Dagegen
läuft ein Test, der die migrierte Datenbank gegen das Schema abgleicht.
## E4 · Schlüssel sind UUIDs, keine laufenden Nummern
Textspalten mit `crypto.randomUUID()`. Läuft auf SQLite und PostgreSQL
gleichermaßen, und beim Zurückspielen einer Sicherung gibt es keine Kollisionen
mit zwischenzeitlich vergebenen Nummern.
## E5 · Debian-slim als Grundlage des Abbilds, nicht Alpine
`better-sqlite3` und `@node-rs/argon2` bringen für glibc fertige Binärdateien
mit, für musl nicht. Auf Alpine müsste im Abbild übersetzt werden – längerer
Bau, größere Bauschicht, mehr Fehlerquellen. Der Größenunterschied im
Laufzeitabbild ist bei einem selbst gehosteten Dienst ohne Belang.
## E6 · Passwortprüfung mit gleichbleibender Antwortzeit
Bei unbekannter E-Mail-Adresse wird trotzdem einmal gegen einen festen
Argon2-Wert gerechnet. Sonst verrät die Antwortzeit, welche Adressen es gibt.
Die Fehlermeldung ist in beiden Fällen dieselbe.
## E7 · Anhänge liegen im Dateisystem, nicht in der Datenbank
Unter `<daten>/anhaenge/`, in der Datenbank steht nur der Verweis. Hält die
Datenbankdatei klein und die Sicherung schnell; das Archiv nimmt beides mit.
## E8 · Sicherung als Shell-Skript, nicht als Node-Werkzeug
`scripts/im-container/sicherung.sh` läuft im Laufzeitabbild, das kein
TypeScript kennt, und auf dem Entwicklungsrechner unter Git Bash. Eine zweite
Fassung in TypeScript wäre eine zweite Fehlerquelle. Die konsistente Kopie der
Datenbank entsteht über die Sicherungsschnittstelle von SQLite – ein `cp` wäre
bei aktivem WAL-Modus nicht verlässlich.
## E9 · Kein `main`-Zweig ohne Freigabe
Die verbindliche Arbeitsweise verbietet Commits direkt auf `main`. Die
Erstfassung entsteht deshalb vollständig auf `feat/lernbar-erstfassung`.
`main` bleibt leer, bis eine Freigabe erfolgt.
---
<!-- Weitere Entscheidungen werden unten angefügt und fortlaufend nummeriert. -->
## E10 · Rahmenplan: A1–A10, B1–B3, C1–**C5**
Der Auftrag nennt die Berufsbildpositionen `A 1 bis A 10`, `B 1 bis B 3` und
`C 1 bis C 4`. Die Verordnung selbst gliedert anders: Sie deckt alle vier
Fachrichtungen ab und hat deshalb sechs Abschnitte. Übersetzt:
| Kürzel hier | Abschnitt der FIAusbV | Inhalt |
|---|---|---|
| A1 – A10 | Abschnitt A | fachrichtungsübergreifend |
| B1 – B3 | Abschnitt C | Fachrichtung Systemintegration |
| C1 – C5 | Abschnitt F | integrativ zu vermitteln |
Abweichung: Abschnitt F hat **fünf** Positionen, nicht vier. Die fünfte
(„Vernetztes Zusammenarbeiten unter Nutzung digitaler Medien") ist 2020 neu
dazugekommen. Sie wegzulassen würde ausgerechnet in der Abdeckungsansicht eine
Lücke erzeugen, die gegenüber der IHK zählt. Deshalb sind alle fünf drin.
Jede Position trägt im Feld `verordnung` ihre amtliche Fundstelle, damit die
Übersetzung nachvollziehbar bleibt.
## E11 · Kennung einer Merkkarte: Handout-Kürzel plus laufende Nummer
Eine Karte heißt `N3-1`, `N3-2` und so weiter – abgeleitet aus dem Handout und
der Reihenfolge im YAML-Kopf. Damit steht die Kennung fest, ohne dass sie in der
Datei gepflegt werden muss.
Der Preis: Wird eine Karte **mittendrin** eingefügt oder gelöscht, verschieben
sich die Kennungen der folgenden, und ihr Lernstand rutscht mit. Neue Karten
gehören deshalb ans Ende der Liste. Bei einem Handout mit ein bis drei Karten
ist das zumutbar; eine gepflegte Kennung je Karte wäre mehr Aufwand für die
Person, die Inhalte schreibt, als sie einbringt.
## E12 · Glossarverweise: Link statt Überfahren
Der Auftrag lässt die Wahl zwischen automatischer Verlinkung und einer
Erklärung beim Überfahren mit der Maus. Es wird beides, aber der Link führt:
Ein reiner `title`-Hinweis ist am Handy nicht erreichbar und mit der Tastatur
nur mit Mühe. Der Verweis zeigt auf die Stelle im Glossar und trägt die
Erklärung zusätzlich im `title`.
Zurückhaltung ist eingebaut: Jeder Begriff wird höchstens einmal je Seite
verlinkt, und nie innerhalb von Code, Überschriften, Tabellenköpfen oder
bestehenden Verweisen. Ein Text, in dem jedes zweite Wort unterstrichen ist,
liest sich schlechter als einer ganz ohne.
## E13 · Kein `gray-matter`
Der YAML-Kopf einer Markdown-Datei wird selbst herausgelöst (zehn Zeilen).
Gründe: `gray-matter` merkt sich Ergebnisse und liefert beim zweiten Einlesen
desselben Textes ein Objekt ohne das Feld `matter` – im Betrieb fällt das nie
auf, im Test sofort. Und der Zeilenversatz für die Fehlermeldungen ist so
nachweislich richtig statt nachgebaut.
## E14 · SM-2 mit drei Bewertungsstufen statt sechs
Das Original arbeitet mit einer Skala von 0 bis 5. In der Praxis unterscheidet
niemand ehrlich zwischen „fast richtig" und „mit Mühe richtig" – und eine
Selbstbewertung, die man nicht ehrlich abgeben kann, verfälscht die Rechnung.
Deshalb: **sitzt** / **unsicher** / **nochmal**. Die Leichtigkeit bewegt sich
weiterhin zwischen 1,3 und 2,8, die Abstände folgen 1, 3, dann Abstand mal
Leichtigkeit. Gedeckelt wird bei 180 Tagen – die Ausbildung dauert drei Jahre,
weiter zu planen bringt nichts.
## E15 · „nochmal" bringt die Karte in derselben Sitzung wieder
Erste Fassung legte sie nur auf den nächsten Tag. Das ist falsch: Wer „nochmal"
drückt, will die Karte *jetzt* noch einmal sehen. Sie wird deshalb hinten an den
laufenden Stapel gehängt.
## E16 · Der tägliche Stapel wird bei 20 Karten gedeckelt
Ohne Deckel sitzt jemand nach drei Wochen Pause vor 52 fälligen Karten und
macht es gar nicht. Sortiert wird nach Überfälligkeit; nie gelernte Karten
kommen zuletzt, damit zuerst der Rückstand abgebaut wird.
## E17 · Als „gelernt" gilt eine Karte ab Fach 4
Fach 4 heißt: Abstand über drei Tage, also mindestens dreimal in Folge gekonnt.
Das ist die Schwelle, ab der die Karte im Wochenfortschritt als erledigt zählt.
Wer sie einmal richtig hatte, hat sie noch nicht gelernt.