# #015 M10 – Dashboard und Archiv **Status:** erledigt **Meilenstein:** v0.1.0 **Labels:** phase-1, frontend, backend **Geschätzt:** 8 h **Tatsächlich:** 2 h 20 min ## Ziel Der Einstieg am Schreibtisch und das Gedächtnis der Anwendung. ## Aufgaben - [x] Dashboard: meine offenen Läufe, überfällige Läufe, zuletzt bearbeitet, Schnellstart der häufigsten Vorlagen - [x] Archiv-Volltextsuche über Titel, Notizen, Werte und Kommentare in einem gemeinsamen Query-Modul mit `pg_trgm` und `ILIKE` - [x] Filter nach Vorlage, Mitarbeiter, Abteilung, Gerät, Zeitraum und Bearbeiter; im Modus `DIENSTLEISTUNG` zusätzlich nach Kunde - [x] Druckansicht eines Laufs: Print-CSS, Kopfdaten, alle Abschnitte und Schritte, Werte, Notizen, Namen, Zeitstempel; ersetzt im MVP den PDF-Export - [x] In der Druckansicht erscheinen vom Mitarbeiter nur Name, UPN und Abteilung, sonst nichts - [x] Screenshots Übersicht, Archiv, Druckansicht in `docs/screenshots/m10/` ## Akzeptanzkriterien - [x] Test: ein archivierter Lauf wird über ein Wort aus einer Schritt-Notiz gefunden - [x] Test: ein archivierter Lauf wird über ein Wort aus einem Kommentar gefunden - [x] Test: die Filter kombinieren sich (Vorlage und Zeitraum und Bearbeiter) - [x] Test: `{{generiertes_passwort}}` erscheint nicht in der Druckansicht - [x] Test: überfällige Läufe sind genau die mit `faelligAm < heute` und Status `OFFEN` oder `IN_ARBEIT` - [x] Die Druckansicht ist hell, ohne Navigation, und passt auf A4 ## Ergebnis Erledigt am 2026-09-25. **980 Tests** (vorher 930) und **67 Ende-zu-Ende-Tests** grün, Screenshots in `docs/screenshots/m10/`. Drei Teile entstanden parallel: Archiv, Druckansicht und Übersicht. Eine Entscheidung des Archiv-Teils ist nicht offensichtlich und darum hier festgehalten: **auch `ABGESCHLOSSEN` gehört ins Archiv.** „Abgeschlossen ist nicht archiviert" (architektur.md §4) betrifft den Schreibschutz, nicht das Suchen — wer die Seriennummer von letzter Woche sucht, weiß nicht, ob schon jemand archiviert hat. ### Der unabhängige Review Zwei Blocker, fünf Befunde, neun Anmerkungen — beide Blocker steckten im Dashboard, also in meinem eigenen Teil: - **„Überfällig" traf auch, was heute fällig ist.** Verglichen wurde mit dem Augenblick statt mit dem Tagesbeginn; ein Datumsfeld speichert Mitternacht UTC, und damit stand ein heute fälliger Lauf hierzulande ab zwei Uhr morgens in Warnfarbe — an genau dem Tag, an dem er erledigt werden soll. Die Regel steht jetzt als `fristVerstrichen()` in `src/lib/fristen.ts`, Lesemodell und Anzeige benutzen dieselbe, und ein Test prüft die Grenze selbst. Der alte Test kannte nur „gestern" und „morgen". - **Der Schnellstart zählte Läufe fremder Kunden mit.** Eine Vorlage ohne Kundenbezug gilt für alle (#009); ihr Zähler sammelte die Läufe sämtlicher Kunden, und „4× gestartet" war damit eine Auskunft über fremde Betriebe — dazu eine, die die Reihenfolge nach fremder Arbeit sortierte. Dazu die Befunde: der E2E-Test „trägt kein Passwort" lief gegen eine Vorlage **ohne** Passwortschritt und konnte gar nicht scheitern; der Trigramm-Index auf `Lauf.titel` war strukturell unerreichbar, weil der Titeltreffer aus der materialisierten CTE las; `pflichtangaben` wurde berechnet, dokumentiert und nie benutzt; „N weitere in der Liste" führte bei Überfälligen in die ungefilterte Liste; und die Zusage „kein `{{generiertes_passwort}}` im Druck" galt nur für Vorlagentexte — wörtlich in eine Notiz geschriebene Zeichenfolgen gibt der Beleg wieder, wie es ein Beleg tun muss.