Files
claude-projects/wuerth-plato/memory/project_kontakt_adress_spec.md
T

3.2 KiB

name, description, metadata
name description metadata
project_kontakt_adress_spec Geplante Spec Kontakte/Adressen — SAP-Schutz, Validierung-bei-Änderung, M:N-Removal (noch NICHT implementiert)
node_type type originSessionId
memory project 9ea3a233-d124-48d2-bcbd-df83326a7e21

Soll-Funktionen für Kontakte/Adressen, am 2026-06-09 mit Marcus festgeklopft und im Wesentlichen UMGESETZT auf development: 282698f Relation-Removal, f423c8f Server-Guard, 5473a2b FE-Anrede-Pflicht, 140c09f Delete-Integrationstest (Kaskade+SAP-Block), 2b16384 Orphan-Delete-Fix+Test (createOrUpdate mergte Collections falsch -> Einzel-Löschen verpuffte; jetzt Skalare mergen, Kind-Arrays explizit setzen wie batchImport). OFFEN nur noch: deleteAll auf eigenem Branch entfernen (s.u.); MS-EXCEL-vs-Mehrgesellschaften vertagt. Commits noch ungepusht (Push macht Marcus).

Adressen NUR auf Kundenebene. Kontakt↔Adresse-M:N (contact_addresses, JoinTable auf Contact-Seite) wird ENTFERNT — toter Code, nie befüllt, auch in Alt-DB _contacts2addresses = 0 Einträge. Evtl. später wieder (geringer Aufwand); dann ist offen, wie eine Adresse bei Kontakt-Neuanlage zugeordnet wird. Removal braucht Entity-Edits + TypeORM-Migration; bringt die latente addressId ON DELETE NO ACTION-Falle weg.

SAP-Schutz (origin === 'SAP' = read-only, „aus SAP hinterfragen wir gar nichts"):

  • UI schützt schon: canEditCustomer (CustomerDetails.vue:163), canEditItem (useCardListManageer.ts:49) — disabled Edit+Delete für Nicht-PlaTo/Excel.
  • Server hat KEINEN Guard (nur enforceOwnership für owner_country). Zu bauen: enforceSapProtection in CustomerCoreService.createOrUpdate (NICHT in batchImport — das ist die Migration), Delete-Guard in delete() (SAP-Kunde nicht löschbar).
  • origin der Kinder aus DB-Stand ableiten (by id), nicht aus Payload — sonst spooft FE origin: 'PlaTo'. SAP-Kind verändert/fehlend → Reject.

Cascade: Plato-Kunde löschen → Kontakte+Adressen mit (existiert via OneToMany cascade/orphanedRowAction, nichts zu tun). deleteAll()/customer.delete.list ist reines Test-Werkzeug → auf PROD raus/nicht erreichbar, KEIN Guard nötig.

Contact-Felder (ALLE bleiben): contact_type, form(=Anrede), title, firstname, lastname, fullname, position, department, phone, mobile, fax, mail, website, contact_number, comment. addresses RAUS.

  • fullname wird abgeleitet = firstname + " " + lastname, nicht editierbar (heute freies Feld CustomerContacts.vue:39).

Validierung:

  • Pflicht = Anrede(form)/firstname/lastname/mail. Keine DB-NOT-NULL, nur Validierungslayer.
  • Greift NUR für origin PlaTo. SAP nie. MS EXCEL = vorerst PlaTo (Mehrgesellschaften später klären).
  • PlaTo entsteht auch beim SAP-Import (Rettungskontakt aus abweichender Mail, guessNameFromEmail) → u.U. unvollständig. Daher: Pflicht NICHT bei Anlage, sondern erst bei ÄNDERUNG erzwingen — nur neue (FE) oder ggü. DB veränderte Kontakte prüfen.
  • „Verändert" = gleicher Diff wie SAP-Guard, via contactProjection/addressProjection aus content-hash (eine Wahrheit).

Beispiel-Stores (Klartext) für Tests: ressources/outbox.v1.json, ressources/inflight.v1.json. Siehe auch project_naechste_schritte.