Files
schalli 6de5eb4f07
Tessera CI/CD / Lint & Type Check (push) Successful in 55s
Tessera CI/CD / Tests (push) Successful in 1m11s
Tessera CI/CD / Desktop-Pakete bauen (push) Failing after 11m56s
Tessera CI/CD / Build & Publish Images (push) Has been skipped
docs(quick-260921-a1d): Benutzerverwaltung meldet abgewiesene Aktionen (WINDOWS #36)
Zusammenfassung und Verifikation zum Quick-Vorgang 260921-a1d,
Registereintrag #36 geschlossen, STATE.md nachgezogen.

Nachgewiesen: alle drei zuvor stillen Stellen (Liste laden, Formular
speichern, Loeschen) zeigen den Servertext oder eine uebersetzte
Ersatzmeldung; fuer einen ADMIN entfallen Bearbeiten und Loeschen in der
SUPER_ADMIN-Zeile. apps/api blieb unangetastet — der Zielrollen-Riegel
im Controller bleibt die wirksame Grenze. Web-Tests 66 Dateien / 459
Tests gruen (vorher 65/447), type-check Exit 0, pnpm lint 5/5.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J
2026-09-21 07:41:19 +02:00

9.1 KiB

phase, plan, subsystem, tags, requires, provides, affects, actuals, tech-stack, key-files, key-decisions, requirements-completed, coverage, duration, completed, status
phase plan subsystem tags requires provides affects actuals tech-stack key-files key-decisions requirements-completed coverage duration completed status
quick-260921-a1d 01 ui
next-intl
react
vitest
error-handling
rbac
phase provides
quick-260914-ebg Zielrollen-Riegel in apps/api/src/user/user.controller.ts (update/remove), der SUPER_ADMIN-Zeilen fuer Nicht-SUPER_ADMIN mit 403 abweist (WINDOWS #29)
Sichtbare Fehlermeldungen (Servertext oder Ersatzmeldung) im Loeschdialog, im Formulardialog und im Listenkopf der Benutzerverwaltung
canManageRow spiegelt den Zielrollen-Riegel client-seitig — ADMIN sieht in der SUPER_ADMIN-Zeile keine Aktionsknoepfe mehr
readApiMessage-Muster fuer den Antwortrumpf, lokal zu apps/web/src/app/(portal)/admin/users/page.tsx
admin-users-page
benutzerverwaltung
error-handling-conventions
tokens tasks commits
7650 3 3
added patterns
readApiMessage(res) liest ausschliesslich res.json().message (String oder String[]), nie res.text() — verhindert, dass eine fremde HTML-Fehlerseite (vorgelagerter Proxy) in die Oberflaeche geraet
Drei-Zustaende-Fehlermuster pro Formular/Dialog: serverRejected (mit Detail) / generic (kein Rumpf) / network (Verbindung gescheitert), alle als role="alert"-Banner mit denselben Klassen wie admin/groups/page.tsx
canManageRow spiegelt eine Server-Autorisierungsbedingung rein als UI-Ergonomie — Kommentar verweist explizit auf die Serverstelle, die die eigentliche Grenze zieht
created modified
apps/web/src/app/(portal)/admin/users/users-page.test.tsx
apps/web/src/app/(portal)/admin/users/page.tsx
apps/web/src/messages/de.json
apps/web/src/messages/en.json
D-01 bis D-06 aus dem Plan unveraendert umgesetzt: next-intl in beiden Katalogen, Sie-Form, Servertext hat Vorrang vor Ersatzmeldung, apps/api unangetastet, vorhandene Muster (groups/page.tsx Banner, tender-radar-api.ts Rumpf-Auswertung) wiederverwendet, keine Umformatierung
Servertexte bleiben englisch (D-03/Ausgangslage) — Uebersetzung waere eine apps/api-Aenderung und damit ausserhalb dieses Plans; siehe T-A1D-04 im Plan
WINDOWS-36
id description requirement verification human_judgment
D1 Ein mit 403 abgewiesener Loeschvorgang zeigt den Servertext im offenen Loeschdialog; Ersatzmeldungen fuer verwertbaren-losen Rumpf und Verbindungsfehler; Erfolgsfall unveraendert WINDOWS-36
kind ref status
unit apps/web/src/app/(portal)/admin/users/users-page.test.tsx#AdminUsersPage — Loeschweg (WINDOWS #36, Aufgabe 1) (4 Tests) pass
false
id description requirement verification human_judgment
D2 Abgewiesenes Speichern zeigt den Servertext (inkl. verketteter Pruefmeldungen) im offenen Formular; Netzmeldung bei Verbindungsfehler; gescheitertes Laden meldet sich im Listenkopf statt faelschlich 'Keine Benutzer gefunden' zu zeigen; Meldungen ueberdauern kein Dialog-Schliessen WINDOWS-36
kind ref status
unit apps/web/src/app/(portal)/admin/users/users-page.test.tsx#AdminUsersPage — Formularweg und Listenladen (WINDOWS #36, Aufgabe 2) (5 Tests) pass
false
id description requirement verification human_judgment
D3 Ein ADMIN bekommt in der SUPER_ADMIN-Zeile weder Bearbeiten noch Loeschen angeboten (Details bleibt); ein SUPER_ADMIN bekommt beide; Selbstloeschungssperre unveraendert WINDOWS-36
kind ref status
unit apps/web/src/app/(portal)/admin/users/users-page.test.tsx#AdminUsersPage — Aktionsknoepfe der SUPER_ADMIN-Zeile (WINDOWS #36, Aufgabe 3) (3 Tests) pass
false
14min 2026-09-21 complete

Quick 260921-a1d: Stille 403-Antworten in der Benutzerverwaltung Summary

Loesch-, Formular- und Ladeweg der Benutzerverwaltung melden abgewiesene Serverantworten jetzt sichtbar (Servertext oder uebersetzte Ersatzmeldung); ein ADMIN bekommt an der SUPER_ADMIN-Zeile keine Aktionsknoepfe mehr angeboten.

Performance

  • Duration: 14 min
  • Started: 2026-09-21T07:19:00+02:00 (gemessen: erster Lesevorgang)
  • Completed: 2026-09-21T07:33:48+02:00 (letzter Task-Commit)
  • Tasks: 3/3
  • Files modified: 4 (1 neu, 3 geaendert)

Gemessene Testzahlen

  • Vorher (Ausgangsmessung im Plan, 2026-09-21): 65 Dateien, 447 Tests, alle gruen.
  • Nachher (dieser Lauf, pnpm --filter @tessera/web test): 66 Dateien, 459 Tests, alle gruen. Die neue Datei users-page.test.tsx traegt 20 Tests (4 aus Aufgabe 1, 5 aus Aufgabe 2, 3 aus Aufgabe 3 — plus die schon vorher zu admin/users zaehlende user-access-modal.test.tsx mit 8 Tests, macht 12 in der Datei admin/users-Glob-Messung von Aufgabe 1/2/3).

Accomplishments

  • readApiMessage(res) liest gezielt body.message (String oder verkettetes String-Feld) aus einer Nicht-2xx-Antwort und gibt sonst null zurueck — niemals den ganzen Rumpf.
  • Drei bisher stumme Fehlerwege melden sich jetzt sichtbar: handleDelete (Loeschdialog), handleSubmit (Formulardialog), fetchUsers (Listenkopf). Jeder Zweig endet in einer Meldung: Servertext (errors.serverRejected), Ersatzmeldung ohne Rumpf (errors.generic), Verbindungsfehler (errors.network) oder Ladefehler (errors.loadFailed).
  • Bei gescheitertem Laden erscheint nicht mehr faelschlich "Keine Benutzer gefunden" — die Tabelle bleibt einfach weg, das Banner sagt, was wirklich passiert ist.
  • canManageRow(user) spiegelt exakt die serverseitige Bedingung (user.role === 'SUPER_ADMIN' && currentUser?.role !== 'SUPER_ADMIN') aus apps/api/src/user/user.controller.ts (update/remove) und blendet Bearbeiten/Loeschen in der SUPER_ADMIN-Zeile fuer jeden Nicht-SUPER_ADMIN komplett aus — nicht nur gesperrt, sondern nicht vorhanden.
  • Vier neue Schluessel unter admin.users.errors in de.json und en.json, identischer Schluesselsatz, Umlaut-Waechter gruen.

Task Commits

Jede Aufgabe wurde atomar committet:

  1. Aufgabe 1: Loeschweg von der Serverantwort bis zur sichtbaren Meldung - 38d2586 (fix)
  2. Aufgabe 2: Formularweg und Listenladen auf dieselbe Rueckmeldung heben - 51bff75 (fix)
  3. Aufgabe 3: Aktionsknoepfe der SUPER_ADMIN-Zeile einem ADMIN nicht anbieten, Gesamtlauf - 13b70df (fix)

Plan-Basis: 24f51e9 (Plan bereits committet vor Ausfuehrung)

Files Created/Modified

  • apps/web/src/app/(portal)/admin/users/page.tsx - readApiMessage, drei neue Fehlerzustaende (deleteError, formError, loadError), drei role="alert"-Banner, canManageRow fuer die Sichtbarkeit der Aktionsknoepfe.
  • apps/web/src/app/(portal)/admin/users/users-page.test.tsx - neu, 20 Tests fuer alle drei Aufgaben.
  • apps/web/src/messages/de.json / en.json - Zweig admin.users.errors mit vier Schluesseln je Sprache.

Decisions Made

  • Servertexte bleiben englisch und werden ungeaendert im deutschen Rahmensatz angezeigt (D-03 aus dem Plan) — eine Uebersetzung waere eine apps/api-Aenderung und damit ausserhalb dieses Plans. Als Beobachtung im Plan unter T-A1D-04 vermerkt, hier nicht behandelt.
  • readApiMessage ist bewusst lokal in page.tsx kopiert statt aus apps/web/src/lib/tender-radar-api.ts importiert — jene Datei gehoert zum Modul Ausschreibungs-Radar, die Verwaltungsseite soll nicht davon abhaengen (Formvorlage extractErrorMessage, D-05).
  • fetchUsers (dritte Fundstelle, urspruenglich nicht Teil der Fehlermeldung) wurde bewusst mitbehandelt, wie der Plan es verlangt — nichts wurde aus Bequemlichkeit ausgelassen.

Deviations from Plan

None - plan executed exactly as written.

Issues Encountered

None.

User Setup Required

None - keine externe Dienstkonfiguration erforderlich.

Verifikation (aus der <verification>-Sektion des Plans)

  1. pnpm --filter @tessera/web test → 66 Testdateien, 459 Tests, 0 Fehler (Ausgangslage: 65/447).
  2. pnpm --filter @tessera/web type-check → Exit 0.
  3. pnpm lint → 5 von 5 Workspaces erfolgreich (287 bestehende Warnungen, 0 neue Fehlerrang-Meldungen).
  4. git status --porcelain → ausschliesslich Pfade unter apps/web/src/, kein Pfad unter apps/api/.

Von Hand vorgesehene Sichtproben (Sichtprobe a: SUPER_ADMIN-Zeile zeigt nur "Details" fuer einen ADMIN; Sichtprobe b: Platzierung des roten Banners) wurden nicht durchgefuehrt — der Plan bezeichnet sie ausdruecklich als optional, da die automatisierten Tests dasselbe Verhalten bereits abdecken.

Next Phase Readiness

  • WINDOWS #36 ist inhaltlich geschlossen — dieser Lauf schliesst den beschriebenen Fehler vollstaendig (alle drei stillen Wege sowie die Sichtbarkeit der Aktionsknoepfe). Die Ledger-Eintragung selbst (gsd-tools windows fixed 36) erfolgt durch den Orchestrator, nicht durch diesen Ausfuehrungslauf.
  • WINDOWS #28 und #32 derselben Fehlerfamilie bleiben ausdruecklich offen — nicht Teil dieses Plans.
  • Keine Blocker fuer nachfolgende Arbeit an der Benutzerverwaltung.

Phase: quick-260921-a1d Completed: 2026-09-21

Self-Check: PASSED

Alle vier veraenderten Dateien und die neue Testdatei existieren auf der Platte; alle drei Task-Commits (38d2586, 51bff75, 13b70df) sind in der Git-Historie auffindbar.