Darstellung
03 – Kontakte / CRM
Reifegrad: 🟢 produktiv · Schicht: kontakte-Tabelle, @work7/domain (Customer-Funktionen), src/app/kontakte/*, src/app/api/kontakte/*, src/components/kontakte/*
Zweck
Zentrale Verwaltung von Geschäftspartnern: Personen und Organisationen mit n:m-Verknüpfung (Ansprechpartner einer Firma), inkl. Adress-, Steuer- und Zahlungsdaten.
Datenmodell
Migration 035 hat customers → kontakte umbenannt und ein Person/Organisation-Modell eingeführt (siehe adr-0005-kontakte-person-organisation).
kontakte:- Typdiskriminator
kind∈ {person,organisation} (NOT NULL, Defaultorganisation). - Person-Felder:
salutation,title,first_name,last_name,name_suffix. - Organisations-Felder:
legal_form,commercial_register. - Adresse:
street,house_number,postal_code,city,state,country. - Kontakt:
email,phone,mobile,website. - Steuer/Zahlung:
vat_number,tax_number,default_vat_rate,payment_term_days,skonto_days,skonto_percent,iban,bic. - CRM-Meta:
customer_number(auto,UNIQUE (company_id, customer_number)),status(DefaultInteressent),customer_group,tags TEXT[],source,birthday,last_interaction_at,preferred_language,notes(JSONB-Array seit Migration 038).
- Typdiskriminator
organisation_personen– n:m zwischen Organisation und Person mitrole/position.- Alte Textfelder
contact_personundpositionwurden verworfen (Position wandert in die Verknüpfung).
Domain-Funktionen (@work7/domain)
listCustomers, searchCustomers, getCustomer, countCustomers, createCustomer, updateCustomer, deleteCustomer sowie die Verknüpfungs-Funktionen linkPersonToOrganisation, listPersonsForOrganisation, listOrganisationsForPerson, unlinkPerson. Alle sind Tenancy-gescoped und als Domain-Tools auch für den WhatsApp-Agent verfügbar.
API-Endpunkte
| Endpoint | Funktion |
|---|---|
GET/POST /api/kontakte | Liste (mit Suche/Pagination) / anlegen |
GET/PUT/DELETE /api/kontakte/[id] | Detail / ändern / löschen |
GET/POST/DELETE /api/kontakte/[id]/personen | Ansprechpartner einer Organisation verwalten |
POST /api/kontakte/extract-impressum | Firmendaten aus Website-Impressum extrahieren (Firecrawl/AI) |
UI
/kontakte(Liste mit Filter/Suche),/kontakte/new(Anlage),/kontakte/[id](Detail mit verknüpften Personen, Projekten, Dokumenten).- Komponenten in
src/components/kontakte/*; Adress-Autocomplete viasrc/components/address/*/api/geo/address-autocomplete(Google Places, siehe 13-integrationen-google-microsoft-storage).
Besonderheiten
- Impressum-Extraktion:
kontakte/extract-impressumzieht über Firecrawl (src/lib/firecrawl/client.ts) + AI strukturierte Firmendaten aus einer Website-URL – beschleunigt die Neuanlage von Organisationen. kontakt_idersetzt in referenzierenden Tabellen das altecustomer_id(Migration 035 hat FKs umgestellt; dieinvoice_summary-View nutzt nunkontakt_id).
Bekannte Befunde / offene Punkte
- In Code/DB existieren historisch beide Begriffe (
customer*in@work7/domain-Funktionsnamen,kontaktein der DB). Funktion ist korrekt, Namensgebung ist gemischt – bei Refactorings aufkontaktvereinheitlichen. customer_counters+ Triggerset_customer_numberstammen aus dem Ur-Schema und vergeben weiterhin die Nummern.