From 37a2f73ffbf4bb1cdc6f59ff70e1f30faad7551e Mon Sep 17 00:00:00 2001 From: Schalli Date: Mon, 14 Sep 2026 10:18:04 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20Sitzung=20wiederaufgenommen=20=E2=80=94?= =?UTF-8?q?=20Handoff=20verbraucht,=20Reihenfolge=20#29=20vor=20Etappe=203?= =?UTF-8?q?c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_018N9CD3ebPKm1b32bPpBknY --- .planning/.continue-here.md | 199 ------------------------------------ .planning/HANDOFF.json | 125 ---------------------- .planning/STATE.md | 6 +- 3 files changed, 3 insertions(+), 327 deletions(-) delete mode 100644 .planning/.continue-here.md delete mode 100644 .planning/HANDOFF.json diff --git a/.planning/.continue-here.md b/.planning/.continue-here.md deleted file mode 100644 index 3a5ff8d..0000000 --- a/.planning/.continue-here.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -context: default -phase: mandantentrennung-etappe-3 -task: null -total_tasks: 4 -status: paused -last_updated: 2026-09-14T08:02:29.277Z ---- - -# Wiedereinstieg — Etappe 3b abgeschlossen, offen sind 3c, 3a, Etappe 4 - -## Critical Anti-Patterns - -Alle stammen aus tatsaechlichen Fehlschlaegen der Etappen 1-3b, nicht aus Vorsicht. - -| Muster | Beschreibung | Schwere | Vermeidung | -|--------|--------------|---------|------------| -| Auf ein ungeprueftes Fundament bauen | `forTenant()` setzte den Kontext per `set_config` auf der Transaktionsverbindung, dispatchte die Abfrage aber ueber den aeusseren Client. Gemessen: `set_config` auf Backend-PID 254999, Abfrage auf 255000, Kontext dort NULL. Die Trennung hat nie funktioniert, auch nicht an den Stellen, die sie scheinbar nutzten. | blocking | Vor jedem Umbau, der auf einem Helfer aufsetzt, dessen Wirkung EMPIRISCH nachweisen — gegen eine Wegwerf-Datenbank, mit zwei Mandanten und einer echten Abfrage. Nicht den Code lesen und schliessen, dass er stimmt. | -| Zaehlung ohne Ansehen der Treffer | Eine `grep`-Zaehlung ergab 36 mandantengebundene Stellen. Tatsaechlich waren die meisten Treffer Kommentare, die erklaeren, warum `forTenant()` dort FEHLT. Echte Aufrufstellen: 6. | blocking | Bei jeder Zahl, die eine Planung traegt, in die Treffer hineinsehen. Eine Zahl aus `grep -c` ist eine Behauptung, kein Befund. | -| Falsche Datei auf dem Server bearbeitet | Die Volume-Zeile ging nach `/opt/tessera/docker-compose.yml` — der Server nutzt `docker-compose.prod.yml`, weil die `.env` `COMPOSE_FILE` setzt. | blocking | Nach JEDER Aenderung an einer Compose-Datei `docker compose config` rendern und pruefen, ob die Aenderung im Ergebnis auftaucht. Vorher `docker compose ls --format json` lesen. | -| Bericht statt Arbeitsbaum geglaubt | Zwei Agenten brachen am Sitzungslimit NACH getaner Arbeit ab; die Arbeit lag vollstaendig auf der Platte, der Bericht fehlte. | blocking | `git status` ist die Wahrheit, nicht der Agentenbericht. | -| Zeichensatz beim Veroeffentlichen angenommen | Die Handbuch-Webseite ging mit zerlegten Umlauten live ("Für" statt "Fuer"). | advisory | Seiten mit deutschem Text als reines ASCII ausliefern (Sonderzeichen als `\uXXXX`), mit `all(ord(c)<128 ...)` pruefen. | - - -**Seit dem 2026-09-11 17:58 wurde nichts mehr angefasst.** Arbeitsbaum leer -(`git status --porcelain` liefert nichts), `main == origin/main`, keine Datei im -Repo ist juenger als der letzte Commit. Es gibt also KEINE angefangene Arbeit, -die aufzunehmen waere — die Sitzung lief nach Etappe 3b bei ~70% Kontext aus, -der Handoff war geschrieben. Diese Datei ist die Neuaufnahme desselben Standes -am 2026-09-14, ergaenzt um zwei Punkte, die im alten Handoff fehlten -(WINDOWS #29 und der nie gelaufene Ship von Phase 17). - -**Stand der Mandantentrennung:** Etappe 1 (Fundament repariert, 227 Zugriffe -klassifiziert), Etappe 2 (alle zwoelf Bereiche gebunden, jeder einzeln -verifiziert), die drei vorgezogenen Datenbankregeln (260910-jab), WINDOWS #27 -(Relations-Blindstelle, 260911-mkj) und Etappe 3b (Benutzerdimension, -260911-nke) sind fertig und gepusht. Endstand 3b: Migration -`20260911120000_rls_user_dimension_personal_tables`, `current_user_id()`, -`forTenant(prisma, tenantId, userId?)`, zehn persoenliche Tabellen, 34 -Aufrufstellen in acht Diensten, 1020 Tests in 62 Dateien, `rls-scratch-check.mjs` -203/203, sechs Loch-Pruefungen umgedreht. - -**Der Umstellungsschalter ist AUS.** `DATABASE_URL` zeigt weiter auf die Rolle -`tessera` mit BYPASSRLS. Der User hat ausdruecklich verlangt, beim Scharfschalten -angehalten und gefragt zu werden. - - - - -- Etappe 1 — `forTenant()` repariert, Anmeldeweg ueber SECURITY-DEFINER-Funktionen, - 227 Zugriffe klassifiziert (`5228f28`). -- Etappe 2 — zwoelf Bereiche gebunden (ldap, groups, tenders, dkv, user, - module-registry, dashboard, calendar, tenant, auth, favorites, settings), - ueber zwoelf Quick-Tasks `260909-ipc` .. `260911-gwh` (`1240932`). -- Drei zu kurz greifende Datenbankregeln geschlossen, auf Anweisung des Users - vorgezogen (260910-jab, `03fb3bf`). -- WINDOWS #27 geschlossen — vierte Erkennungsform der Bestandsaufnahme, - 72 Paare, Restmenge als #33 eingetragen (260911-mkj, `388690f`). -- Etappe 3b — Benutzerdimension in den Regeln (260911-nke, `f0b531b`, `07fc653`, - `b62a905`, `3b08d8e`), verifiziert 13/13. - - - - -1. **Etappe 3c — Systemkontext fuer die Hintergrunddienste.** Sechs Faelle: - `dkv-scheduler` / `loadAnyActiveConfigForScheduler()` (WINDOWS #21, heute - bereits falsch — willkuerlicher Mandant), `mail.module` / - `loadAnySmtpConfigForStartupTransport()` (WINDOWS #30, dieselbe Form), - `ldap-config.service` `getAllActiveConfigs()`, `tender-digest.scheduler`, - `tender-matching.service`, `admin-seed.service` - `ensureDefaultGroupsForAllTenants`. Bauform: benannter Systemkontext - `forSystem(prisma)` mit dritter Sitzungsvariable `app.system_context`, - lesend erlaubt, Schreiben innerhalb der Schleife je Mandant gebunden. - **Braucht keine Entscheidung des Users — als naechstes empfohlen.** -2. **Etappe 3a — Anmeldenamen pro Mandant.** `@@unique([tenantId, username])` - und `@@unique([tenantId, email])` statt plattformweit, die drei - SECURITY-DEFINER-Funktionen bekommen `p_tenant_id`. Enthaelt **die eine - offene Produktfrage**: woran der Login den Mandanten erkennt — Subdomain je - Mandant (Empfehlung, weil Tessera hinter Nginx Proxy Manager laeuft) oder - Mandantenwahl im Anmeldeformular. Schliesst WINDOWS #22. -3. **Etappe 4 — Scharfschalten.** `rls-preflight.mjs` davor, dokumentierter - Rueckweg. NUR nach Rueckfrage beim User. WINDOWS #18. -4. **WINDOWS #29 — offene Rechteausweitung, unabhaengig von der - Mandantentrennung.** `adminResetPassword` verhindert ADMIN -> SUPER_ADMIN im - eigenen Handler (T-FH9-04), der Schwesterweg `PATCH /users/:id` - (`UserController.update`, T-02-08) prueft nur, ob die Rolle existiert. Das ist - der einzige offene Punkt, der nicht am Scharfschalten haengt, und der einzige - mit Sicherheitsbezug vor dem Live-Gehen. -5. **Phase 17 ist VERIFIED, aber `/gsd-ship` lief nie** — v1.2 ist formal nicht - geschlossen. Mit `windows_enforce` blockiert der Ship, solange - `open_count > 0` (aktuell 15). - -Von den 15 offenen WINDOWS-Eintraegen sind #25, #26, #28, #31, #32 Beschreibungen -der umgedrehten Fehlerrichtung je Bereich — sie werden erst mit dem Scharfschalten -(#18) akut und sind bewusst so abgelegt. #33 und #34 sind Luecken im Netz der -Bestandsaufnahme, nicht im Produkt. #21, #22, #24, #30 fallen mit 3a bzw. 3c. - - - - -- **Anmeldenamen pro Mandant eindeutig, nicht plattformweit** (User, 2026-09-10) — - `m.schmidt` darf es bei Firma A und Firma B geben. -- **Kollegen derselben Firma strikt getrennt** (User, 2026-09-10) — jeder sieht - nur seine eigenen gespeicherten Suchen, Favoriten, Dashboard-Anordnung. Mit - Etappe 3b in den Datenbankregeln verankert. -- **Anmeldeweg ueber SECURITY-DEFINER-Funktionen**, nicht ueber eine Policy: eine - Policy ist ein Zeilenpraedikat, jede Regel die eine Suche nach Benutzername - erlaubt, erlaubt das Lesen der ganzen Tabelle. Die Funktion pinnt die Ausnahme - auf feste Spaltenliste, Gleichheit und `LIMIT 1`. -- **Helfer erweitern statt zweiten bauen** — `forTenant()` bekam den optionalen - dritten Parameter statt eines `forTenantAndUser()`. -- **Am Active Directory wird nichts veraendert** (User, 2026-09-09, mit Nachdruck). -- **Datenverlust in der Datenbank ist derzeit hinnehmbar** (User, 2026-09-09): - nichts laeuft produktiv. Gilt nur, solange das so bleibt. -- **Beim Scharfschalten anhalten und fragen** (User, seit 2026-09-09) — die einzige - Ausnahme von "nicht nachfragen". - - - - -**Etappe 4 darf nicht vorgezogen werden.** Wird scharf geschaltet, bevor Etappe 3 -durch ist, liefern die noch nicht umgestellten Abfragen null Zeilen statt zu vieler. -Der gefaehrlichste Fall ist der Loeschzweig in `ldap.service.ts` (~Zeile 1559), der -Leere als "Gruppe im Verzeichnis verschwunden" deutet und samt Mitgliedschaften und -Modulfreigaben loescht. - -Keine offenen Handgriffe des Users. Der Server ist auf dem aktuellen Stand. -Keine laufenden Hintergrundauftraege (`.planning/async-jobs/` existiert nicht). - - -## Required Reading (in order) - -1. `docs/mandantentrennung-etappe3-auftrag.md` — der gemessene Auftrag fuer 3a/3b/3c; - 3b ist dort als erledigt vermerkt, der historische Auftragstext steht daneben -2. `.planning/STATE.md` — Position, Quick-Task-Tabelle mit allen Ergebnissen -3. `docs/mandantentrennung-zugriffsklassifikation.md` — die Arbeitsgrundlage -4. `docs/mandantentrennung-etappe2-fehlerrichtung.md` — Abschnitt "Regelschluss - Benutzerdimension (Etappe 3b, 260911-nke)" -5. `docs/mandantentrennung-datenbankrolle.md` — Befund, Sperrgrund, Handgriffe, Rueckweg -6. `.planning/WINDOWS.md` — 15 offen, davon #29 als einziger ohne Bezug zum Schalter -7. `apps/api/src/prisma/prisma-tenant.extension.ts` — der Helfer, dreistellig - -## Infrastructure State - -- **alpha** (192.168.13.12, https://alpha.tessera.ctl.de): Stand `ea003d4`, - Container am 2026-09-09 neu erstellt, `user-files` als Volume `tessera_user-files` - am api-Container nachgewiesen. **Live-Gehen am Dienstag, 2026-09-15** — braucht - den Schalter NICHT (ein Mandant, BYPASSRLS-Stand laeuft heute dort). -- **Die Serverdatei ist `docker-compose.prod.yml`**, nicht `docker-compose.yml` — die - `.env` setzt `COMPOSE_FILE`. Sicherungen als `.bak.20260909-0818` daneben. -- **git push** geht ausschliesslich ueber `localhost:3002`; die Push-URL des Remotes - ist dauerhaft darauf gesetzt, ein schlichtes `git push` genuegt. -- **Lokal**: `api`, `db` und `web` laufen; KEIN mailhog-Container, deshalb scheitert - der Mailversand lokal mit `ENOTFOUND mailhog` — umgebungsbedingt, kein Defekt. -- **Datenbank**: kein Host-Port. IP per `docker inspect` frisch ermitteln, - `tessera:tessera_dev`. Prisma-Binary aus `apps/api/node_modules/.bin/prisma`, - NICHT `npx prisma` (zieht Prisma 8). -- **Worktree-Isolation ist abgeschaltet** (`workflow.use_worktrees=false`), weil - `origin/HEAD` in diesem Repo nicht aufloesbar ist. - -## Pre-Execution Critique Required - -Vor jedem weiteren Bereich gilt die Frage aus Etappe 2 unveraendert: - -**Woran wuerde ich merken, dass eine umgestellte Abfrage jetzt zu WENIG liefert statt -zu viel?** Der Umbau dreht die Fehlerrichtung um. Der still gefaehrlichste Ort ist -jeder Code, der Leere als Abwesenheit deutet und daraufhin loescht. - - -Etappe 2 lief ueber zwoelf Quick-Tasks plus einen Regel-Durchlauf, jeder mit Planer, -Plan-Pruefer, Executor, Verifizierer. ZEHN Lieferungen wurden vom jeweils NAECHSTEN -Schritt gefangen, nie vom eigenen: vier geschrumpfte Zaehlungen, zwei nicht -committete Messungen, zwei Zusammenfassungen mit N statt N-1, uebersprungene -handgepflegte Dokumentstellen, Falsifizierungsnachweise nur in Commit-Nachrichten, -eine Wegwerf-Tabelle ohne `createdAt`/`updatedAt`, ein Selbstwiderspruch, ein Pruefer -der etwas als plausibel durchwinkte, ein still fehlgeschlagener `git add`, und zwei -Agenten die am Sitzungslimit NACH getaner Arbeit abbrachen. Die Kette vollstaendig zu -fahren ist deshalb keine Zeremonie, sondern das, was in dieser Arbeit tatsaechlich -Fehler gefangen hat. - -Verifizierer-Hinweis zu 3b (WINDOWS #34, angenommenes Risiko): die dreistelligen -`forTenant()`-Zusicherungen sind je Spec-Datei, nicht je Methode; das Gate "keine -zweistellige Form in den acht Dateien" ist ein Shell-Check, nicht CI. Wer das -schliessen will, baut den Check in `rls-access-inventory.spec.ts` ein. - -USER-ANWEISUNG 2026-09-11, weiter gueltig: "mach #27 und dann Etappe 3, nicht -nachfragen. du machst alles, was ohne mich geht. am dienstag geht eine voll -funktionsfaehige version live." Nach jedem Durchlauf pushen. - - - -1. `docs/mandantentrennung-etappe3-auftrag.md` lesen — 3b ist dort als erledigt vermerkt. -2. **Etappe 3c** (Systemkontext, sechs Hintergrunddienst-Faelle) als - `/gsd-quick --validate` — braucht keine Entscheidung des Users. -3. **WINDOWS #29** (`PATCH /users/:id` ohne Rollenausweitungs-Pruefung) — - kleiner, unabhaengiger Durchlauf, der einzige Sicherheitspunkt vor dem Live-Gehen. -4. **Etappe 3a** — enthaelt die eine offene Produktfrage (Subdomain vs. Login-Wahl). -5. **Etappe 4** — Scharfschalten. NUR nach Rueckfrage beim User. - diff --git a/.planning/HANDOFF.json b/.planning/HANDOFF.json deleted file mode 100644 index ceb0049..0000000 --- a/.planning/HANDOFF.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "version": "1.0", - "timestamp": "2026-09-14T08:02:29.277Z", - "phase": null, - "phase_name": "Mandantentrennung wirksam machen (Etappenarbeit ausserhalb der Phasen, ueber Quick-Tasks)", - "phase_dir": null, - "plan": null, - "task": null, - "total_tasks": 5, - "status": "paused", - "completed_tasks": [ - { - "id": 1, - "name": "Etappe 1 / forTenant() repariert, Anmeldeweg ueber SECURITY DEFINER, 227 Zugriffe klassifiziert", - "status": "done", - "commit": "5228f28" - }, - { - "id": 2, - "name": "Etappe 2 / alle zwoelf Bereiche gebunden, jeder einzeln verifiziert (260909-ipc .. 260911-gwh)", - "status": "done", - "commit": "1240932" - }, - { - "id": 3, - "name": "Auf Anweisung des Users vorgezogen: drei zu kurz greifende Datenbankregeln geschlossen (260910-jab)", - "status": "done", - "commit": "03fb3bf" - }, - { - "id": 4, - "name": "WINDOWS #27 geschlossen: vierte Erkennungsform, 72 Paare, #33 fuer die Rest-Empfaenger (260911-mkj)", - "status": "done", - "commit": "388690f" - }, - { - "id": 5, - "name": "Etappe 3b: Benutzerdimension — current_user_id(), forTenant() dreistellig, zehn Tabellen, 34 Aufrufstellen, sechs Pruefungen umgedreht (260911-nke, verifiziert 13/13)", - "status": "done", - "commit": "3b08d8e" - } - ], - "remaining_tasks": [ - { - "id": 6, - "name": "Etappe 3c: Systemkontext fuer die sechs Hintergrunddienst-Faelle (forSystem(), dritte Sitzungsvariable) — EMPFOHLEN ALS NAECHSTES, braucht keine Produktentscheidung; schliesst WINDOWS #21 und #30; siehe docs/mandantentrennung-etappe3-auftrag.md", - "status": "not_started" - }, - { - "id": 7, - "name": "WINDOWS #29: PATCH /users/:id (UserController.update) prueft die Rollenausweitung ADMIN -> SUPER_ADMIN nicht, der Schwesterweg adminResetPassword tut es. Unabhaengig vom Scharfschalten, einziger Sicherheitspunkt vor dem Live-Gehen", - "status": "not_started" - }, - { - "id": 8, - "name": "Etappe 3a: Anmeldenamen pro Mandant (@@unique([tenantId, username/email]), p_tenant_id in den drei SECURITY-DEFINER-Funktionen) — enthaelt DIE EINE offene Produktfrage: Subdomain je Mandant vs. Mandantenwahl im Login; fuer Dienstag nicht noetig", - "status": "not_started" - }, - { - "id": 9, - "name": "Etappe 4: Scharfschalten (DATABASE_URL auf eine Rolle ohne BYPASSRLS, rls-preflight.mjs davor) — USER WILL GEFRAGT WERDEN. Nicht noetig fuer das Live-Gehen am Dienstag 2026-09-15", - "status": "not_started" - }, - { - "id": 10, - "name": "Phase 17 ist VERIFIED, aber /gsd-ship lief nie — v1.2 formal nicht geschlossen; windows_enforce blockiert den Ship bei open_count 15", - "status": "not_started" - } - ], - "blockers": [ - { - "description": "Etappe 4 darf erst nach Etappe 3 laufen. Vorher liefern die nicht umgestellten Abfragen null Zeilen statt zu vieler; der Loeschzweig in ldap.service.ts (~1559) deutet Leere als 'Gruppe im Verzeichnis verschwunden' und loescht. Der User hat ausdruecklich verlangt, beim Scharfschalten angehalten und gefragt zu werden.", - "type": "process", - "workaround": "Reihenfolge einhalten: 3c, dann 3a, dann fragen" - } - ], - "async_jobs": [], - "human_actions_pending": [ - { - "action": "Produktentscheidung fuer Etappe 3a: woran der Login den Mandanten erkennt — eigene Subdomain je Mandant (Empfehlung) oder Mandantenwahl im Anmeldeformular", - "context": "Ohne diese Entscheidung laesst sich 3a nicht planen; mit einem Mandanten ist plattformweit = pro Mandant, deshalb fuer das Live-Gehen am 2026-09-15 nicht noetig", - "blocking": false - }, - { - "action": "Freigabe fuer Etappe 4 (Scharfschalten)", - "context": "Ausdrueckliche Anweisung des Users seit 2026-09-09", - "blocking": true - } - ], - "decisions": [ - { - "decision": "Anmeldenamen pro Mandant eindeutig, nicht plattformweit", - "rationale": "Produktentscheidung des Users am 2026-09-10 — m.schmidt darf es bei Firma A und B geben", - "phase": "Etappe 3" - }, - { - "decision": "Kollegen derselben Firma strikt getrennt — Benutzerdimension in die Datenbankregeln", - "rationale": "Produktentscheidung des Users am 2026-09-10; mit Etappe 3b umgesetzt", - "phase": "Etappe 3b" - }, - { - "decision": "Helfer erweitern statt zweiten bauen — forTenant(prisma, tenantId, userId?)", - "rationale": "Praezedenz withTenantTransaction(); Hintergrunddienste und Verwaltungswege rufen weiter zweistellig, die Regel traegt IS-NULL", - "phase": "260911-nke" - }, - { - "decision": "req.tenantPrisma entfernt, Middleware geloescht", - "rationale": "Bei jeder Anfrage gebaut, nirgends gelesen; Middleware war nirgends registriert", - "phase": "260911-e2s" - }, - { - "decision": "Datenbankregeln VOR Abschluss von Etappe 2 vorgezogen", - "rationale": "Ausdrueckliche Anweisung des Users am 2026-09-10 — offene Loecher werden vergessen", - "phase": "260910-jab" - }, - { - "decision": "Datenverlust in der Datenbank ist derzeit hinnehmbar", - "rationale": "User 2026-09-09: nichts laeuft produktiv. Gilt nur solange das so bleibt.", - "phase": "Etappe 4 (Vorgriff)" - } - ], - "uncommitted_files": [], - "next_action": "docs/mandantentrennung-etappe3-auftrag.md lesen. Etappe 3c (Systemkontext) als /gsd-quick --validate starten — braucht keine Entscheidung des Users. Danach WINDOWS #29, dann 3a. NICHT nachfragen ausser beim Scharfschalten.", - "context_notes": "Gemessen am 2026-09-14: git status --porcelain leer, main == origin/main, keine Datei juenger als der letzte Commit vom 2026-09-11 17:58 — es gibt KEINE angefangene Arbeit. Die Sitzung vom 11.09. lief nach Etappe 3b bei ~70% Kontext aus, der Handoff war geschrieben; dieser hier ist die Neuaufnahme desselben Standes plus zwei Punkte, die im alten fehlten (WINDOWS #29, nie gelaufener Ship von Phase 17). Verifizierer-Hinweis zu 3b: die dreistelligen forTenant()-Zusicherungen sind je Spec-Datei, nicht je Methode; das Gate 'keine zweistellige Form in den acht Dateien' ist ein Shell-Check, nicht CI (WINDOWS #34, angenommenes Risiko) — wer das schliessen will, baut den Check in rls-access-inventory.spec.ts ein. USER-ANWEISUNG 2026-09-11, weiter gueltig: 'mach #27 und dann Etappe 3, nicht nachfragen. du machst alles, was ohne mich geht. am dienstag geht eine voll funktionsfaehige version live.' Live-Gehen braucht den Schalter NICHT (ein Mandant, BYPASSRLS-Stand laeuft heute auf alpha); Etappe 3 darf es nicht blockieren. Nach jedem Durchlauf pushen. Etappe 2 lief ueber zwoelf Quick-Tasks plus einen Regel-Durchlauf, jeder mit Planer, Plan-Pruefer, Executor, Verifizierer: ZEHN Lieferungen wurden vom jeweils NAECHSTEN Schritt gefangen, nie vom eigenen — vier geschrumpfte Zaehlungen, zwei nicht committete Messungen, zwei Zusammenfassungen mit N statt N-1, uebersprungene handgepflegte Dokumentstellen, Falsifizierungsnachweise nur in Commit-Nachrichten, eine Wegwerf-Tabelle ohne createdAt/updatedAt, ein Selbstwiderspruch, ein Pruefer der etwas als plausibel durchwinkte, ein still fehlgeschlagener git add, und zwei Agenten die am Sitzungslimit NACH getaner Arbeit abbrachen. Die Placeholder-Suche ueber .planning/phases/ meldet 53 Treffer, alle geprueft: es sind Prosa-Stellen, die Debt-Marker BESCHREIBEN (z.B. 17-VERIFICATION.md Zeile 135), keine unfertigen Zusammenfassungen." -} diff --git a/.planning/STATE.md b/.planning/STATE.md index 0a9d72c..0927379 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -5,7 +5,7 @@ current_phase: 17 current_phase_name: eigene-ausschreibungs-quellen-je-nutzer status: verified stopped_at: "Quick 260911-nke abgeschlossen: Etappe 3b Benutzerdimension — Migration 20260911120000, forTenant() mit userId, 34 Aufrufstellen, 203/203 Werkzeugpruefungen, sechs Loch-Pruefungen umgedreht, gepusht" -last_updated: "2026-09-11T15:49:27.138Z" +last_updated: "2026-09-14T08:18:04.000Z" last_activity: 2026-09-10 last_activity_desc: Quick 260910-jab — drei zu kurz greifende RLS-Regeln geschlossen (GroupMembership beide Seiten, ModuleGrant beide Ziele, TenderRssFeedSource Lese-/Schreibsplit), listForUser gebunden, Aktenstand kohaerent state_head: b62a905adb19f8c68eba45e66f2290ed978c2239 @@ -435,8 +435,8 @@ sind. Kein Anlass, sie vorher erneut vorzulegen. ## Session Continuity -Last session: 2026-09-11T15:49:18.581Z -Resumed: 2026-09-09 — Sitzung ueber /gsd-resume-work fortgesetzt; Einstiegspunkt Etappe 2 (Bereich ldap), Auswahl des Nutzers steht aus. +Last session: 2026-09-14T08:18:04.000Z +Resumed: 2026-09-14 — Sitzung ueber /gsd-resume-work fortgesetzt; HANDOFF.json und .continue-here.md verbraucht und entfernt. Entscheidung des Users: WINDOWS #29 VOR Etappe 3c (Live-Gehen am 2026-09-15), danach 3c, dann 3a, Etappe 4 nur nach Rueckfrage. Stopped at: **ETAPPE 2 KOMPLETT, WINDOWS #27 GESCHLOSSEN, ETAPPE 3b (BENUTZERDIMENSION) KOMPLETT — 2026-09-11.** Endstand 1020 Tests / 62 Dateien, 203 Live-Pruefungen, 72 Paare in der Klassifikation, Ledger 15 offen von 34. Alles gepusht, Arbeitsbaum sauber. DER SCHALTER IST AUS. **User-Anweisung 2026-09-11: 'mach #27 und dann Etappe 3, nicht nachfragen. am dienstag [2026-09-15] geht eine voll funktionsfaehige version live.'** Live-Gehen braucht den Schalter NICHT (ein Mandant, BYPASSRLS-Stand laeuft heute auf alpha). OFFEN: **Etappe 3a** (Anmeldenamen pro Mandant — Schema `@@unique([tenantId, username/email])`, Anmeldeweg muss den Mandanten VOR der Suche kennen, SECURITY-DEFINER-Funktionen mit zweiter Gleichheitsbedingung; enthaelt EINE Produktfrage an den User: Mandant per Subdomain (Empfehlung) oder Login-Wahl; fuer Dienstag NICHT noetig, da ein Mandant) und **Etappe 3c** (Systemkontext `app.system_context` fuer die sechs Hintergrunddienst-Faelle #21/#30 und die vier beides-Uebergaben; macht DKV- und SMTP-Startpfad zu einmal-abfragen-viele-bedienen). VOLLSTAENDIGER AUFTRAG: docs/mandantentrennung-etappe3-auftrag.md (3b dort als 'Erledigt' vermerkt). Danach Etappe 4 Scharfschalten mit rls-preflight.mjs — DER USER WILL DORT GEFRAGT WERDEN. Die Sitzung vom 2026-09-11 endete bei ~70% Kontext nach 3b; Einstieg `/gsd-resume-work`, dann 3c oder 3a als `/gsd-quick --validate` mit vollstaendiger Kette (Planer, Pruefer, Executor, Verifizierer). Resume file: None Last activity: 2026-09-10 - Completed quick task 260910-jab: Die drei zu kurz greifenden Datenbankregeln (T-JTS-02, T-JTS-03, WINDOWS #19) geschlossen