diff --git a/.planning/STATE.md b/.planning/STATE.md index d0f4166..caf87ac 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -5,10 +5,10 @@ milestone_name: Plattform-Berechtigungen current_phase: 17 current_phase_name: eigene-ausschreibungs-quellen-je-nutzer status: verified -stopped_at: "Aufraeumen abgeschlossen. Zwei veraltete .continue-here-Dateien entfernt, ihre noch gueltigen Inhalte (5 Anti-Patterns, Infrastruktur-Stand alpha, Blocker 'kein AD-Schreibzugriff') nach STATE.md Accumulated Context ueberfuehrt; .gsd/ in .gitignore. Naechster Schritt: Live-Tests WINDOWS #4, #6 (echtes AD) und #12 (echtes Exchange-Postfach). Achtung: #4 braucht AD-Schreibrechte, die am 2026-08-11 noch fehlten." -last_updated: "2026-09-07T14:40:00.000Z" +stopped_at: "Live-Test gegen das echte AD (balios.ctl.local) auf alpha durchgefuehrt. BELEGT: #4/A2 (byteweise Filter-Syntax, read-only gemessen) und #6 Teile (a) drei Zahlenzeilen und (c) Spaltensuche unter internem und AD-Namen. OFFEN und auf den User angewiesen: #4/A1 und #6/(b) brauchen AD-Schreibzugriff (Weg: Wegwerf-Gruppe im AD anlegen, einbinden, umbenennen bzw. loeschen); #12 braucht Postfachadresse, EWS-Adresse und Zugangsdaten — auf alpha ist TenderEmailConfig leer. NEU gefunden: #14 (Matrix-Suche leert die jeweils andere Achse, Matrix damit unbenutzbar sobald gesucht wird) und #15 (rohe Prisma- und englische Techniktexte im Sync-Ergebnis, vier AD-Konten werden wegen E-Mail-Kollision nie importiert)." +last_updated: "2026-09-07T14:50:00.000Z" last_activity: 2026-09-07 -last_activity_desc: Checkpoint-Aufraeumen — veraltete .continue-here-Dateien entfernt, Pitfalls und Infrastruktur-Stand nach STATE.md gerettet +last_activity_desc: Live-Test gegen echtes AD — WINDOWS #4/A2 belegt, #6 (a)+(c) bestanden, zwei neue Defekte im Ledger progress: total_phases: 17 completed_phases: 17 @@ -368,9 +368,9 @@ Items acknowledged and carried forward from previous milestone close: | Category | Item | Status | Deferred At | |----------|------|--------|-------------| -| Live-Test AD | WINDOWS #4 — Annahmen A1 (objectGUID uebersteht Umbenennung) und A2 (byteweise Hex-Filter-Syntax) gegen ein echtes Active Directory pruefen. Negatives Ergebnis waere Stopp-Grund fuer die Loeschsemantik D-05 | offen, bewusst auf das Live-System verschoben | 2026-09-07 | -| Live-Test AD | WINDOWS #6 — Sync ausloesen und die drei Zahlenzeilen sowie die Amber-Zeile bei verschobener Standardmarkierung pruefen | offen, bewusst auf das Live-System verschoben | 2026-09-07 | -| Live-Test E-Mail | WINDOWS #12 — echtes Portal-Alert-Postfach ueber Exchange/EWS anbinden und eine echte Alarm-Mail ingestieren; der handgeschriebene NTLM/SOAP-Weg ist bisher nur gegen Mocks geprueft | offen, bewusst auf das Live-System verschoben | 2026-09-07 | +| Live-Test AD | WINDOWS #4 — **A2 am 2026-09-07 gegen das echte AD belegt** (EqualityFilter ueber rohen Buffer: 1 Treffer, escapter String: 0 Treffer; Bericht `16-LIVETEST-2026-09-07.md`). **A1 (objectGUID uebersteht Umbenennung) weiterhin offen** — braucht Schreibzugriff im Verzeichnis | teilweise belegt, A1 offen | 2026-09-07 | +| Live-Test AD | WINDOWS #6 — **Teil (a) drei Zahlenzeilen und Teil (c) Spaltensuche unter beiden Namen am 2026-09-07 auf alpha bestanden**. **Teil (b) Amber-Zeile weiterhin offen** — nur ausloesbar, wenn eine AD-gebundene Gruppe im Verzeichnis wirklich verschwindet (Schreibzugriff noetig; ueber den Suchbereich nicht nachstellbar, das verhindert die WR-03-Weitsuche zu Recht) | teilweise bestanden, (b) offen | 2026-09-07 | +| Live-Test E-Mail | WINDOWS #12 — echtes Portal-Alert-Postfach ueber Exchange/EWS anbinden und eine echte Alarm-Mail ingestieren; der handgeschriebene NTLM/SOAP-Weg ist bisher nur gegen Mocks geprueft. Stand 2026-09-07: auf alpha ist **kein Postfach hinterlegt** (`TenderEmailConfig` leer) — der Test kann erst starten, wenn Postfachadresse, EWS-Adresse und Zugangsdaten vorliegen | offen, wartet auf Zugangsdaten | 2026-09-07 | **Entscheidung des Users vom 2026-09-07 zur Mandantenfaehigkeit:** Tessera wird zunaechst **nur intern** eingesetzt. Die Mandantentrennung ist damit vorerst @@ -388,7 +388,7 @@ sind. Kein Anlass, sie vorher erneut vorzulegen. ## Session Continuity -Last session: 2026-09-07T14:40:00.000Z -Stopped at: Aufraeumen erledigt (veraltete Checkpoint-Dateien entfernt, ihr Wissen nach STATE.md gerettet, .gsd/ ignoriert). Als naechstes: die drei zurueckgestellten Live-Tests WINDOWS #4, #6, #12 gegen echtes AD und echtes Exchange-Postfach. +Last session: 2026-09-07T14:50:00.000Z +Stopped at: Live-Test gegen das echte AD durchgefuehrt. Belegt: WINDOWS #4/A2 und WINDOWS #6 Teile (a) und (c). Offen bleiben #4/A1 und #6/(b) — beide brauchen Schreibzugriff im Verzeichnis — sowie #12, das ein Exchange-Postfach samt Zugangsdaten braucht. Zwei neue Defekte gefunden und im Ledger erfasst (#14 Matrix-Suche leert die jeweils andere Achse, #15 rohe Techniktexte im Sync-Ergebnis). Bericht: .planning/phases/16-ad-gruppen-synchronisation/16-LIVETEST-2026-09-07.md Resume file: None -Last activity: 2026-09-07 - Checkpoint-Aufraeumen; Pitfalls und Infrastruktur-Stand in STATE.md ueberfuehrt +Last activity: 2026-09-07 - Live-Test AD auf alpha; #4/A2 und #6 (a)+(c) bestanden, zwei neue Defekte erfasst diff --git a/.planning/WINDOWS.md b/.planning/WINDOWS.md index 5c88f32..1c995f1 100644 --- a/.planning/WINDOWS.md +++ b/.planning/WINDOWS.md @@ -1,10 +1,10 @@ --- schema_version: 1 -open_count: 3 +open_count: 5 waived_count: 0 fixed_count: 10 -total_count: 13 -last_updated: 2026-09-07T09:35:49.019Z +total_count: 15 +last_updated: 2026-09-07T12:47:32.058Z --- # Broken Windows Ledger @@ -28,6 +28,8 @@ last_updated: 2026-09-07T09:35:49.019Z | 11 | 13 | unmet-truth | apps/api/src/tenders/tender-fingerprint.ts | | Cross-Source-Dedup kollabiert die Mehrzahl echter Duplikate nicht: tenderFingerprint() haengt [buyerName, title, cpvDivisionKey, deadlineKey, valueBucket] zu einem String und hasht ihn. Die Scraper-Adapter liefern cpvDivisions immer leer, DOE dagegen meist gefuellt - dieselbe Ausschreibung ergibt aus beiden Quellen verschiedene Fingerabdruecke, die Fingerprint-Stufe greift also gerade dort nicht, wo sie greifen soll. Steht als offener Rest in 13-VERIFICATION.md (status gaps_found, 3/4 Wahrheiten), war aber bisher nicht im Ledger und damit unsichtbar. Die frueher vermutete Ursache (Normalizer-Defaults) ist mit 9881005 geschlossen und nicht gemeint. | fixed | | 2026-09-07T08:09:04.188Z | 2026-09-07T08:42:34.794Z | | 12 | 14 | unrun-verify | .planning/phases/14-rss-email-alert-ingestion-module-rollout/14-03-PLAN.md | | 14-03 Task 4 (checkpoint human-verify, gate blocking): echtes Portal-Alert-Postfach ueber den Exchange/EWS-Weg anbinden und eine echte Alarm-Mail ingestieren. Zu belegen sind (a) die Mail erzeugt eine mandantenprivate Ausschreibung, (b) ein anderer Mandant sieht sie nicht, (c) der EWS-Body-Abruf liefert nicht-leeren, nicht-verstuemmelten Inhalt gegen einen echten Exchange-Server. Der handgeschriebene NTLM/SOAP-Weg ist nur gegen gemocktes httpntlm.post geprueft, nie gegen einen echten Server. Braucht ein echtes Postfach - vom User am 2026-07-24 bewusst zurueckgestellt. Stand bisher nur in 14-VERIFICATION.md (status human_needed), nicht im Ledger. | open | | 2026-09-07T08:09:04.406Z | | | 13 | 1 | unmet-truth | apps/web/src/app/globals.css | | Tailwind-4-Dunkelvariante war nie an die .dark-Klasse gebunden: globals.css definierte die Farbtokens unter .dark, deklarierte aber kein @custom-variant dark. In Tailwind 4 haengt die dark:-Utility-Variante per Vorgabe an prefers-color-scheme, nicht an einer Klasse. Die App schaltet den Modus jedoch ueber next-themes mit attribute=class. Folge: JEDE dark:-Utility im Web-Quellcode (ueber 100 Vorkommen in 10+ Dateien - Status-, Warn- und Fehlerfarben, Hinweisboxen, Badges in der Administration) blieb wirkungslos, sobald der Nutzer im Portal auf dunkel stellte, waehrend sein Betriebssystem hell stand. Am laufenden System gemessen: html.dark gesetzt, prefers-color-scheme hell, dark:bg-gray-800 ergab transparent und dark:text-green-400 blieb ohne Wirkung. Unentdeckt geblieben, weil Hintergrund und Textfarbe ueber CSS-Variablen unter .dark laufen und deshalb korrekt umschalten. Aufgedeckt beim Logo-Einbau 260907-fgv, dessen Plattenkontur dark:stroke-white/25 aus demselben Grund nicht griff. | fixed | | 2026-09-07T09:32:24.960Z | 2026-09-07T09:35:49.019Z | +| 14 | 15 | unmet-truth | apps/web/src/app/(portal)/admin/modules/grants/page.tsx | | Die Suche in der Freigaben-Matrix macht die Matrix unbenutzbar, sobald sie etwas findet: derselbe Suchbegriff filtert BEIDE Achsen unabhaengig voneinander (page.tsx:137 filtert Module ueber m.name, page.tsx:145 filtert Gruppen ueber internalName/name). Ein Begriff, der nur eine Achse trifft, leert die andere vollstaendig — es bleibt nie ein Kaestchen zum Klicken uebrig. Am 2026-09-07 im Browser auf alpha gemessen: Suche 'Claude_VT' bzw. 'Vertrieb' laesst die Gruppenspalte stehen, entfernt aber jede Modulzeile; Suche 'Cert' laesst die Modulzeile stehen, entfernt aber jede Gruppenspalte. Damit scheitert genau der Zweck der Suche — in einer grossen Matrix die Kreuzung Modul x Gruppe finden. Belege: .planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/befund-matrix-suche-gruppenname.png und befund-matrix-suche-modulname.png | open | | 2026-09-07T12:46:56.172Z | | +| 15 | 16 | unmet-truth | apps/api/src/ldap/ldap.service.ts | | Der Sync reicht rohe Techniktexte an den Administrator durch und laesst echte AD-Konten still liegen. Am 2026-09-07 auf alpha gegen das echte AD gemessen (Lauf 14:42): zehn Fehlerzeilen unter den drei Zahlenzeilen, davon zwei Sorten. (1) Vier Konten scheitern mit der woertlichen Prisma-Meldung 'Invalid prisma.user.create() invocation: Unique constraint failed on the fields: (email)' — CN=uvertrieb_ro, uvertrieb_rw, uvertrieb_ro_ss, usoftware_rw aus OU=CTL_PWS_Gruppen teilen sich offenbar eine E-Mail-Adresse. Sie werden dadurch NIE importiert, ohne dass der Administrator erfaehrt warum oder was er tun soll. (2) Sechs Eintraege melden englisch 'no username mapped (check sAMAccountName mapping)' — korrekt uebersprungene Kontakte/Ressourcen ohne sAMAccountName, aber die Meldung liest sich wie ein Fehler und ist nicht uebersetzt. Beides braucht eine verstaendliche deutsche Meldung; die E-Mail-Kollision zusaetzlich eine Entscheidung, ob solche Konten ohne E-Mail angelegt oder bewusst uebersprungen werden. Beleg: .planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/windows6a-sync-zahlenzeilen.png | open | | 2026-09-07T12:47:32.058Z | | ````json [ @@ -186,6 +188,30 @@ last_updated: 2026-09-07T09:35:49.019Z "reason": "", "recorded_at": "2026-09-07T09:32:24.960Z", "resolved_at": "2026-09-07T09:35:49.019Z" + }, + { + "id": 14, + "kind": "unmet-truth", + "phase": "15", + "file": "apps/web/src/app/(portal)/admin/modules/grants/page.tsx", + "line": null, + "description": "Die Suche in der Freigaben-Matrix macht die Matrix unbenutzbar, sobald sie etwas findet: derselbe Suchbegriff filtert BEIDE Achsen unabhaengig voneinander (page.tsx:137 filtert Module ueber m.name, page.tsx:145 filtert Gruppen ueber internalName/name). Ein Begriff, der nur eine Achse trifft, leert die andere vollstaendig — es bleibt nie ein Kaestchen zum Klicken uebrig. Am 2026-09-07 im Browser auf alpha gemessen: Suche 'Claude_VT' bzw. 'Vertrieb' laesst die Gruppenspalte stehen, entfernt aber jede Modulzeile; Suche 'Cert' laesst die Modulzeile stehen, entfernt aber jede Gruppenspalte. Damit scheitert genau der Zweck der Suche — in einer grossen Matrix die Kreuzung Modul x Gruppe finden. Belege: .planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/befund-matrix-suche-gruppenname.png und befund-matrix-suche-modulname.png", + "status": "open", + "reason": "", + "recorded_at": "2026-09-07T12:46:56.172Z", + "resolved_at": null + }, + { + "id": 15, + "kind": "unmet-truth", + "phase": "16", + "file": "apps/api/src/ldap/ldap.service.ts", + "line": null, + "description": "Der Sync reicht rohe Techniktexte an den Administrator durch und laesst echte AD-Konten still liegen. Am 2026-09-07 auf alpha gegen das echte AD gemessen (Lauf 14:42): zehn Fehlerzeilen unter den drei Zahlenzeilen, davon zwei Sorten. (1) Vier Konten scheitern mit der woertlichen Prisma-Meldung 'Invalid prisma.user.create() invocation: Unique constraint failed on the fields: (email)' — CN=uvertrieb_ro, uvertrieb_rw, uvertrieb_ro_ss, usoftware_rw aus OU=CTL_PWS_Gruppen teilen sich offenbar eine E-Mail-Adresse. Sie werden dadurch NIE importiert, ohne dass der Administrator erfaehrt warum oder was er tun soll. (2) Sechs Eintraege melden englisch 'no username mapped (check sAMAccountName mapping)' — korrekt uebersprungene Kontakte/Ressourcen ohne sAMAccountName, aber die Meldung liest sich wie ein Fehler und ist nicht uebersetzt. Beides braucht eine verstaendliche deutsche Meldung; die E-Mail-Kollision zusaetzlich eine Entscheidung, ob solche Konten ohne E-Mail angelegt oder bewusst uebersprungen werden. Beleg: .planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/windows6a-sync-zahlenzeilen.png", + "status": "open", + "reason": "", + "recorded_at": "2026-09-07T12:47:32.058Z", + "resolved_at": null } ] ```` diff --git a/.planning/phases/16-ad-gruppen-synchronisation/16-LIVETEST-2026-09-07.md b/.planning/phases/16-ad-gruppen-synchronisation/16-LIVETEST-2026-09-07.md new file mode 100644 index 0000000..8356853 --- /dev/null +++ b/.planning/phases/16-ad-gruppen-synchronisation/16-LIVETEST-2026-09-07.md @@ -0,0 +1,119 @@ +# Live-Test gegen echtes AD — 2026-09-07 + +Durchgefuehrt auf **alpha** (https://alpha.tessera.ctl.de) gegen das echte +Active Directory `balios.ctl.local` (172.16.0.11), Basis-DN `DC=ctl,DC=local`, +Dienstkonto `svc_tessera@ctl.local`. Angemeldet als `admin` (SUPER_ADMIN). + +Betrifft die Ledger-Punkte WINDOWS.md **#4** (Annahmen A1/A2) und **#6** +(Sync-Durchlauf im Browser). + +--- + +## WINDOWS #4 — Annahme A2: byteweise Filter-Syntax — **BELEGT** + +Gemessen mit einer read-only Sonde im API-Container, die den Produktionsweg +nachvollzieht. Der erwartete DN stammt aus der Tessera-Datenbank, nicht aus +derselben Hilfsfunktion, die den Filter baut — sonst waere die Messung +tautologisch (siehe Anti-Pattern-Tabelle in STATE.md). + +Referenzobjekt: Gruppe `Claude_VT`, gespeicherter objectGUID +`d11c8cea7d455f49a4919daee0039aa3`. + +| Messung | Ergebnis | +|---------|----------| +| `EqualityFilter` ueber rohen Buffer (heutiger Produktionsweg) | **1 Treffer** — `cn=Claude_VT`, DN identisch mit dem in Tessera gespeicherten, zurueckgelesener objectGUID identisch mit dem gespeicherten | +| `\xx`-escapter Hex-String (frueherer, fehlerhafter Weg) | **0 Treffer** | +| Unabhaengiger Anker: base-Suche auf dem gespeicherten DN | **1 Treffer**, gleiche Gruppe, gleicher objectGUID | + +**Bewertung:** A2 ist gegen ein echtes Active Directory bestaetigt. Der heutige +Weg findet das Objekt, der frueher verwendete findet es nicht — das ist genau +der Fehler, der am 2026-08-11 mit `d2019dc` behoben wurde, hier noch einmal am +echten Verzeichnis nachgemessen. + +**Zusaetzlicher Beleg aus dem echten Produktionspfad:** Der Sync-Lauf um 14:42 +meldete `AD-Gruppen: 0 neu uebernommen, 0 umbenannt, 0 geloescht`. Haette die +Existenzpruefung die Gruppe nicht gefunden, waere `Claude_VT` als verschwunden +behandelt und geloescht worden. Sie steht unveraendert mit 9 Mitgliedern da. + +## WINDOWS #4 — Annahme A1: objectGUID uebersteht Umbenennung — **OFFEN** + +Nicht pruefbar ohne Schreibzugriff auf das Verzeichnis: der Beleg verlangt, eine +AD-Gruppe tatsaechlich umzubenennen und danach zu messen, dass der objectGUID +gleich bleibt und Tessera den neuen Namen nachzieht. Der Stand vom 2026-08-11 +(kein AD-Schreibzugriff) wurde in dieser Sitzung nicht veraendert und nicht +erneut geprueft — es wurde bewusst kein Schreibversuch gegen das +Produktiv-Verzeichnis unternommen. + +--- + +## WINDOWS #6 — Sync-Durchlauf im Browser + +### Teil (a) — drei Zahlenzeilen — **BESTANDEN** + +Sync ueber `Jetzt synchronisieren` ausgeloest (Lauf 2026-09-07 14:42:22). Alle +drei Zahlenzeilen erscheinen: + +``` +Erstellt: 4, aktualisiert: 404, deaktiviert: 0 +Gruppenmitgliedschaften: 0 hinzugefügt, 0 entfernt +AD-Gruppen: 0 neu übernommen, 0 umbenannt, 0 gelöscht +``` + +Beleg: `uat-2026-09-07/windows6a-sync-zahlenzeilen.png` + +**Nebenbefund:** Unter den Zahlenzeilen stehen zehn Fehlerzeilen in roher +Techniksprache. Als eigener Ledger-Punkt erfasst (WINDOWS.md #15). + +### Teil (b) — Amber-Zeile bei verschobener Standardmarkierung — **OFFEN** + +Nicht ausloesbar ohne Schreibzugriff auf das Verzeichnis. Die vierte Zeile +erscheint nur, wenn die Standardmarkierung vor einer Loeschung umgehaengt wird — +das setzt voraus, dass eine AD-gebundene Gruppe im Verzeichnis tatsaechlich +verschwindet. + +Wichtig: das laesst sich **nicht** dadurch nachstellen, dass man die Gruppe aus +dem konfigurierten Suchbereich nimmt. Genau dafuer hat der Code die +WR-03-Weitsuche ueber die Domain-Wurzel: eine Gruppe, die nur ausserhalb des +Basis-DN liegt, wird ausdruecklich nicht als geloescht behandelt. Das Verhalten +ist korrekt und verhindert die Nachstellung. + +Gangbarer Weg ohne Risiko fuer echte Gruppen: eine Wegwerf-Gruppe im AD anlegen, +in Tessera einbinden, dort zur Standardgruppe machen, dann im AD loeschen und +den Sync ausloesen. + +### Teil (c) — Spaltensuche unter beiden Namen — **BESTANDEN** + +Vorbereitung: bei `Claude_VT` den internen Namen `Vertrieb Team` gesetzt. Die +Gruppenliste zeigt danach den internen Namen, der AD-Name bleibt im gesperrten +Namensfeld sichtbar. + +| Sucheingabe | Ergebnis | +|-------------|----------| +| `Vertrieb` (interner Name) | Spalte `Vertrieb Team` bleibt stehen, `Alle Benutzer` wird ausgefiltert | +| `Claude_VT` (AD-Name) | Spalte `Vertrieb Team` bleibt ebenfalls stehen | + +Die Spalte ist also unter beiden Namen auffindbar — der Pruefpunkt ist erfuellt +(`grants/page.tsx:145` prueft `internalName` und `name`). + +**Dabei aufgefallen:** Sobald die Suche greift, verschwindet die jeweils andere +Achse vollstaendig, sodass kein Kaestchen mehr zum Klicken bleibt. Als eigener +Ledger-Punkt erfasst (WINDOWS.md #14). + +--- + +## Zustand nach dem Test + +Alles Veraenderte wurde zurueckgesetzt: + +- Modul `Cert Manager` war zum Aufbau der Matrix voruebergehend aktiviert und ist + wieder deaktiviert (0 aktive Module, wie vorher). +- Der interne Name `Vertrieb Team` wurde wieder geleert. + +Nicht zurueckgesetzt, weil Folge des beauftragten Sync-Laufs: die Benutzerzahl +stieg von 405 auf 409 (vier zuvor nicht importierte AD-Konten), und die +Zeitstempel der bestehenden 404 Konten wurden aktualisiert. Reine Testdaten. + +Der bestehende Haken `Cert Manager` fuer `Alle Benutzer` in der Matrix stammt +nicht aus diesem Test: alle Gruppen-Freigaben tragen den Zeitstempel +2026-08-05 10:03:37. Der Aktivierungsdialog hat unter `Spaeter konfigurieren` +korrekt keine Freigabe angelegt. diff --git a/.planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/befund-matrix-suche-gruppenname.png b/.planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/befund-matrix-suche-gruppenname.png new file mode 100644 index 0000000..9a51fe0 Binary files /dev/null and b/.planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/befund-matrix-suche-gruppenname.png differ diff --git a/.planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/befund-matrix-suche-modulname.png b/.planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/befund-matrix-suche-modulname.png new file mode 100644 index 0000000..b7d8861 Binary files /dev/null and b/.planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/befund-matrix-suche-modulname.png differ diff --git a/.planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/windows6a-sync-zahlenzeilen.png b/.planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/windows6a-sync-zahlenzeilen.png new file mode 100644 index 0000000..a52ecb9 Binary files /dev/null and b/.planning/phases/16-ad-gruppen-synchronisation/uat-2026-09-07/windows6a-sync-zahlenzeilen.png differ