Skip to content

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 customerskontakte umbenannt und ein Person/Organisation-Modell eingeführt (siehe adr-0005-kontakte-person-organisation).

  • kontakte:
    • Typdiskriminator kind ∈ {person, organisation} (NOT NULL, Default organisation).
    • 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 (Default Interessent), customer_group, tags TEXT[], source, birthday, last_interaction_at, preferred_language, notes (JSONB-Array seit Migration 038).
  • organisation_personen – n:m zwischen Organisation und Person mit role/position.
  • Alte Textfelder contact_person und position wurden 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

EndpointFunktion
GET/POST /api/kontakteListe (mit Suche/Pagination) / anlegen
GET/PUT/DELETE /api/kontakte/[id]Detail / ändern / löschen
GET/POST/DELETE /api/kontakte/[id]/personenAnsprechpartner einer Organisation verwalten
POST /api/kontakte/extract-impressumFirmendaten 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 via src/components/address/*

Besonderheiten

  • Impressum-Extraktion: kontakte/extract-impressum zieht über Firecrawl (src/lib/firecrawl/client.ts) + AI strukturierte Firmendaten aus einer Website-URL – beschleunigt die Neuanlage von Organisationen.
  • kontakt_id ersetzt in referenzierenden Tabellen das alte customer_id (Migration 035 hat FKs umgestellt; die invoice_summary-View nutzt nun kontakt_id).

Bekannte Befunde / offene Punkte

  • In Code/DB existieren historisch beide Begriffe (customer* in @work7/domain-Funktionsnamen, kontakte in der DB). Funktion ist korrekt, Namensgebung ist gemischt – bei Refactorings auf kontakt vereinheitlichen.
  • customer_counters + Trigger set_customer_number stammen aus dem Ur-Schema und vergeben weiterhin die Nummern.

Verwandte Notes

Work7 · Software für Handwerksbetriebe