diff --git a/.planning/STATE.md b/.planning/STATE.md index 6065e6b..6b8f1ac 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -5,10 +5,10 @@ milestone_name: Ausschreibungs-Radar current_phase: 17 current_phase_name: eigene-ausschreibungs-quellen-je-nutzer status: verified -stopped_at: "Phase 17 verifiziert und abgeschlossen: die drei offenen Browser-Gegenproben (WINDOWS.md #7/#8/#9) wurden am 2026-09-07 im echten Browser nachgeholt und bestanden. Verifikationsbericht steht auf passed, Roadmap auf Complete. Naechster Schritt: /gsd-ship." -last_updated: "2026-09-07T07:56:00.000Z" +stopped_at: "Phase 17 auf passed. Zusaetzlich die alten Browser-Gegenproben nachgeholt: WINDOWS #1, #2, #5 geschlossen, #3 durchgefuehrt. Dabei ein Defekt gefunden und als #10 erfasst — der Zugriffs-Guard greift nicht auf den modul-eigenen Routen (PERM-04 unvollstaendig). Offen bleiben #4 und #6 (brauchen echtes AD) sowie #10." +last_updated: "2026-09-07T08:10:00.000Z" last_activity: 2026-09-07 -last_activity_desc: Phase 17 Browser-Gegenproben nachgeholt, Phase auf passed +last_activity_desc: Alle nachholbaren Browser-Gegenproben erledigt (Phase 15/16/17); ein Defekt gefunden (WINDOWS #10) progress: total_phases: 17 completed_phases: 17 @@ -336,7 +336,7 @@ Items acknowledged and carried forward from previous milestone close: ## Session Continuity -Last session: 2026-09-07T07:56:00.000Z -Stopped at: Phase 17 auf passed gesetzt; 6 aeltere Browser-Gegenproben aus Phase 15/16 (WINDOWS.md #1-#6) bleiben offen. +Last session: 2026-09-07T08:10:00.000Z +Stopped at: Naechster Schritt: WINDOWS #10 beheben (Guard ins gemeinsame Modul-Layout) oder /gsd-ship fuer Phase 17. Resume file: None Last activity: 2026-07-14 - Built LDAP per-user exclude/denylist filter (9d1323f), migration applied on live DB, verified via Playwright: sync deactivated 4 excluded service accounts (administrator/krbtgt/guest/dns-ldap), 2 real LDAP users stay active, 0 wrongly created diff --git a/.planning/WINDOWS.md b/.planning/WINDOWS.md index 48c84eb..75c772c 100644 --- a/.planning/WINDOWS.md +++ b/.planning/WINDOWS.md @@ -1,10 +1,10 @@ --- schema_version: 1 -open_count: 6 +open_count: 3 waived_count: 0 -fixed_count: 3 -total_count: 9 -last_updated: 2026-09-07T07:50:56.910Z +fixed_count: 7 +total_count: 10 +last_updated: 2026-09-07T08:03:51.517Z --- # Broken Windows Ledger @@ -15,15 +15,16 @@ last_updated: 2026-09-07T07:50:56.910Z | id | phase | kind | file | line | description | status | reason | recorded_at | resolved_at | |----|-------|------|------|------|-------------|--------|--------|-------------|-------------| -| 1 | 15 | unrun-verify | .planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-06-PLAN.md | | 15-06 : manueller Browser-Durchklick (Anlegen/Umbenennen/Standardmarkierung/AD-Bindung/Mitglieder/Loeschdialog + Fehlerpfade bei abgeschalteter API) nicht ausgefuehrt — kein Browser-Tool in dieser Session verfuegbar | open | | 2026-08-04T17:05:42.026Z | | -| 2 | 15 | unrun-verify | .planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-07-PLAN.md | | Manueller Browser-Durchklick aus dem Plan-Verification-Block (Matrix-Freigabe setzen/entziehen, Aktivierungsdialog beide Wege, Direkt-Grant neben Gruppen-Grant, Fehlerfall bei gestoppter API, lange Namen) nicht ausgefuehrt -- kein Browser-Tool in dieser Session (15-07-SUMMARY.md D4) | open | | 2026-08-04T17:27:42.267Z | | -| 3 | 15 | unrun-verify | .planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-08-PLAN.md | | Manueller Browser-Durchklick aus dem Plan-Verification-Block (USER ohne Freigabe: Sidebar/403-Seite/Marketplace-Badge+Toast/API-403 identisch; ADMIN: alle vier Ebenen zugaenglich) nicht ausgefuehrt - kein Browser-Tool in dieser Session verfuegbar. | open | | 2026-08-04T17:50:13.320Z | | +| 1 | 15 | unrun-verify | .planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-06-PLAN.md | | 15-06 : manueller Browser-Durchklick (Anlegen/Umbenennen/Standardmarkierung/AD-Bindung/Mitglieder/Loeschdialog + Fehlerpfade bei abgeschalteter API) nicht ausgefuehrt — kein Browser-Tool in dieser Session verfuegbar | fixed | | 2026-08-04T17:05:42.026Z | 2026-09-07T08:03:50.832Z | +| 2 | 15 | unrun-verify | .planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-07-PLAN.md | | Manueller Browser-Durchklick aus dem Plan-Verification-Block (Matrix-Freigabe setzen/entziehen, Aktivierungsdialog beide Wege, Direkt-Grant neben Gruppen-Grant, Fehlerfall bei gestoppter API, lange Namen) nicht ausgefuehrt -- kein Browser-Tool in dieser Session (15-07-SUMMARY.md D4) | fixed | | 2026-08-04T17:27:42.267Z | 2026-09-07T08:03:51.067Z | +| 3 | 15 | unrun-verify | .planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-08-PLAN.md | | Manueller Browser-Durchklick aus dem Plan-Verification-Block (USER ohne Freigabe: Sidebar/403-Seite/Marketplace-Badge+Toast/API-403 identisch; ADMIN: alle vier Ebenen zugaenglich) nicht ausgefuehrt - kein Browser-Tool in dieser Session verfuegbar. | fixed | | 2026-08-04T17:50:13.320Z | 2026-09-07T08:03:51.288Z | | 4 | 16 | unrun-verify | .planning/phases/16-ad-gruppen-synchronisation/16-03-PLAN.md | | 16-03 Task 2 human-check: RESEARCH.md Annahmen A1 (objectGUID uebersteht AD-Umbenennung) und A2 (byteweise Hex-Filter-Syntax) sind gegen kein echtes Active Directory geprueft — kein erreichbares AD in dieser Sandbox. Negatives Ergebnis bei A1 oder A2 ist Stopp-Grund fuer die Loeschsemantik (D-05). | open | | 2026-08-06T14:21:59.987Z | | -| 5 | 16 | unrun-verify | .planning/phases/16-ad-gruppen-synchronisation/16-04-PLAN.md | | Manueller Browser-Durchklick aus dem Plan-Verification-Block (drei GroupFormModal-Zustaende: Anlegen mit Hinweis-Link, lokale Gruppe umbenennen, importierte Gruppe mit gesperrtem Namen + internem Namen speichern; Namensanzeige mit Tooltip in der Liste nach dem Speichern) nicht ausgefuehrt — kein Browser-Tool in dieser Session verfuegbar. | open | | 2026-08-06T14:31:14.336Z | | +| 5 | 16 | unrun-verify | .planning/phases/16-ad-gruppen-synchronisation/16-04-PLAN.md | | Manueller Browser-Durchklick aus dem Plan-Verification-Block (drei GroupFormModal-Zustaende: Anlegen mit Hinweis-Link, lokale Gruppe umbenennen, importierte Gruppe mit gesperrtem Namen + internem Namen speichern; Namensanzeige mit Tooltip in der Liste nach dem Speichern) nicht ausgefuehrt — kein Browser-Tool in dieser Session verfuegbar. | fixed | | 2026-08-06T14:31:14.336Z | 2026-09-07T08:03:51.517Z | | 6 | 16 | unrun-verify | .planning/phases/16-ad-gruppen-synchronisation/16-05-PLAN.md | | 16-05 Manuell nachzuholen (Browser): Sync ausloesen und pruefen, dass alle drei Zahlenzeilen erscheinen; Lauf mit verschobener Standardmarkierung provozieren und Amber-Zeile pruefen; Freigabe-Matrix-Spaltensuche unter beiden Namen probieren - nicht ausgefuehrt, kein Browser-Tool in dieser Session verfuegbar. | open | | 2026-08-06T14:39:03.905Z | | | 7 | 17 | unrun-verify | .planning/phases/17-eigene-ausschreibungs-quellen-je-nutzer/17-01-PLAN.md | | 17-01 Task 2 human-check: Browser-Gegenprobe (normaler Nutzer oeffnet /modules/tender-radar/my-sources, speichert Postfach, zweites Konto desselben Mandanten sieht leeres Formular) nicht ausgefuehrt — kein Browser-Tool in dieser Session verfuegbar. Automatisierte Pruefungen (prisma validate/migrate status, Index-Liste, beide Typpruefungen, 335/335 src/tenders-Tests) sind gelaufen und gruen. | fixed | | 2026-08-12T09:24:35.289Z | 2026-09-07T07:50:56.468Z | | 8 | 17 | unrun-verify | apps/web/src/app/(portal)/modules/tender-radar/my-sources/page.tsx | | Browser-Gegenprobe Plan 17-03 Task 1 (Tracer-Feedback-Gate): Meine Quellen mit drei Abschnitten, neu angelegter eigener Feed sofort sichtbar, plattformweiter Feed ohne Entfernen-Knopf, Digest-Intervall speichert nach Reload — kein Browser-Tool in dieser Sitzung verfuegbar | fixed | | 2026-08-12T10:02:49.122Z | 2026-09-07T07:50:56.693Z | | 9 | 17 | unrun-verify | apps/web/src/app/(portal)/modules/tender-radar/settings/page.tsx | | Browser-Gegenprobe Plan 17-03 Task 2: USER-Konto sieht keine Bedienelemente auf /settings (nur Hinweis+Verweis), ADMIN-Konto sieht Abrufintervall+plattformweite Feeds ohne Postfach/Benachrichtigung, Zahnrad fuehrt in beiden Faellen nach Meine Quellen — kein Browser-Tool in dieser Sitzung verfuegbar | fixed | | 2026-08-12T10:02:49.291Z | 2026-09-07T07:50:56.910Z | +| 10 | 15 | unmet-truth | apps/web/src/app/(portal)/modules/tender-radar/page.tsx | | PERM-04 greift nicht auf modul-eigenen Routen: der Zugriffs-Guard sitzt nur in modules/[category]/[moduleSlug]/page.tsx. Die vier fest verdrahteten Modulrouten (tender-radar, dkv-fleet, cert-manager, domaincheck) samt Unterseiten (z.B. tender-radar/my-sources) laufen daran vorbei und rendern fuer einen USER OHNE Modulfreigabe vollstaendig, inklusive bedienbarer Knoepfe. Im Browser gemessen am 2026-09-07 mit nutzer2 (keine Freigabe): /modules/procurement/tender-radar zeigt korrekt die 403-Seite, /modules/tender-radar und /modules/tender-radar/my-sources und /modules/dkv-fleet zeigen die volle Seite. Keine Datenpreisgabe - die API antwortet auf allen Endpunkten mit 403 - aber der Nutzer sieht Bedienelemente, die er nicht benutzen darf, und bekommt rohe englische Techniktexte statt einer verstaendlichen Meldung. Beleg: .planning/phases/17-eigene-ausschreibungs-quellen-je-nutzer/uat-2026-09-07/befund-modul-eigene-route-ohne-freigabe.png | open | | 2026-09-07T08:03:45.978Z | | ````json [ @@ -34,10 +35,10 @@ last_updated: 2026-09-07T07:50:56.910Z "file": ".planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-06-PLAN.md", "line": null, "description": "15-06 : manueller Browser-Durchklick (Anlegen/Umbenennen/Standardmarkierung/AD-Bindung/Mitglieder/Loeschdialog + Fehlerpfade bei abgeschalteter API) nicht ausgefuehrt — kein Browser-Tool in dieser Session verfuegbar", - "status": "open", + "status": "fixed", "reason": "", "recorded_at": "2026-08-04T17:05:42.026Z", - "resolved_at": null + "resolved_at": "2026-09-07T08:03:50.832Z" }, { "id": 2, @@ -46,10 +47,10 @@ last_updated: 2026-09-07T07:50:56.910Z "file": ".planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-07-PLAN.md", "line": null, "description": "Manueller Browser-Durchklick aus dem Plan-Verification-Block (Matrix-Freigabe setzen/entziehen, Aktivierungsdialog beide Wege, Direkt-Grant neben Gruppen-Grant, Fehlerfall bei gestoppter API, lange Namen) nicht ausgefuehrt -- kein Browser-Tool in dieser Session (15-07-SUMMARY.md D4)", - "status": "open", + "status": "fixed", "reason": "", "recorded_at": "2026-08-04T17:27:42.267Z", - "resolved_at": null + "resolved_at": "2026-09-07T08:03:51.067Z" }, { "id": 3, @@ -58,10 +59,10 @@ last_updated: 2026-09-07T07:50:56.910Z "file": ".planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-08-PLAN.md", "line": null, "description": "Manueller Browser-Durchklick aus dem Plan-Verification-Block (USER ohne Freigabe: Sidebar/403-Seite/Marketplace-Badge+Toast/API-403 identisch; ADMIN: alle vier Ebenen zugaenglich) nicht ausgefuehrt - kein Browser-Tool in dieser Session verfuegbar.", - "status": "open", + "status": "fixed", "reason": "", "recorded_at": "2026-08-04T17:50:13.320Z", - "resolved_at": null + "resolved_at": "2026-09-07T08:03:51.288Z" }, { "id": 4, @@ -82,10 +83,10 @@ last_updated: 2026-09-07T07:50:56.910Z "file": ".planning/phases/16-ad-gruppen-synchronisation/16-04-PLAN.md", "line": null, "description": "Manueller Browser-Durchklick aus dem Plan-Verification-Block (drei GroupFormModal-Zustaende: Anlegen mit Hinweis-Link, lokale Gruppe umbenennen, importierte Gruppe mit gesperrtem Namen + internem Namen speichern; Namensanzeige mit Tooltip in der Liste nach dem Speichern) nicht ausgefuehrt — kein Browser-Tool in dieser Session verfuegbar.", - "status": "open", + "status": "fixed", "reason": "", "recorded_at": "2026-08-06T14:31:14.336Z", - "resolved_at": null + "resolved_at": "2026-09-07T08:03:51.517Z" }, { "id": 6, @@ -134,6 +135,18 @@ last_updated: 2026-09-07T07:50:56.910Z "reason": "", "recorded_at": "2026-08-12T10:02:49.291Z", "resolved_at": "2026-09-07T07:50:56.910Z" + }, + { + "id": 10, + "kind": "unmet-truth", + "phase": "15", + "file": "apps/web/src/app/(portal)/modules/tender-radar/page.tsx", + "line": null, + "description": "PERM-04 greift nicht auf modul-eigenen Routen: der Zugriffs-Guard sitzt nur in modules/[category]/[moduleSlug]/page.tsx. Die vier fest verdrahteten Modulrouten (tender-radar, dkv-fleet, cert-manager, domaincheck) samt Unterseiten (z.B. tender-radar/my-sources) laufen daran vorbei und rendern fuer einen USER OHNE Modulfreigabe vollstaendig, inklusive bedienbarer Knoepfe. Im Browser gemessen am 2026-09-07 mit nutzer2 (keine Freigabe): /modules/procurement/tender-radar zeigt korrekt die 403-Seite, /modules/tender-radar und /modules/tender-radar/my-sources und /modules/dkv-fleet zeigen die volle Seite. Keine Datenpreisgabe - die API antwortet auf allen Endpunkten mit 403 - aber der Nutzer sieht Bedienelemente, die er nicht benutzen darf, und bekommt rohe englische Techniktexte statt einer verstaendlichen Meldung. Beleg: .planning/phases/17-eigene-ausschreibungs-quellen-je-nutzer/uat-2026-09-07/befund-modul-eigene-route-ohne-freigabe.png", + "status": "open", + "reason": "", + "recorded_at": "2026-09-07T08:03:45.978Z", + "resolved_at": null } ] ```` diff --git a/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-UAT-2026-09-07.md b/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-UAT-2026-09-07.md new file mode 100644 index 0000000..5e9f9c1 --- /dev/null +++ b/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-UAT-2026-09-07.md @@ -0,0 +1,129 @@ +--- +phase: 15-modul-berechtigungen-gruppen-user-grants +kind: uat-nachtrag +date: 2026-09-07 +windows_addressed: [1, 2, 3] +windows_opened: [10] +result: 2 von 3 bestanden, 1 mit Befund +--- + +# Phase 15 — Browser-Gegenproben, nachgeholt am 2026-09-07 + +Die drei Browser-Durchläufe aus den Plänen 15-06, 15-07 und 15-08 waren seit dem +2026-08-04 offen, weil in den damaligen Ausführungssitzungen kein Browser-Tool +verfügbar war (WINDOWS.md #1, #2, #3). Sie wurden jetzt nachgeholt. + +**Aufbau:** frisch gebaute Images aus `main` (`79015dd`), lokaler Docker-Stack, +leere Datenbank, echter Chrome über Playwright. Testdaten über die Oberfläche +angelegt: Modul im Marktplatz aktiviert, zwei USER-Konten (`nutzer1`, `nutzer2`) +im selben Mandanten, Gruppen und Freigaben über die Administrationsseiten. + +## WINDOWS #1 — Gruppenverwaltung (15-06) — BESTANDEN + +| Schritt aus dem Plan | Beobachtung | +|---|---| +| Gruppe anlegen | „Vertrieb" erscheint in der Liste, Spalte AD-Bindung „Manuell", 0 Mitglieder | +| Umbenennen | Auf „Vertrieb Innendienst" geändert, Liste zieht nach | +| Standardmarkierung setzen | Markierung wandert exklusiv: „Alle Benutzer" wechselt auf „Als Standardgruppe festlegen", die neue Gruppe trägt „Standardgruppe" | +| Standardmarkierung wieder abschalten | Durch Setzen bei „Alle Benutzer" zurückgewandert | +| Mitglied hinzufügen | „Nutzer Eins" erscheint mit Herkunfts-Badge „Manuell"; seine Auswahl-Checkbox ist danach gesperrt, ein Doppel-Hinzufügen also nicht möglich | +| Mitglied entfernen | Liste wieder leer, Checkbox wieder frei | +| Löschdialog mit gefüllter Gruppe | „Diese Gruppe hat 1 Mitglieder und 1 Modul-Freigaben." — beide Zahlen konkret genannt (D-17) | +| Löschvorgang bei gestoppter API | Sichtbare deutsche Klartextmeldung „Gruppe konnte nicht gelöscht werden. Bitte erneut versuchen.", Löschen-Knopf danach gesperrt, Gruppe bleibt in der Liste | + +**Nicht mehr prüfbar, weil bewusst geändert:** Der Plan verlangte „an eine +AD-Gruppe binden und Bindung lösen" sowie die AD-Suche bei gestoppter API. Beides +gibt es an dieser Stelle nicht mehr. Phase 16 hat den Anlegen-Dialog umgebaut: er +trägt jetzt den Hinweis „AD-Gruppen werden im LDAP-Bereich importiert, nicht hier +angelegt." samt Link dorthin. Die Prüfpunkte sind damit gegenstandslos, nicht +übersprungen. + +**Kleiner Sprachbefund:** Der Löschdialog schreibt „1 Mitglieder" statt +„1 Mitglied" — Plural auch bei Eins. + +## WINDOWS #2 — Freigaben-Matrix und Direkt-Grants (15-07) — BESTANDEN + +| Schritt aus dem Plan | Beobachtung | +|---|---| +| Freigabe in der Matrix setzen | Checkbox für „Vertrieb Innendienst" gesetzt, Beschriftung wechselt von „freigeben" auf „entziehen" | +| Freigabe wieder entziehen und Wirkung gegenprüfen | Entzug für „Alle Benutzer" führte dazu, dass `nutzer2` den Zugriff sofort verlor — belegt über alle vier Ebenen unter #3 | +| Aktivierungsdialog, Weg „Sofort freigeben" | Cert Manager aktiviert; Grant an die Standardgruppe „Alle Benutzer" entstand (D-10) | +| Aktivierungsdialog, Weg „Später konfigurieren" | DKV-Rechnung aktiviert; **kein** Grant entstanden (0 Freigaben in der Datenbank) | +| Direkt-Grant neben Gruppen-Grant | Im Benutzer-Detail von `nutzer1` zeigt die Spalte „Über Gruppe(n)" beide freigebenden Gruppen an, während die Spalte „Direkt" unabhängig davon gesetzt werden kann | +| Matrix-Zelle bei gestoppter API | Fehlermeldung erscheint **und** die Checkbox springt in ihren alten Zustand zurück; die Datenbank zeigt danach unveränderte Freigaben — kein optimistischer Zustand überlebt den fehlgeschlagenen Request. Beleg: `uat-2026-09-07/w2-matrix-rollback-api-aus.png` | +| Direkt-Kästchen bei gestoppter API | Fehlermeldung im Dialog, Grant unverändert in der Datenbank | +| Sehr langer Gruppenname | Kopfzeile schneidet mit Ellipse ab („Abteilung Zentraler Einkauf und Vergabemanagement…"), Spaltenbreiten bleiben, die Seite scrollt nicht horizontal. Beleg: `uat-2026-09-07/w2-matrix-lange-namen.png` | + +**Befunde ohne Blockerwirkung:** + +- Die Fehlermeldung bei gestoppter API lautet in Matrix und Benutzer-Detail roh + „500: Internal Server Error". Der Löschdialog der Gruppenseite kann es besser + (deutscher Klartext) — die Behandlung ist also uneinheitlich. +- Wird eine Matrix-Seite bei bereits gestoppter API frisch geladen, meldet sie dem + Administrator „Zugriff verweigert" statt „Server nicht erreichbar". Das ist eine + irreführende Diagnose: der Administrator vermutet ein Rechteproblem statt eines + Serverausfalls. +- Der Aktivierungsdialog duzt („möchtest du die Freigaben separat konfigurieren?"), + während die übrige Oberfläche siezt. +- Das Deaktivieren eines Moduls entfernt seine Freigaben nicht. Beim + Wiederaktivieren sind die alten Freigaben sofort wieder wirksam. Das wirkt + gewollt, ist aber nirgends festgehalten. + +## WINDOWS #3 — Sperrung ohne Freigabe über alle vier Ebenen (15-08) — DURCHGEFÜHRT, MIT BEFUND + +Geprüft mit `nutzer2` (Rolle USER, Freigabe für Ausschreibungs-Radar entzogen) +gegen `nutzer1` (Freigabe über Gruppe) und `admin`. + +| Ebene | Ergebnis | +|---|---| +| 1. Sidebar | Kategorie „procurement" fehlt für `nutzer2` vollständig; nur „security tools" (Cert Manager, dort freigegeben) erscheint ✓ | +| 2. Direkte URL `/modules/procurement/tender-radar` | 403-Seite „Kein Zugriff auf dieses Modul" mit Handlungsanweisung und Weg zurück ✓ (D-07) | +| 3. Marketplace | Karte trägt „Aktiviert" **und** das Sperr-Badge „Kein Zugriff", ist nicht anklickbar; der Klick löst den Toast „Kein Zugriff auf dieses Modul — wende dich an deinen Administrator." aus und navigiert **nicht** ✓ (D-08). Modul wird gekennzeichnet, nicht ausgeblendet | +| 4. API | `nutzer2` erhält auf `/modules/tender-radar` und allen geprüften Unterendpunkten (`saved-searches`, `rss-feeds`, `email-config`) durchgehend HTTP 403; `nutzer1` durchgehend 200 ✓ | + +**Der Nachweis von PERM-04 gelingt damit auf drei von vier Ebenen nicht +vollständig — siehe WINDOWS #10.** + +### WINDOWS #10 (neu) — der Zugriffs-Guard greift nicht auf modul-eigenen Routen + +Ebene 2 ist nur für die generische Route abgesichert. Der Guard sitzt in +`modules/[category]/[moduleSlug]/page.tsx`. Vier Module haben daneben fest +verdrahtete eigene Routen: + +``` +apps/web/src/app/(portal)/modules/cert-manager/ +apps/web/src/app/(portal)/modules/dkv-fleet/ +apps/web/src/app/(portal)/modules/domaincheck/ +apps/web/src/app/(portal)/modules/tender-radar/ +``` + +Diese laufen am Guard vorbei. Im Browser als `nutzer2` **ohne** Freigabe gemessen: + +| Adresse | Ergebnis | +|---|---| +| `/modules/procurement/tender-radar` | 403-Seite ✓ (generische Route, abgesichert) | +| `/modules/tender-radar` | **volle Seite** — Überschrift, Filter, Suchprofil-Formular, Trefferliste, Zahnrad-Link | +| `/modules/tender-radar/my-sources` | **volle Seite** — Postfach-Formular, Feed-Formular, Digest-Auswahl, alle Knöpfe bedienbar | +| `/modules/dkv-fleet` | **volle Seite** — inklusive Knopf „Jetzt pruefen" und Link zu den Moduleinstellungen | + +**Es werden keine Daten preisgegeben.** Die API antwortet auf jedem Endpunkt mit +403, die Listen bleiben leer. Der Defekt liegt auf der Anzeigeebene: + +1. Der Nutzer sieht eine Seite, die er nicht benutzen darf, statt der 403-Seite. +2. Die Bedienelemente sind anklickbar und laufen ins Leere — genau das, was + Plan 17-03 auf der Einstellungsseite des Ausschreibungs-Radars abgeschafft hat. +3. Statt einer verständlichen Meldung erscheinen rohe englische Techniktexte + mitten in der deutschen Oberfläche: „Module 'tender-radar' is not accessible + for this user", „Failed to fetch tenders", „Failed to fetch saved searches", + „Failed to fetch notification preference". + +Beleg: `uat-2026-09-07/befund-modul-eigene-route-ohne-freigabe.png` + +**Erwartete Behebung:** Die Zugriffsprüfung gehört in ein gemeinsames Layout über +allen Modulrouten (etwa `(portal)/modules/layout.tsx` mit Auflösung des Modul-Slugs +aus dem Pfad) statt in die einzelne Seitenkomponente der generischen Route. + +## Ergebnis + +WINDOWS #1 und #2 sind geschlossen. #3 ist als Durchlauf erledigt; der dabei +gefundene Defekt ist als #10 eigenständig erfasst und bleibt offen. diff --git a/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/uat-2026-09-07/befund-modul-eigene-route-ohne-freigabe.png b/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/uat-2026-09-07/befund-modul-eigene-route-ohne-freigabe.png new file mode 100644 index 0000000..9c6ce9b Binary files /dev/null and b/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/uat-2026-09-07/befund-modul-eigene-route-ohne-freigabe.png differ diff --git a/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/uat-2026-09-07/w2-matrix-lange-namen.png b/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/uat-2026-09-07/w2-matrix-lange-namen.png new file mode 100644 index 0000000..5cf0e39 Binary files /dev/null and b/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/uat-2026-09-07/w2-matrix-lange-namen.png differ diff --git a/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/uat-2026-09-07/w2-matrix-rollback-api-aus.png b/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/uat-2026-09-07/w2-matrix-rollback-api-aus.png new file mode 100644 index 0000000..d709221 Binary files /dev/null and b/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/uat-2026-09-07/w2-matrix-rollback-api-aus.png differ diff --git a/.planning/phases/16-ad-gruppen-synchronisation/16-UAT-2026-09-07.md b/.planning/phases/16-ad-gruppen-synchronisation/16-UAT-2026-09-07.md new file mode 100644 index 0000000..f848d77 --- /dev/null +++ b/.planning/phases/16-ad-gruppen-synchronisation/16-UAT-2026-09-07.md @@ -0,0 +1,61 @@ +--- +phase: 16-ad-gruppen-synchronisation +kind: uat-nachtrag +date: 2026-09-07 +windows_addressed: [5] +windows_still_open: [4, 6] +result: 1 bestanden, 2 weiterhin offen (echtes AD erforderlich) +--- + +# Phase 16 — Browser-Gegenprobe, nachgeholt am 2026-09-07 + +Von den drei offenen Punkten aus Phase 16 (WINDOWS.md #4, #5, #6) ließ sich einer +ohne erreichbares Active Directory nachholen. Die beiden anderen nicht — sie +messen den Sync selbst, nicht die Oberfläche. + +**Aufbau:** frisch gebaute Images aus `main` (`79015dd`), lokaler Docker-Stack, +leere Datenbank, echter Chrome über Playwright. + +## WINDOWS #5 — die drei Zustände des Gruppen-Dialogs (16-04) — BESTANDEN + +| Zustand | Beobachtung | +|---|---| +| Anlegen | Kein Feld für eine AD-Bindung, sondern der Hinweis „AD-Gruppen werden im LDAP-Bereich importiert, nicht hier angelegt." mit Link „Zum LDAP-Bereich" | +| Lokale Gruppe umbenennen | Namensfeld frei editierbar, kein AD-Hinweis, kein Feld für einen internen Namen. Umbenennung von „Vertrieb" auf „Vertrieb Innendienst" zieht sofort in die Liste durch | +| Importierte Gruppe bearbeiten | Namensfeld **gesperrt** mit dem vollen AD-Namen und der Erklärung „Von der AD-Gruppe übernommen. Wird beim nächsten Sync automatisch aktualisiert."; darunter die Zeile „AD-DN: CN=Zentraler Einkauf,OU=Abteilungen,DC=firma,DC=local"; darunter das freie Feld „Interner Name" mit der Erklärung „Wird von der Synchronisation nie verändert. Bleibt das Feld leer, zeigt die Oberfläche stattdessen den AD-Namen." | + +**Namensanzeige mit Tooltip nach dem Speichern:** Nach dem Setzen des internen +Namens auf „Einkauf Nordwest" zeigt die Liste diesen an, und das `title`-Attribut +der Namenszelle trägt den vollen AD-Namen „Abteilung Zentraler Einkauf und +Vergabemanagement Region Nordwest Standort Braunschweig". Die Spalte AD-Bindung +steht auf „AD-gebunden". Programmatisch aus dem gerenderten DOM ausgelesen, nicht +aus dem Quelltext geschlossen. + +Beleg: `uat-2026-09-07/w5-gruppenliste-interner-name.png` + +**Wie die importierte Gruppe entstanden ist — ausdrücklich vermerkt:** In dieser +Sandbox gibt es kein erreichbares Active Directory. Die AD-Bindung wurde deshalb +direkt in der Datenbank gesetzt (`ldapDn`, `ldapObjectGuid`, `internalName`), nicht +durch einen echten Import. Das ist für diesen Prüfpunkt zulässig, weil der zu +prüfende Dialogzustand ausschließlich vom Datensatz abhängt und nicht davon, wie er +entstanden ist. Für die Prüfpunkte #4 und #6 gilt das ausdrücklich **nicht** — die +messen den Sync-Vorgang selbst. + +## WINDOWS #4 und #6 — weiterhin offen + +Beide brauchen ein echtes Active Directory und können hier nicht ersetzt werden: + +- **#4 (16-03):** Die Annahmen A1 (`objectGUID` übersteht eine Umbenennung im AD) + und A2 (byteweise Hex-Filter-Syntax) sind gegen kein echtes Verzeichnis geprüft. + Ein negatives Ergebnis bei A1 oder A2 wäre ein Stopp-Grund für die + Löschsemantik (D-05). Der verwandte kritische Fehler in der Löscherkennung wurde + am 2026-08-11 mit `d2019dc` behoben und dabei read-only am echten AD gemessen — + A1 selbst bleibt davon unberührt offen. +- **#6 (16-05):** Einen Sync auslösen und die drei Zahlenzeilen sowie die + Amber-Zeile bei verschobener Standardmarkierung prüfen. Ohne Verzeichnis gibt es + keinen Lauf, dessen Zahlen man ablesen könnte. Die Spaltensuche der + Freigaben-Matrix unter beiden Namen ist dagegen inzwischen indirekt belegt: die + Matrix zeigt AD-gebundene Gruppen unter ihrem internen Namen an (siehe #5). + +Beide Punkte bleiben im Ledger `open` und sind vor dem Produktivbetrieb der +AD-Synchronisation an einem echten Verzeichnis nachzuholen. diff --git a/.planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/w5-gruppenliste-interner-name.png b/.planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/w5-gruppenliste-interner-name.png new file mode 100644 index 0000000..361147c Binary files /dev/null and b/.planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/w5-gruppenliste-interner-name.png differ