Files
claude-wuerth-plato/memory/project_cleanup_timeline.md
2026-07-09 09:21:42 +02:00

58 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: project-cleanup-timeline
description: Cleanup-Sprint plato-customer Mai 2026 — Status nach BFF-Umbau und nächste Themen (User-DB, Postgres).
metadata:
node_type: memory
type: project
originSessionId: 9259f85f-e34d-4327-89e2-534bbfbc48c2
---
10-PT-Aufräum-Sprint auf `development`. Linie: [[feedback-priorisierung]].
**Status Ende 2026-05-22 (Fr):**
- ✅ Storage-Layout (Subdirs + `.crypt`) + AES → Base64 (`94d19a5`)
- ✅ Auto-Migration `plato5/crm.sqlite` bei Init (`ee57b86`)
- ✅ IdP-Anbindung verifiziert (siehe [[project-idp-witglobal]])
-**Auth-Umbau auf BFF abgeschlossen** (`00e2c37` "activate odic login" + weitere Commits): Dummy-JWT raus, `passport-jwt`+`jwks-rsa` raus, `openid-client`+`express-session` rein, `client_secret` server-seitig (nicht mehr im Browser), Session-Cookie-basiert. Siehe [[project-idp-witglobal]] und [[project-run-commands]].
- ✅ User `ex08802409` in `user.json` ergänzt (provisorisch, ohne echten Datensatz)
- ⏳ Test-Rig `scripts/oidc-test.mjs` uncommitted (separater Scope, war Pre-BFF-Verifikation)
**Nächste Themen (am 2026-05-22 angerissen, Implementierung steht aus):**
- **User-DB**: aktuell statisch aus `user.json` via `UserRegistry` (Konstruktor `readFileSync`). Soll eine richtige DB werden — Marcus hat das explizit als nächstes Thema benannt nachdem die User-Mapping-Lücke beim Login auffiel.
- **Kunden-Persistenz: SQLite → Postgres**: aktuell SQLite via TypeORM in `data/customer.db` (PVC-mounted im Container). Bedeutet Single-Pod, kein Rolling-Deploy. Plan: separater Postgres-Pod (StatefulSet, im Gitops-Repo zu definieren), TypeORM-DataSource auf `postgres` umstellen, Migrations neu generieren, lokal Compose o.ä. — kein Managed-Service bei Würth (außer SQL Server).
- **Infrastruktur-Repo** existiert ("haben wir") — noch nicht im Detail angeschaut.
**Plan 2026-05-26 (Di) — "alles fertig":**
- Übergabe an Kollegen zum Testen
- Test-Automatisierung
- QS-Übergabe
- **Blocker für Auth-Rollout**: Windows-Kollege braucht funktionierenden Weg zum IdP. Solange nicht geklärt, kann der BFF-Stand nicht "scharf" für ihn werden — er kommt sonst nicht in die App.
**Stand 2026-05-27 (Mi) — Deployment-Cleanup-Runde (siehe Commits `f6d7b6d`, `acafac5`, `b6856e9`):**
- ✅ OIDC_CLIENT_SECRET + SESSION_SECRET aus Image, via Sealed-Secret im GitOps-Repo (`plato-customer-secrets`), `envFrom` im Deployment-Patch `backend.yaml`
-`trust proxy` für Session-Cookies hinter OCP-Router
- ✅ Proxy-ENVs (`HTTPS_PROXY` etc.) aus Image, in Deployment-`env:`-Block; undici-`ProxyAgent` für Node-22-fetch
- ✅ Fail-Fast in `main.ts` und `oidc.service.ts` wenn Secrets fehlen (Crash statt stille Dev-Fallbacks)
- ✅ Alte GHCR-Versionen mit eingebackenem Secret gelöscht (manuell via Web-UI), aktuelle Version 0.3.0
- ⏸️ Session-Store-Umzug (MemoryStore → Redis) verschoben: replicas=1, kein akuter Bedarf, kein Redis im Namespace deploybar
**Plan 2026-05-28 (Do) — umgestellt:**
- **Vormittag (statt Postgres-Backbone):** Migration + Import-Handling. Postgres-Backbone wurde verschoben. Code-Bereich: `apps/plato-customer-be/src/migration/` (Controller `/import/sqlite` + `/import/excel`, `SqliteImportService`/`MsExcelImportService`, `CustomerRehydrator`, `DuplicateFinderUtils`, SQL-Selects, `SQliteDb`); shared `xlImport2Customer`+`excel2json`; FE `migrationUploadClient` + `legacyMigration` (`./plato5/crm.sqlite`). Import liefert nur `MigrationCheck` (Vorschau, BE persistiert nicht selbst — Persistenz FE über `persistentStorage`/Outbox bzw. `CustomerCoreService.createOrUpdateList`).
- Offene Schwachstellen im Import (28.05. analysiert): (1) `DuplicateFinderUtils.fuzzyFinds` (Kunden ohne customer_number) wird gesammelt aber nie ins Ergebnis/Report übernommen; `getByCustomerFuzzy` existiert im Core-Service, wird aber nicht aufgerufen — angefangenes Feature. (2) `SQliteDb.executeSelect` als `Promise<string>` typisiert, liefert aber Row-Array. (3) Import schreibt nichts BE-seitig.
- **Architektur-Klarstellung Marcus (28.05.):** SQLite-Migration ist ein EINMALIGER Prozess beim ersten App-Start — `main.js` Boot-Schritt 5.5 ruft `legacyMigration.migrateIfPresent()` nur `if (manifest.created)` (Cache-Verzeichnis frisch). Ab dann wird mit SAP-Daten gearbeitet. Die manuellen Header-Buttons `⇆ SQLite`/`⇆ Excel` (`CustomerHeaderActions.vue`) widersprechen dem → auf Marcus' Wunsch **disabled** (nicht gelöscht, reaktivierbar). Wie es mit dem Import-Pfad weitergeht, will Marcus noch besprechen.
- **SAP-Einzel-Flow umgebaut (28.05., erledigt, typecheck grün):** SAP-Nummer ist führend, Eingabe über `SapImportDialog` (bleibt). `CustomerStore.fetchFromSap` sucht lokal nach `customer_number`; gefunden → hart aus SAP überschreiben (8 Stammdaten-Felder, Identität bleibt), nicht gefunden → neu anlegen. Verdrängte alte Email → geretteter Kontakt (`overwriteWithSap` + `guessNameFromEmail` in `sap-adapter.ts`), Name aus Email-Local-Part geraten, Match per Email. Bestehende Kontakte/Adressen bleiben beim Überschreiben erhalten; SAP-Partner-Kontakt/-Adresse kommen nur bei Neuanlage rein.
- **SAP-Mock ins BE integriert (28.05., erledigt, typecheck grün) — Variante B, bewusst Notlösung & komplett removable:** Marcus' Vorgabe war „muss ohne großes Aufhebens vollständig rausnehmbar sein". Neues self-contained Modul `apps/plato-customer-be/src/sap-mock/` (Controller `@Get('CustomerSet')`, Service liest `crm.sqlite` via `better-sqlite3`, Query/XML 1:1 aus altem Express-Mock portiert). In `app.module.ts` **flag-gegatet** via `SAP_MOCK_ENABLED=true`. Dockerfile bekommt eine `COPY apps/sap-mock/crm.sqlite`-Zeile (30 MB). Begründung B statt eigenem Pod: SAP-Call kommt aus dem Browser (`sapClient``VITE_SAP_URL`), eigener Pod bräuchte Route+HTTPS+CORS+FE-Build-URL; B = ein Deployment, same-origin. **Rausnehmen** = Ordner löschen + 2 Zeilen in app.module.ts + COPY-Zeile + `VITE_SAP_URL` aufs echte SAP. Standalone `apps/sap-mock/` bleibt unangetastet (Quelle der crm.sqlite).
- **SAP-Mock Container-Build + Runtime VERIFIZIERT (28.05., podman):** `better-sqlite3` baut auf `node:22-alpine` ohne Build-Tools (prebuilt musl-binary), Modul wird vom nx-Webpack externalisiert, Image ~853 MB. Container bootet mit `SAP_MOCK_ENABLED=true` + Dummy-`OIDC_CLIENT_SECRET`/`SESSION_SECRET` (OIDC-Discovery-Fehler crasht NICHT). `/CustomerSet` liefert OData-XML aus `/app/apps/sap-mock/crm.sqlite`. Lokal: `docker` nicht da (kein Daemon) → `podman` nutzen.
- **SAP-Mock Query an neuen Flow angepasst (28.05.):** Lookup jetzt per `customer_number` (war interne `customer_id`) — die SAP-Nummer ist führend, und der FE-Adapter mappt `d:CustomerID``customer_number`, also gibt der Query auch `cu.customer_number as CustomerID` aus. Contacts/Addresses-Joins von `INNER` auf `LEFT OUTER` umgestellt, damit auch Kunden ohne Kontakt/Adresse auflösen (404 nur noch bei unbekannter Nummer). **OFFEN (Marcus klärt):** `CustomerToplevelNumber` = `customer_number` (→ FE `verband_nummer` = Kundennummer), weil Legacy-DB keine eigene Verband-Spalte hat — evtl. auf leer setzen.
- **Postgres-Backbone — am 2026-05-28 abend LIVE auf DEV gebracht (war "verschoben"):** Zweiter Pod `plato-postgres` im GitOps-Repo (`base/postgres.yaml`: Deployment RHEL-Image `registry.redhat.io/rhel9/postgresql-16` + ClusterIP-Service `plato-postgres:5432`, KEINE Route). Creds via Sealed-Secret `plato-postgres-secrets` (User `plato_admin`, DB `Plato`). **Bewusst OHNE PVC = ephemer** (Daten weg bei Restart). Backend-DataSource umschaltbar gemacht (`DB_TYPE=postgres``pg`, sonst sqlite-Default), `synchronize:true` für Postgres (keine PG-Migrations, da eh ephemer). Im DEV-Backend-Deployment via `envFrom plato-postgres-secrets` + `DB_TYPE=postgres` aktiviert. Verifiziert: Pod 0.6.1 Running, mit Postgres verbunden, Tabellen (customer/contact/address/contact_addresses) per synchronize angelegt, DB leer. **Stolperstein gefixt:** Entities hatten hartes `type:'datetime'` (SQLite-only) → auf Dialekt-Default umgestellt (kein Typ bei `@CreateDateColumn`/`@UpdateDateColumn`), sonst `DataTypeNotSupportedError` auf Postgres. Namespace `1401-plato-development`, RedHat-Image pullt im Cluster.
- **PVC konfiguriert (2026-05-28 abend):** StorageClass-Frage geklärt — Plattform-Team: PVC selbst als K8s-Objekt anlegen, CSI-Treiber legt PV automatisch an; **thin-csi** = Default/OLTP (für DB), trident-nas nur für File-RWX. In `base/postgres.yaml` ergänzt: PVC `plato-postgres-data` (thin-csi, RWO, **50Gi** — Marcus' Wahl quota-sparsam: 400 Nutzer × 50MB ≈ 20GB Rohdaten + DB-Overhead; nicht die beantragten 100GB), gemountet an `/var/lib/pgsql/data`, dazu `strategy: Recreate` (sonst RWO-Mount-Deadlock beim Redeploy). Kustomize-Build grün. **Noch nicht committet/deployed** (Stand Reden). `data/customer.db` bleibt uncommitted, sqlite-Daten werden NICHT nach Postgres migriert (leerer Start gewollt).
- **synchronize → PG-Migrations umgestellt (2026-05-28, Weg „B" hand-portiert):** Marcus' Entscheidung — `synchronize` raus, weil mit PVC persistent; „wenn der Pod dann deterministisch crasht, ist offensichtlich was an der Migration falsch" (Crash+Log = Diagnose, [[feedback-keine-zwischenstufen]]). Befund: die einzige bestehende Migration ist rein SQLite (`datetime`, Temp-Table-Tanz) → läuft auf PG nie. Daher neue PG-Migration `libs/customer/customer-be/src/lib/db/1780000000000-…-customer-pg-migration.js` hand-portiert aus den Entities (uuid-PK `gen_random_uuid()`, `TIMESTAMP/now()`, FKs per ALTER, Constraint-/Index-Namen 1:1 aus M000). `customer-data-source.ts`: Postgres `synchronize:false` + eigener Glob `*customer-pg-migration.js` (disjunkt vom SQLite-Glob `*customer-migration.js`). Asset-Copy (`apps/plato-customer-be/project.json`: `**/db/**/*migration.js`) erfasst beide; Prod-Build verifiziert, beide JS landen in dist, Globs trennen sauber. Deploy-Hinweis: Backend gegen ALTEN synchronize-Pod → `CREATE TABLE … already exists`; gitops-PVC-Change zuerst deployen (Pod neu = leeres PVC), dann läuft Migration clean.
- **Migrations-Features angefragt (2026-05-28, noch offen, Rückfragen unbeantwortet):** (1) Bei Import zusätzlich per `customer_number` prüfen ob Kunde existiert → wenn ja, "aus SAP updaten" und an Client zurückgeben (offen: BE-seitig SAP-Mock rufen + sap-adapter-Logik BE-portieren, oder FE macht `fetchFromSap`?). (2) Neuer FE-Dialog: aus ALLEN Kunden (`CustomerCoreService.findAll` aus Postgres) auswählen, welche in den lokalen Stand geladen werden.
**Plan 2026-05-29 (Fr):**
- **Outbox / Inflight / BadBox** Pattern + eine weitere Sync-Schnittstelle. Marcus will erst "genau anschauen" bevor implementiert wird.
**Why:** Marcus hat den Sprint explizit als "10 PT" geframet mit Test-/QS-Übergabe Di 26.05.2026.
**How to apply:** Wenn am Montag/Dienstag oder später eine neue Session startet, hier reinschauen für aktuellen Stand, statt aus git log zu rekonstruieren. Beim Aufgreifen der User-DB oder Postgres-Themen: Marcus wollte beide Sachen aufgreifen, hatte aber explizit das Postgres-Thema vor sich her geschoben (Kunden-DB zuerst). Reihenfolge mit ihm abklären.