feat(crm): end_customers table, RLS, wizard customer selector, /my-customers CRUD, GDPR anonymization
This commit is contained in:
@@ -9,6 +9,7 @@ import type {
|
||||
Category,
|
||||
CategorySelection,
|
||||
CustomerSnapshot,
|
||||
EndCustomer,
|
||||
LicenseBundle,
|
||||
LicenseOption,
|
||||
OrderItem,
|
||||
@@ -37,10 +38,28 @@ export function slugify(name: string): string {
|
||||
|
||||
/**
|
||||
* Baut einen validen CustomerSnapshot aus einem Profil oder Formulardaten.
|
||||
* Fehlende Pflichtfelder werden mit leerem String aufgefüllt (kein throw –
|
||||
* Validierung findet im Wizard-UI statt).
|
||||
*
|
||||
* Wenn ein Endkunde übergeben wird, werden DESSEN Daten eingefroren (für die Rechnung).
|
||||
* Ohne Endkunden-Übergabe: Partner-Profil als Fallback (Abwärtskompatibilität).
|
||||
* Fehlende Pflichtfelder werden mit leerem String aufgefüllt (Validierung im Wizard).
|
||||
*/
|
||||
export function buildCustomerSnapshot(profile: Partial<Profile>): CustomerSnapshot {
|
||||
export function buildCustomerSnapshot(
|
||||
profile: Partial<Profile>,
|
||||
endCustomer?: EndCustomer | null
|
||||
): CustomerSnapshot {
|
||||
if (endCustomer) {
|
||||
return {
|
||||
schema_version: 1,
|
||||
end_customer_id: endCustomer.id,
|
||||
company_name: endCustomer.company_name ?? '',
|
||||
vat_id: endCustomer.vat_id ?? '',
|
||||
first_name: endCustomer.first_name ?? '',
|
||||
last_name: endCustomer.last_name ?? '',
|
||||
address: endCustomer.street ?? '',
|
||||
zip_code: endCustomer.zip ?? '',
|
||||
city: endCustomer.city ?? '',
|
||||
}
|
||||
}
|
||||
return {
|
||||
schema_version: 1,
|
||||
company_name: profile.company_name ?? '',
|
||||
|
||||
Reference in New Issue
Block a user