11 KiB
name, description, metadata
| name | description | metadata | ||||||
|---|---|---|---|---|---|---|---|---|
| project-cleanup-timeline | Cleanup-Sprint plato-customer Mai 2026 — Status nach BFF-Umbau und nächste Themen (User-DB, Postgres). |
|
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.sqlitebei 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-rsaraus,openid-client+express-sessionrein,client_secretserver-seitig (nicht mehr im Browser), Session-Cookie-basiert. Siehe project-idp-witglobal und project-run-commands. - ✅ User
ex08802409inuser.jsonergänzt (provisorisch, ohne echten Datensatz) - ⏳ Test-Rig
scripts/oidc-test.mjsuncommitted (separater Scope, war Pre-BFF-Verifikation)
Nächste Themen (am 2026-05-22 angerissen, Implementierung steht aus):
- User-DB: aktuell statisch aus
user.jsonviaUserRegistry(KonstruktorreadFileSync). 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 aufpostgresumstellen, 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),envFromim Deployment-Patchbackend.yaml - ✅
trust proxyfür Session-Cookies hinter OCP-Router - ✅ Proxy-ENVs (
HTTPS_PROXYetc.) aus Image, in Deployment-env:-Block; undici-ProxyAgentfür Node-22-fetch - ✅ Fail-Fast in
main.tsundoidc.service.tswenn 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); sharedxlImport2Customer+excel2json; FEmigrationUploadClient+legacyMigration(./plato5/crm.sqlite). Import liefert nurMigrationCheck(Vorschau, BE persistiert nicht selbst — Persistenz FE überpersistentStorage/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;getByCustomerFuzzyexistiert im Core-Service, wird aber nicht aufgerufen — angefangenes Feature. (2)SQliteDb.executeSelectalsPromise<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.jsBoot-Schritt 5.5 ruftlegacyMigration.migrateIfPresent()nurif (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.fetchFromSapsucht lokal nachcustomer_number; gefunden → hart aus SAP überschreiben (8 Stammdaten-Felder, Identität bleibt), nicht gefunden → neu anlegen. Verdrängte alte Email → geretteter Kontakt (overwriteWithSap+guessNameFromEmailinsap-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 liestcrm.sqliteviabetter-sqlite3, Query/XML 1:1 aus altem Express-Mock portiert). Inapp.module.tsflag-gegatet viaSAP_MOCK_ENABLED=true. Dockerfile bekommt eineCOPY 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_URLaufs echte SAP. Standaloneapps/sap-mock/bleibt unangetastet (Quelle der crm.sqlite). - SAP-Mock Container-Build + Runtime VERIFIZIERT (28.05., podman):
better-sqlite3baut aufnode:22-alpineohne Build-Tools (prebuilt musl-binary), Modul wird vom nx-Webpack externalisiert, Image ~853 MB. Container bootet mitSAP_MOCK_ENABLED=true+ Dummy-OIDC_CLIENT_SECRET/SESSION_SECRET(OIDC-Discovery-Fehler crasht NICHT)./CustomerSetliefert OData-XML aus/app/apps/sap-mock/crm.sqlite. Lokal:dockernicht da (kein Daemon) →podmannutzen. - SAP-Mock Query an neuen Flow angepasst (28.05.): Lookup jetzt per
customer_number(war internecustomer_id) — die SAP-Nummer ist führend, und der FE-Adapter mapptd:CustomerID→customer_number, also gibt der Query auchcu.customer_number as CustomerIDaus. Contacts/Addresses-Joins vonINNERaufLEFT OUTERumgestellt, damit auch Kunden ohne Kontakt/Adresse auflösen (404 nur noch bei unbekannter Nummer). OFFEN (Marcus klärt):CustomerToplevelNumber=customer_number(→ FEverband_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-postgresim GitOps-Repo (base/postgres.yaml: Deployment RHEL-Imageregistry.redhat.io/rhel9/postgresql-16+ ClusterIP-Serviceplato-postgres:5432, KEINE Route). Creds via Sealed-Secretplato-postgres-secrets(Userplato_admin, DBPlato). Bewusst OHNE PVC = ephemer (Daten weg bei Restart). Backend-DataSource umschaltbar gemacht (DB_TYPE=postgres→pg, sonst sqlite-Default),synchronize:truefür Postgres (keine PG-Migrations, da eh ephemer). Im DEV-Backend-Deployment viaenvFrom plato-postgres-secrets+DB_TYPE=postgresaktiviert. Verifiziert: Pod 0.6.1 Running, mit Postgres verbunden, Tabellen (customer/contact/address/contact_addresses) per synchronize angelegt, DB leer. Stolperstein gefixt: Entities hatten hartestype:'datetime'(SQLite-only) → auf Dialekt-Default umgestellt (kein Typ bei@CreateDateColumn/@UpdateDateColumn), sonstDataTypeNotSupportedErrorauf Postgres. Namespace1401-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.yamlergänzt: PVCplato-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, dazustrategy: Recreate(sonst RWO-Mount-Deadlock beim Redeploy). Kustomize-Build grün. Noch nicht committet/deployed (Stand Reden).data/customer.dbbleibt uncommitted, sqlite-Daten werden NICHT nach Postgres migriert (leerer Start gewollt). - synchronize → PG-Migrations umgestellt (2026-05-28, Weg „B" hand-portiert): Marcus' Entscheidung —
synchronizeraus, 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-Migrationlibs/customer/customer-be/src/lib/db/1780000000000-…-customer-pg-migration.jshand-portiert aus den Entities (uuid-PKgen_random_uuid(),TIMESTAMP/now(), FKs per ALTER, Constraint-/Index-Namen 1:1 aus M000).customer-data-source.ts: Postgressynchronize: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_numberprü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 machtfetchFromSap?). (2) Neuer FE-Dialog: aus ALLEN Kunden (CustomerCoreService.findAllaus 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.