Initial commit
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
---
|
||||
name: project_kontakt_adress_spec
|
||||
description: "Geplante Spec Kontakte/Adressen — SAP-Schutz, Validierung-bei-Änderung, M:N-Removal (noch NICHT implementiert)"
|
||||
metadata:
|
||||
node_type: memory
|
||||
type: project
|
||||
originSessionId: 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]].
|
||||
Reference in New Issue
Block a user