# #037 Zwei Nachzügler aus der Durchsicht von Phase 2 **Status:** erledigt **Im Tracker:** – **Meilenstein:** v0.2.0 **Labels:** phase-2, backend, test **Geschätzt:** 2 h **Tatsächlich:** 1 h 50 min ## Ziel Zwei Befunde aus [#036](036-reviewbefunde-phase-2.md), die mehr sind als eine Korrektur: beide verlangen einen Umbau, und beide sind heute kein Schaden, sondern eine offene Flanke. ## 1. `anhaengeDesLaufs` ist ein Lesemodell am falschen Ort `anhaengeDesLaufs(laufId)` liegt in `src/server/services/anhaenge.ts`, nimmt nur eine Lauf-Kennung und wendet **weder Rollen- noch Mandantensicht** an. Beide Aufrufer (`src/app/(app)/laeufe/[id]/page.tsx` und `src/server/queries/druck.ts`) prüfen den Lauf vorher, und die Kommentare sagen das auch — es ist also heute kein Fehler. Es steht aber gegen die Regel aus `CLAUDE.md` und `docs/architektur.md` §2: Lesemodelle liegen in `queries/*` und **wenden ihre Sicht selbst an, damit kein Aufrufer sie vergessen kann**. Zwei Aufrufer in zwei Schichten gibt es schon; der dritte ist der, der es vergisst — und er wird nicht auffallen, weil die zwei bestehenden korrekt sind. - [x] Nach `src/server/queries/anhaenge.ts` ziehen, mit `HandelnderBenutzer` als Parameter - [x] Mandanten- und Rollensicht dort anwenden, nicht beim Aufrufer - [x] Test: ein Benutzer, der auf andere Kunden beschränkt ist, bekommt eine leere Liste — **ohne** dass der Aufrufer vorher geprüft hat - [x] Gegenprobe: die Sicht entfernen, der Test muss rot werden ## 2. `/meine-geraete` fehlt in der 390-px-Prüfung Die Seite ist das Ergebnis von #035 und ausdrücklich mit „am Handy kein horizontales Scrollen“ abgenommen — von Hand. In `tests/e2e/mobil.spec.ts` steht sie nicht, und sie kann dort nicht einfach ergänzt werden: sie verlangt das Recht `selbstauskunft`, und das hat nur `MITARBEITER`. Der Ablauf meldet sich als Admin an und würde die Verweigerungsseite messen — die scrollt garantiert nicht. - [x] Ein `MITARBEITER`-Konto für die Abläufe: lokales Passwort, verknüpft mit einer `Mitarbeiter`-Zeile (der CHECK `Benutzer_mitarbeiter_nur_bei_rolle` verlangt die Verknüpfung) - [x] Im Seed oder im E2E-Vorlauf? **Im Vorlauf**, denn ein Konto mit bekanntem Passwort gehört nicht in einen Seed, der auch produktiv läuft - [x] `/meine-geraete` in die Seitenliste von `mobil.spec.ts` - [x] Dabei prüfen, was ein `MITARBEITER` auf den **anderen** Seiten sieht: die Rollenmatrix ist in Vitest vollständig, aber kein Ablauf klickt sie durch ## Akzeptanzkriterien - [x] `anhaengeDesLaufs` liegt in `queries/`, und ein Test belegt die Sicht ohne Vorprüfung des Aufrufers - [x] `/meine-geraete` wird bei 390 px gemessen, mit einem echten `MITARBEITER` - [x] Beide Gegenproben werden rot ## Beim Umsetzen dazugekommen - **Das Konto liegt im E2E-Vorlauf, nicht im Seed** — wie im Issue vorgezeichnet, und der Grund hat sich beim Schreiben bestätigt: ein Konto mit bekanntem Passwort gehört nicht in einen Seed, der auch produktiv läuft. Es trägt `ZZ` im Namen und fällt damit unter das Aufräumen aus [#027](027-e2e-reste-vorlagen.md); der Nachlauf meldet es mit („1 Benutzer“). - **Die Person wird gewählt, nicht gesetzt:** die erste aktive mit mindestens einem Gerät. Eine feste Kennung wäre eine Annahme über den Seed, und ohne Gerät zeigte die Seite nur ihren Leerzustand — der Test hätte dann nichts gemessen. Der Vorlauf bricht mit einer Erklärung ab, wenn es keine solche Person gibt. - **Ein zweiter Test dazu, den das Issue nicht verlangte:** dass ein `MITARBEITER` auf `/meine-geraete` **keinen** Link in die Verwaltung angeboten bekommt. Die Rollenmatrix ist in Vitest vollständig, und seit #035 nennt jeder Navigationseintrag sein Recht — dass das im **gerenderten** DOM ankommt, prüfte nichts. Gegenprobe: ein Eintrag ohne `recht`, und der Test wird rot. ## Was dabei schiefging, und warum es hier steht Für das zweite Konto brauchte `anmelden` eine Variante, die nicht auf `/` wartet — ein `MITARBEITER` landet auf `/meine-geraete`, weil `startseite(rolle)` das Ziel an der Rolle entscheidet (#035). Dabei habe ich das Warten für **alle** gelockert: „irgendeine Adresse außer `/anmelden`“. Das sah harmlos aus und machte **zwei unverwandte Abläufe** unzuverlässig — und zwar nur im vollen Durchgang, nicht beim Einzellauf: der nächste Schritt begann, bevor die Übersicht stand. Einer davon war `laeufe.spec.ts` („verlangt für nicht zutreffend eine Begründung“), der mit dem Thema nichts zu tun hat. Behoben: `anmelden` wartet wieder streng auf `/`, `anmeldenMit` nimmt das Ziel als Parameter, und beide warten zusätzlich auf `load` — ein `waitForURL` endet an der Adresse, nicht am geladenen Dokument. **Die Lehre:** ein gemeinsamer Helfer in einer Testsuite ist geteilter Zustand. Ihn für einen neuen Fall aufzuweichen kostet die Zuverlässigkeit aller alten, und das zeigt sich erst im vollen Lauf.