# NexAI CRM — Datenformate der exportierbaren Daten

Register der Datenstrukturen und Datenformate nach Art. 26 Buchst. b der Verordnung (EU) 2023/2854 (Data Act), zusammen mit der Beschreibung der offenen Schnittstelle nach Art. 30 Abs. 2 (`crm-openapi.json`, OpenAPI 3.1). Maschinenlesbar steht dasselbe in `crm-datenformate.json`.

Diese Datei wird aus dem Quelltext des CRM erzeugt und gilt für die Fassung, mit der sie ausgeliefert wird.

## 1. Wege, die Daten zu erhalten

- **Gesamtexport** — alle Datensätze der Organisation als ZIP mit einer CSV-Datei je Tabelle (Abschnitt 2–4). In der Oberfläche auf der Seite „Datenschutz“; über die Schnittstelle `GET /api/tenant-export`.
- **Dateipaket** — die Dateien selbst (Abschnitt 5); über die Schnittstelle `GET /api/tenant-export/dateien`.
- **Programmierschnittstelle** — lesender Zugriff auf Kontakte, Firmen, Anfragen, Deals, Aufgaben, Termine, Anrufe, Dateien und Belege; beschrieben in `crm-openapi.json`.
- **Einzelne Belege und Buchhaltung** — Beleg-PDF, XML der E-Rechnung und DATEV-Dateien (Abschnitt 6).

## 2. Aufbau des Gesamtexports

Eine ZIP-Datei (Kompression Deflate) mit dem Namen `nexai-crm-export-JJJJ-MM-TT.zip`. Sie enthält 64 CSV-Dateien, eine je Tabelle, und die Textdatei `LIESMICH.txt` (UTF-8), die den Inhalt kurz beschreibt. Jede CSV-Datei steht auch dann im Paket, wenn sie keine Zeilen hat — dann nur mit der Kopfzeile.

## 3. Regeln für alle CSV-Dateien

- Format nach RFC 4180: Komma als Trennzeichen, Zeilenende CRLF.
- Erste Zeile: die Spaltennamen, wie in den Tabellen unten.
- Ein Feld steht in doppelten Anführungszeichen, wenn es ein Komma, ein Anführungszeichen oder einen Zeilenumbruch enthält; ein Anführungszeichen darin wird verdoppelt.
- Zeichenkodierung UTF-8 (RFC 3629) mit Byte-Order-Mark (EF BB BF) am Dateianfang.
- Ein leeres Feld heißt: kein Wert. Ein leerer Text und „kein Wert“ sind in der CSV nicht zu unterscheiden.
- Die Reihenfolge der Zeilen ist nicht festgelegt.
- Gelöschte Datensätze im Papierkorb sind enthalten; sie tragen einen Zeitpunkt in deleted_at.
- Beträge sind Ganzzahlen in Cent, Mengen in Tausendsteln, Steuersätze und Rabatte in Basispunkten — es gibt keine Dezimalzahlen.
- Spalten vom Typ UUID verweisen auf die Spalte id der genannten Datei.

## 4. Datentypen

| Typ | Schreibweise in der CSV | Norm |
|---|---|---|
| Text | beliebiger Text | RFC 3629 |
| Kennung (UUID) | 8-4-4-4-12 hexadezimale Ziffern, Kleinbuchstaben | RFC 9562 |
| Zeitpunkt | JJJJ-MM-TTThh:mm:ss.ffffffZ, immer UTC, sechs Nachkommastellen | RFC 3339, ISO 8601 |
| Datum | JJJJ-MM-TT | RFC 3339, ISO 8601 |
| Monat | JJJJ-MM | ISO 8601 |
| Ganzzahl | Ziffern, negativ mit führendem Minus, ohne Tausendertrennzeichen | — |
| Wahrheitswert | true oder false | — |
| Auswahl | genau einer der genannten Werte | — |
| JSON | JSON-Text; in der CSV in Anführungszeichen, innere Anführungszeichen verdoppelt | RFC 8259 |
| Währungscode | drei Großbuchstaben, z. B. EUR | ISO 4217 |
| Ländercode | zwei Großbuchstaben, z. B. DE | ISO 3166-1 alpha-2 |
| E-Mail-Adresse | wie erfasst | — |
| Telefonnummer | wie erfasst | — |
| Internetadresse | wie erfasst | — |
| SHA-256-Prüfsumme | 64 hexadezimale Ziffern, Kleinbuchstaben | FIPS 180-4 |
| Einheitencode | zwei bis drei Großbuchstaben oder Ziffern, z. B. H87 | UN/ECE Recommendation 20 |

Einheiten bei Ganzzahlen stehen in der Spaltenbeschreibung (z. B. „in Cent“).

## 5. Das Dateipaket

Ein ZIP mit allen Dateien, die im CRM liegen — Byte für Byte: hochgeladene Dateien (Ordner dateien/anhaenge/), abgelegte Beleg-PDFs (belege/pdf/), die XML der E-Rechnungen (belege/e-rechnung/), die Anhänge verschickter Mails (mails/anhaenge/) und das Logo der Organisation (einstellungen/logo.png, .jpg, .svg oder .webp — je nach Bildtyp; in einstellungen.csv steht es nicht). Jeder andere Dateiname beginnt mit der Kennung und einem Bindestrich, danach folgt der Originalname (Zeichen, die ein Dateisystem nicht verträgt, durch _ ersetzt). Dazu LIESMICH.txt und zuordnung.csv (Regeln wie bei allen CSV-Dateien, Spalten unten). Ein Teil umfasst höchstens die gewählte Größe (Vorgabe 2.000 MB) und 60.000 Dateien, geordnet nach Art und Anlagedatum; weitere Teile über ?teil=2, ?teil=3 … Die Zahl der Teile nennen die Kopfzeile x-nexai-teile und GET /api/tenant-export/dateien/umfang. Nicht enthalten: Dateien, deren Inhalt ein Löschlauf schon entfernt hat, und PDFs von Entwürfen und nie per Mail verschickten Angeboten oder Auftragsbestätigungen (sie entstehen bei jedem Abruf neu).

Spalten von `zuordnung.csv`:

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `pfad` | Text | nein | Pfad der Datei in diesem ZIP |
| `art` | Auswahl: `anhang`, `beleg_pdf`, `e_rechnung`, `mail_anhang`, `logo` | nein | Art: hochgeladene Datei, Beleg-PDF, XML der E-Rechnung, Anhang einer Mail oder Logo |
| `id` | Kennung (UUID) | nein | Kennung der Datei (bei Belegen: die Kennung des Belegs, beim Logo: die der Organisation) |
| `dateiname` | Text | nein | Ursprünglicher Dateiname |
| `mime_typ` | Text | nein | MIME-Typ |
| `bytes` | Ganzzahl: in Bytes | nein | Größe in Bytes |
| `sha256` | SHA-256-Prüfsumme | nein | SHA-256 der Datei |
| `gehoert_zu` | Auswahl: `contact`, `company`, `lead`, `deal`, `asset`, `document`, `mail`, `einstellungen` | nein | Art des Datensatzes, zu dem die Datei gehört (document = belege.csv, mail = mails.csv, einstellungen = einstellungen.csv, sonst wie object_type) |
| `gehoert_zu_id` | Kennung (UUID) | nein | Kennung dieses Datensatzes (bei einstellungen: tenant_id) |

## 6. Weitere Formate

- **Beleg-PDF** (`GET /api/documents/{id}/pdf`): PDF/A-3b nach ISO 19005-3. Herausgegebene Belege werden genau so geliefert, wie sie abgelegt wurden; die Kopfzeile `x-nexai-sha256` trägt dann ihren SHA-256.
- **E-Rechnung** (`GET /api/documents/{id}/einvoice`): die abgelegte XML nach EN 16931 in der Syntax UN/CEFACT CII — als ZUGFeRD/Factur-X (Profil EN 16931, eingebettet in das PDF/A-3) oder als XRechnung 3.0. Die Kennung der Spezifikation (BT-24) steht in `e-rechnungen.csv`.
- **DATEV** (`GET /api/datev/…`): Buchungsstapel und Debitoren im DATEV-Format EXTF Version 700, Zeichenkodierung Windows-1252, Semikolon als Trennzeichen; dazu eine lesbare Umsatzliste als CSV mit Semikolon (Windows-1252).
- **Kalender**: Termine lassen sich zusätzlich als Kalender-Abonnement im Format iCalendar (RFC 5545) abrufen; jede Person legt ihre Abo-Adresse in der Oberfläche selbst an.

## 7. Normen und Spezifikationen

- [RFC 4180](https://www.rfc-editor.org/rfc/rfc4180) — CSV-Dateien
- [RFC 3629](https://www.rfc-editor.org/rfc/rfc3629) — UTF-8
- [RFC 8259](https://www.rfc-editor.org/rfc/rfc8259) — JSON
- [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) — Datum und Uhrzeit (Profil von ISO 8601)
- ISO 8601 — Darstellung von Datum und Uhrzeit
- [RFC 9562](https://www.rfc-editor.org/rfc/rfc9562) — UUID
- ISO 4217 — Währungscodes
- ISO 3166-1 alpha-2 — Ländercodes
- [UN/ECE Recommendation 20](https://unece.org/trade/uncefact/cl-recommendations) — Codes für Maßeinheiten
- [FIPS 180-4](https://doi.org/10.6028/NIST.FIPS.180-4) — SHA-256
- [APPNOTE (PKWARE)](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT) — ZIP-Dateiformat
- ISO 19005-3 — PDF/A-3 (Beleg-PDFs als PDF/A-3b)
- EN 16931-1:2017 — Europäische Norm für die elektronische Rechnung, Syntax UN/CEFACT CII
- [ZUGFeRD / Factur-X](https://www.ferd-net.de/) — Hybride E-Rechnung (PDF/A-3 mit eingebetteter CII-XML), Profil EN 16931
- [XRechnung 3.0](https://xeinkauf.de/xrechnung/) — Deutscher Standard der E-Rechnung (CII-Syntax)
- DATEV-Format EXTF, Version 700 — Buchungsstapel (Kategorie 21) und Debitoren (Kategorie 16)
- [RFC 5545](https://www.rfc-editor.org/rfc/rfc5545) — iCalendar
- [RFC 6750](https://www.rfc-editor.org/rfc/rfc6750) — Bearer-Token für die Programmierschnittstelle
- [OpenAPI 3.1](https://spec.openapis.org/oas/v3.1.0) — Beschreibung der Schnittstelle

## 8. Was nicht exportiert wird, und warum

- Zugänge: API-Schlüssel, Anmeldesitzungen, Wiederherstellungscodes und Marken zum Zurücksetzen des Passworts. Sie sind kein Datenbestand, sondern ein Schlüssel zum System; im neuen System werden sie neu angelegt.
- Verbindungen zu fremden Konten (eigenes Postfach, Kalender, Absendernummer) mit ihren Zugangsdaten. Im neuen System verbindet man sie neu.
- Kalender-Abo-Adressen und eingetragene Kalender-Links. Die Adresse selbst ist ein Zugang; die Termine stehen in termine.csv.
- Technik des Kalenderabgleichs und zwischengespeicherte belegte Zeiten aus dem eigenen Kalender der Mitarbeitenden. Sie werden beim nächsten Abgleich neu gelesen.
- Das Zustellprotokoll der Webhooks: Kopien von Daten, die ohnehin im Paket stehen.
- Der Stammsatz der Organisation selbst (Name und Kürzel im System); ihre Einstellungen stehen in einstellungen.csv.

In den exportierten Dateien fehlen außerdem bewusst:

- Passwort-Hashes und Zwei-Faktor-Geheimnisse der Benutzer.
- Signaturgeheimnisse der Webhooks sowie Geheimnisse und Konfiguration der verbundenen Dienste.
- Das Antwortkennzeichen einer Mail (ein Zugang zum Mailfaden) und Kennungen beim Mailanbieter.
- Interne Angaben zur Aufbewahrung und Versandtechnik (z. B. Wiederholungszeitpunkte).
- Das hinterlegte Logo in einstellungen.csv — es steht als Bilddatei im Dateipaket.

## 9. Die Dateien im Einzelnen

### kontakte.csv

Personen: Kundinnen, Interessenten, Ansprechpartner.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `first_name` | Text | ja | Vorname |
| `last_name` | Text | ja | Nachname |
| `email` | E-Mail-Adresse | ja | E-Mail-Adresse |
| `phone` | Telefonnummer | ja | Telefonnummer, wie erfasst |
| `company_id` | Kennung (UUID) → firmen.csv | ja | Zugehörige Firma |
| `position` | Text | ja | Funktion in der Firma |
| `street` | Text | ja | Straße und Hausnummer |
| `postal_code` | Text | ja | Postleitzahl |
| `city` | Text | ja | Ort |
| `country` | Text | ja | Land (Name) |
| `country_code` | Ländercode | ja | Land als Code |
| `source` | Text | ja | Herkunft des Kontakts (z. B. Formular, Telefon) |
| `status` | Auswahl: `active`, `archived` | nein | Zustand |
| `owner_id` | Kennung (UUID) → benutzer.csv | ja | Zuständige Person |
| `last_contacted_at` | Zeitpunkt | ja | Zuletzt kontaktiert am |
| `next_follow_up_at` | Zeitpunkt | ja | Nächste Wiedervorlage |
| `notes` | Text | ja | Notizen (Freitext) |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |
| `deleted_at` | Zeitpunkt | ja | In den Papierkorb gelegt am; leer = nicht gelöscht |

### firmen.csv

Firmen mit Anschrift, Rechnungsangaben und Stammdaten der E-Rechnung.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `name` | Text | nein | Name der Firma |
| `domain` | Text | ja | Internetdomain |
| `phone` | Telefonnummer | ja | Telefonnummer |
| `email` | E-Mail-Adresse | ja | Allgemeine E-Mail-Adresse |
| `billing_email` | E-Mail-Adresse | ja | E-Mail-Adresse für Rechnungen |
| `street` | Text | ja | Straße und Hausnummer |
| `postal_code` | Text | ja | Postleitzahl |
| `city` | Text | ja | Ort |
| `country` | Text | ja | Land (Name) |
| `country_code` | Ländercode | ja | Land als Code |
| `vat_id` | Text | ja | USt-IdNr., ohne Leerzeichen (z. B. DE123456789) |
| `buyer_reference` | Text | ja | Käuferreferenz für die E-Rechnung (BT-10), bei Behörden die Leitweg-ID |
| `einvoice_format` | Auswahl: `auto`, `xrechnung` | nein | Gewünschte E-Rechnung: auto = ZUGFeRD/Factur-X, xrechnung = XRechnung |
| `notes` | Text | ja | Notizen (Freitext) |
| `industry` | Text | ja | Branche |
| `employee_count` | Ganzzahl | ja | Anzahl Mitarbeitende |
| `primary_contact_id` | Kennung (UUID) → kontakte.csv | ja | Hauptansprechpartner |
| `external_ref` | Text | ja | Kennung im vorgelagerten System, aus dem die Firma gespiegelt wird |
| `external_updated_at` | Zeitpunkt | ja | Stand im vorgelagerten System, zuletzt übernommen |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |
| `deleted_at` | Zeitpunkt | ja | In den Papierkorb gelegt am; leer = nicht gelöscht |

### anfragen.csv

Anfragen (Leads): Interesse, das noch kein Geschäft ist.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `title` | Text | nein | Titel |
| `contact_id` | Kennung (UUID) → kontakte.csv | ja | Zugehöriger Kontakt |
| `company_id` | Kennung (UUID) → firmen.csv | ja | Zugehörige Firma |
| `status` | Auswahl: `new`, `contacted`, `qualified`, `unqualified`, `converted`, `lost` | nein | Bearbeitungsstand |
| `source` | Text | ja | Herkunft der Anfrage |
| `owner_id` | Kennung (UUID) → benutzer.csv | ja | Zuständige Person |
| `notes` | Text | ja | Notizen (Freitext) |
| `next_follow_up_at` | Zeitpunkt | ja | Nächste Wiedervorlage |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |
| `deleted_at` | Zeitpunkt | ja | In den Papierkorb gelegt am; leer = nicht gelöscht |

### deals.csv

Deals (Vorgänge) in einer Pipeline, mit Wert, Phase und Ausgang.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `title` | Text | nein | Titel |
| `pipeline_id` | Kennung (UUID) → pipelines.csv | nein | Pipeline |
| `stage_id` | Kennung (UUID) → pipeline-phasen.csv | nein | Aktuelle Phase |
| `contact_id` | Kennung (UUID) → kontakte.csv | ja | Zugehöriger Kontakt |
| `company_id` | Kennung (UUID) → firmen.csv | ja | Zugehörige Firma |
| `value_cents` | Ganzzahl: in Cent (1/100 der Währungseinheit) | nein | Wert in Cent der Währung |
| `currency` | Währungscode | nein | Währung |
| `status` | Auswahl: `open`, `won`, `lost` | nein | Offen, gewonnen oder verloren |
| `owner_id` | Kennung (UUID) → benutzer.csv | ja | Zuständige Person |
| `notes` | Text | ja | Notizen (Freitext) |
| `expected_close_at` | Zeitpunkt | ja | Erwarteter Abschluss |
| `closed_at` | Zeitpunkt | ja | Abgeschlossen am (gewonnen oder verloren) |
| `lost_reason` | Auswahl: `price`, `competitor`, `no_need`, `no_budget`, `no_response`, `timing`, `other` | ja | Verlustgrund: price = Preis, competitor = Wettbewerber, no_need = kein Bedarf, no_budget = kein Budget, no_response = keine Rückmeldung, timing = Zeitpunkt, other = Sonstiges |
| `lost_note` | Text | ja | Notiz zum Verlust |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |
| `deleted_at` | Zeitpunkt | ja | In den Papierkorb gelegt am; leer = nicht gelöscht |

### objekte.csv

Objekte: Geräte, Fahrzeuge, Anlagen, Verträge — was bei einem Kunden steht oder läuft.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `kind` | Text | nein | Art des Objekts (frei benannt) |
| `name` | Text | nein | Bezeichnung |
| `identifier` | Text | ja | Kennzeichen, Seriennummer o. Ä. |
| `contact_id` | Kennung (UUID) → kontakte.csv | ja | Zugehöriger Kontakt |
| `company_id` | Kennung (UUID) → firmen.csv | ja | Zugehörige Firma |
| `active` | Wahrheitswert | nein | Aktiv |
| `acquired_on` | Datum | ja | Angeschafft am |
| `notes` | Text | ja | Notizen (Freitext) |
| `owner_id` | Kennung (UUID) → benutzer.csv | ja | Zuständige Person |
| `location_id` | Kennung (UUID) → standorte.csv | ja | Standort |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |
| `deleted_at` | Zeitpunkt | ja | In den Papierkorb gelegt am; leer = nicht gelöscht |

### sms.csv

SMS an Kontakte, mit Zustellstand und Umfang.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `contact_id` | Kennung (UUID) → kontakte.csv | ja | Zugehöriger Kontakt |
| `to_phone` | Telefonnummer | nein | Empfängernummer |
| `body` | Text | nein | Text, wie er versandt wurde (auf das SMS-Alphabet umgeschrieben) |
| `status` | Auswahl: `pending`, `sent`, `failed`, `dead` | nein | Versandstand: pending = wartet, sent = versandt, failed = Versuch fehlgeschlagen, dead = aufgegeben |
| `attempts` | Ganzzahl | nein | Anzahl Versandversuche |
| `last_error` | Text | ja | Letzte Fehlermeldung |
| `provider_message_id` | Text | ja | Kennung der Nachricht beim SMS-Anbieter |
| `sent_at` | Zeitpunkt | ja | Versandt am |
| `segments` | Ganzzahl | nein | Anzahl SMS-Teile (Abrechnungseinheit) |
| `encoding` | Auswahl: `gsm7`, `ucs2` | nein | Zeichensatz der SMS (GSM 7-Bit oder UCS-2) |
| `sender_phone` | Telefonnummer | ja | Absendernummer |
| `keine_werbung` | Wahrheitswert | nein | Beim Schreiben bestätigt, dass die SMS keine Werbung enthält — verlangt, wenn die Person der Werbung widersprochen hat (werbewidersprueche.csv); ohne die Bestätigung geht die SMS an eine solche Person nicht hinaus. false = nicht bestätigt, so auch bei jeder SMS, die vor dem 01.11.2026 geschrieben wurde |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Angelegt von |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### zahlungseingaenge.csv

Zahlungen, die zu einer Rechnung eingegangen sind.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `document_id` | Kennung (UUID) → belege.csv | nein | Rechnung |
| `amount_cents` | Ganzzahl: in Cent (1/100 der Währungseinheit) | nein | Betrag in Cent der Belegwährung |
| `paid_on` | Datum | nein | Zahlungstag |
| `source` | Auswahl: `manual`, `datev`, `api` | nein | Erfasst von Hand, aus einem DATEV-Buchungsstapel oder über die Schnittstelle |
| `reference` | Text | ja | Verwendungszweck oder Referenz |
| `note` | Text | ja | Bemerkung |
| `import_key` | Text | ja | Schlüssel der importierten Buchung (verhindert doppeltes Einlesen) |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Angelegt von |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### freigabe-regeln.csv

Regeln, ab welchem Rabatt ein Beleg eine Freigabe braucht.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `name` | Text | nein | Name der Regel |
| `active` | Wahrheitswert | nein | Aktiv |
| `kind` | Auswahl: `document.discount` | nein | Art der Regel |
| `threshold_bp` | Ganzzahl: in Basispunkten (1/100 Prozent) | nein | Schwelle in Basispunkten (1000 = 10 %) |
| `document_kinds` | JSON | nein | Belegarten, für die die Regel gilt, als JSON-Array (leer = alle) |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Angelegt von |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |

### freigaben.csv

Freigabeanfragen: wer welchen Rabatt beantragt, genehmigt oder abgelehnt hat.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `rule_id` | Kennung (UUID) → freigabe-regeln.csv | nein | Regel |
| `document_id` | Kennung (UUID) → belege.csv | nein | Beleg |
| `status` | Auswahl: `open`, `approved`, `rejected` | nein | Offen, genehmigt oder abgelehnt |
| `measured_bp` | Ganzzahl: in Basispunkten (1/100 Prozent) | nein | Gemessener größter Rabatt in Basispunkten |
| `threshold_bp` | Ganzzahl: in Basispunkten (1/100 Prozent) | nein | Schwelle zum Zeitpunkt der Anfrage |
| `requested_by` | Kennung (UUID) → benutzer.csv | ja | Beantragt von |
| `requested_at` | Zeitpunkt | nein | Beantragt am |
| `decided_by` | Kennung (UUID) → benutzer.csv | ja | Entschieden von |
| `decided_at` | Zeitpunkt | ja | Entschieden am |
| `note` | Text | ja | Begründung |

### automatisierungen.csv

Automatisierungen: Regeln „wenn Ereignis, dann Aufgabe oder Notiz“.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `name` | Text | nein | Name der Regel |
| `active` | Wahrheitswert | nein | Aktiv |
| `trigger_type` | Auswahl: `deal.stageChanged`, `lead.created`, `contact.created`, `asset.created`, `task.completed` | nein | Auslösendes Ereignis |
| `trigger_filter` | JSON | nein | Einengung als JSON-Objekt (Feld → Wert); {} = jedes Ereignis |
| `action_type` | Auswahl: `task.create`, `note.create` | nein | Folge |
| `action_config` | JSON | nein | Einstellungen der Folge als JSON-Objekt (z. B. Titel, Fälligkeit in Tagen, Zuständigkeit) |
| `last_fired_at` | Zeitpunkt | ja | Zuletzt ausgelöst am |
| `fired_count` | Ganzzahl | nein | Anzahl Auslösungen |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Angelegt von |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |

### automatisierungen-protokoll.csv

Protokoll der Automatisierungen: warum eine Regel ausgelöst hat oder nicht.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `rule_id` | Kennung (UUID) → automatisierungen.csv | nein | Regel |
| `event_id` | Kennung (UUID) → systemereignisse.csv | nein | Auslösendes Ereignis |
| `status` | Auswahl: `fired`, `skipped`, `failed` | nein | Ausgelöst, übersprungen oder fehlgeschlagen |
| `detail` | Text | ja | Erläuterung |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### abwesenheiten.csv

Abwesenheiten (Urlaub) mit Vertretung und Übergabe; ohne Grund der Abwesenheit.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `user_id` | Kennung (UUID) → benutzer.csv | nein | Abwesende Person |
| `substitute_id` | Kennung (UUID) → benutzer.csv | ja | Vertretung |
| `handover_to` | Kennung (UUID) → benutzer.csv | ja | Person, an die Datensätze übergeben wurden |
| `handed_over_at` | Zeitpunkt | ja | Übergeben am |
| `returned_at` | Zeitpunkt | ja | Zurückgegeben am |
| `from_on` | Datum | nein | Erster Tag |
| `to_on` | Datum | nein | Letzter Tag |
| `note` | Text | ja | Bemerkung |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Angelegt von |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### feste-berichte.csv

Feste Berichte: welcher Bericht wie oft an wen per Mail geht. Ohne Zahlen.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `title` | Text | nein | Titel |
| `recipient` | E-Mail-Adresse | nein | Empfängeradresse |
| `source` | Auswahl: `deals`, `leads`, `calls` | nein | Datenquelle des Berichts |
| `metric` | Auswahl: `count`, `sum_value`, `weighted_value`, `avg_value`, `sum_duration`, `avg_duration` | nein | Kennzahl |
| `grouping` | Auswahl: `none`, `month`, `stage`, `pipeline`, `owner`, `status`, `source`, `direction`, `outcome`, `location`, `lost_reason` | nein | Gruppierung |
| `date_field` | Auswahl: `created`, `closed`, `started` | nein | Datumsfeld, nach dem der Zeitraum gilt |
| `cadence` | Auswahl: `month`, `week` | nein | Rhythmus: monatlich oder wöchentlich |
| `day_of_month` | Ganzzahl | nein | Versandtag im Monat (1–31) |
| `active` | Wahrheitswert | nein | Aktiv |
| `last_sent_on` | Datum | ja | Zuletzt versandt am |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Angelegt von |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### chargen.csv

Chargen und Seriennummern von Artikeln. Der Bestand ergibt sich aus lagerbewegungen.csv.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `article_id` | Kennung (UUID) → preisverzeichnis.csv | nein | Artikel |
| `kind` | Auswahl: `lot`, `serial` | nein | lot = Charge, serial = Seriennummer |
| `code` | Text | nein | Chargen- bzw. Seriennummer |
| `expires_on` | Datum | ja | Haltbar bis |
| `note` | Text | ja | Bemerkung |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Angelegt von |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### lagerbewegungen.csv

Das Bewegungsbuch des Lagers. Der Bestand ist die Summe von quantity_milli.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `article_id` | Kennung (UUID) → preisverzeichnis.csv | nein | Artikel |
| `location_id` | Kennung (UUID) → standorte.csv | ja | Standort |
| `kind` | Auswahl: `in`, `out`, `correction`, `stocktake` | nein | in = Zugang, out = Abgang, correction = Korrektur, stocktake = Inventur |
| `quantity_milli` | Ganzzahl: in Tausendsteln | nein | Menge in Tausendsteln, mit Vorzeichen (Abgang negativ) |
| `lot_id` | Kennung (UUID) → chargen.csv | ja | Charge oder Seriennummer |
| `document_id` | Kennung (UUID) → belege.csv | ja | Zugehöriger Beleg |
| `deal_id` | Kennung (UUID) → deals.csv | ja | Zugehöriger Deal (Vorgang) |
| `note` | Text | ja | Bemerkung |
| `occurred_on` | Datum | nein | Tag der Bewegung |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Angelegt von |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### wiederkehrendes.csv

Wiederkehrende Termine (Wartung, Prüfung, Verlängerung) an einem Datensatz.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `object_type` | Auswahl: `contact`, `company`, `lead`, `deal`, `asset` | nein | Art des Datensatzes, an dem dies hängt |
| `record_id` | Kennung (UUID) | nein | Kennung des Datensatzes, an dem dies hängt (Datei je nach object_type) |
| `title` | Text | nein | Titel |
| `notes` | Text | ja | Notizen (Freitext) |
| `every_count` | Ganzzahl | nein | Abstand: Anzahl |
| `every_unit` | Auswahl: `day`, `week`, `month`, `year` | nein | Abstand: Einheit |
| `lead_days` | Ganzzahl: in Tagen | nein | Vorlauf: so viele Tage vorher entsteht die Aufgabe |
| `anchor_on` | Datum | nein | Ausgangstermin, von dem aus gerechnet wird |
| `next_due_on` | Datum | nein | Nächster fälliger Termin |
| `last_created_on` | Datum | ja | Zuletzt Aufgabe angelegt am |
| `assignee_id` | Kennung (UUID) → benutzer.csv | ja | Zuständige Person |
| `active` | Wahrheitswert | nein | Aktiv |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |

### preisverzeichnis.csv

Artikel und Leistungen mit Preis und Steuersatz.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `number` | Text | nein | Artikelnummer |
| `name` | Text | nein | Bezeichnung |
| `description` | Text | ja | Beschreibung |
| `kind` | Auswahl: `product`, `service` | nein | Ware oder Dienstleistung |
| `tracks` | Auswahl: `lot`, `serial` | ja | Geführt nach Charge (lot) oder Seriennummer (serial); leer = keines |
| `unit` | Text | nein | Einheit, wie sie auf dem Beleg steht |
| `unit_code` | Einheitencode | ja | Einheitencode nach UN/ECE Recommendation 20 (z. B. H87 = Stück) |
| `net_price_cents` | Ganzzahl: in Cent (1/100 der Währungseinheit) | nein | Listenpreis netto in Cent |
| `tax_rate_bp` | Ganzzahl: in Basispunkten (1/100 Prozent) | nein | Umsatzsteuersatz in Basispunkten (1900 = 19 %) |
| `active` | Wahrheitswert | nein | Aktiv |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |

### deal-positionen.csv

Positionen eines Deals (Grundlage der Belege).

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `deal_id` | Kennung (UUID) → deals.csv | nein | Deal |
| `position` | Ganzzahl | nein | Reihenfolge |
| `article_id` | Kennung (UUID) → preisverzeichnis.csv | ja | Artikel; leer = frei getippt |
| `number` | Text | ja | Artikelnummer |
| `name` | Text | nein | Bezeichnung |
| `unit` | Text | nein | Einheit, wie sie auf dem Beleg steht |
| `unit_code` | Einheitencode | ja | Einheitencode nach UN/ECE Recommendation 20 (z. B. H87 = Stück) |
| `quantity_milli` | Ganzzahl: in Tausendsteln | nein | Menge in Tausendsteln (2500 = 2,5) |
| `net_price_cents` | Ganzzahl: in Cent (1/100 der Währungseinheit) | nein | Einzelpreis netto in Cent der Belegwährung |
| `tax_rate_bp` | Ganzzahl: in Basispunkten (1/100 Prozent) | nein | Umsatzsteuersatz in Basispunkten (1900 = 19 %) |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### termine.csv

Termine im CRM.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `title` | Text | nein | Titel |
| `starts_at` | Zeitpunkt | nein | Beginn |
| `ends_at` | Zeitpunkt | nein | Ende |
| `place` | Text | ja | Ort |
| `notes` | Text | ja | Notizen (Freitext) |
| `status` | Auswahl: `planned`, `held`, `cancelled` | nein | Geplant, stattgefunden oder abgesagt |
| `contact_id` | Kennung (UUID) → kontakte.csv | ja | Zugehöriger Kontakt |
| `company_id` | Kennung (UUID) → firmen.csv | ja | Zugehörige Firma |
| `deal_id` | Kennung (UUID) → deals.csv | ja | Zugehöriger Deal (Vorgang) |
| `asset_id` | Kennung (UUID) → objekte.csv | ja | Zugehöriges Objekt |
| `owner_id` | Kennung (UUID) → benutzer.csv | ja | Zuständige Person |
| `location_id` | Kennung (UUID) → standorte.csv | ja | Standort |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Angelegt von |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |
| `deleted_at` | Zeitpunkt | ja | In den Papierkorb gelegt am; leer = nicht gelöscht |

### belege.csv

Angebote, Auftragsbestätigungen, Rechnungen und Stornos. Absender und Empfänger stehen als eingefrorener Stand in JSON-Spalten.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `kind` | Auswahl: `quote`, `order_confirmation`, `invoice`, `credit_note` | nein | Belegart: quote = Angebot, order_confirmation = Auftragsbestätigung, invoice = Rechnung, credit_note = Storno |
| `number` | Text | ja | Belegnummer; leer, solange Entwurf |
| `deal_id` | Kennung (UUID) → deals.csv | ja | Zugehöriger Deal (Vorgang) |
| `contact_id` | Kennung (UUID) → kontakte.csv | ja | Zugehöriger Kontakt |
| `company_id` | Kennung (UUID) → firmen.csv | ja | Zugehörige Firma |
| `status` | Auswahl: `draft`, `sent`, `accepted`, `declined` | nein | draft = Entwurf, sent = herausgegeben, accepted/declined = Angebot angenommen/abgelehnt |
| `title` | Text | nein | Titel |
| `intro` | Text | ja | Einleitungstext |
| `outro` | Text | ja | Schlusstext |
| `buyer_reference` | Text | ja | Käuferreferenz (BT-10) |
| `order_reference` | Text | ja | Bestellnummer des Käufers (BT-13) |
| `sender_snapshot` | JSON | ja | Absender beim Herausgeben als JSON-Objekt (name, street, postalCode, city, country, countryCode, phone, email, website, vatId, taxNumber, registerId, contactName, legal, bankName, iban, bic) |
| `recipient_snapshot` | JSON | ja | Empfänger beim Herausgeben als JSON-Objekt (company, person, street, postalCode, city, country, countryCode, email, vatId) |
| `currency` | Währungscode | nein | Währung |
| `valid_until` | Datum | ja | Angebot gültig bis |
| `issued_on` | Datum | ja | Belegdatum |
| `sent_at` | Zeitpunkt | ja | Herausgegeben am |
| `decided_at` | Zeitpunkt | ja | Angebot entschieden am |
| `service_date` | Datum | ja | Leistungsdatum |
| `service_period_start` | Datum | ja | Leistungszeitraum: Beginn |
| `service_period_end` | Datum | ja | Leistungszeitraum: Ende |
| `due_date` | Datum | ja | Zahlbar bis |
| `cancels_document_id` | Kennung (UUID) → belege.csv | ja | Rechnung, die dieses Storno aufhebt |
| `billing_run_id` | Kennung (UUID) → abrechnungslaeufe.csv | ja | Abrechnungslauf, aus dem der Beleg stammt |
| `small_business` | Wahrheitswert | nein | Ausgestellt als Kleinunternehmer (§ 19 UStG) |
| `locked_at` | Zeitpunkt | ja | Festgeschrieben am (danach unveränderbar) |
| `einvoice_format` | Auswahl: `hybrid`, `xrechnung` | ja | E-Rechnung: hybrid = ZUGFeRD/Factur-X, xrechnung = XRechnung; leer = PDF ohne XML |
| `net_cents` | Ganzzahl: in Cent (1/100 der Währungseinheit) | nein | Summe netto in Cent |
| `tax_cents` | Ganzzahl: in Cent (1/100 der Währungseinheit) | nein | Umsatzsteuer in Cent |
| `gross_cents` | Ganzzahl: in Cent (1/100 der Währungseinheit) | nein | Summe brutto in Cent |
| `owner_id` | Kennung (UUID) → benutzer.csv | ja | Zuständige Person |
| `location_id` | Kennung (UUID) → standorte.csv | ja | Standort |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |

### beleg-positionen.csv

Positionen der Belege.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `document_id` | Kennung (UUID) → belege.csv | nein | Beleg |
| `position` | Ganzzahl | nein | Reihenfolge |
| `number` | Text | ja | Artikelnummer |
| `name` | Text | nein | Bezeichnung |
| `unit` | Text | nein | Einheit, wie sie auf dem Beleg steht |
| `unit_code` | Einheitencode | ja | Einheitencode nach UN/ECE Recommendation 20 (z. B. H87 = Stück) |
| `quantity_milli` | Ganzzahl: in Tausendsteln | nein | Menge in Tausendsteln (2500 = 2,5) |
| `net_price_cents` | Ganzzahl: in Cent (1/100 der Währungseinheit) | nein | Einzelpreis netto in Cent der Belegwährung |
| `tax_rate_bp` | Ganzzahl: in Basispunkten (1/100 Prozent) | nein | Umsatzsteuersatz in Basispunkten (1900 = 19 %) |
| `period_start` | Datum | ja | Eigener Leistungszeitraum: Beginn |
| `period_end` | Datum | ja | Eigener Leistungszeitraum: Ende |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### abo-vertraege.csv

Abo-Verträge der monatlichen bzw. jährlichen Abrechnung.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `company_id` | Kennung (UUID) → firmen.csv | nein | Kunde (Firma) |
| `source` | Auswahl: `portal`, `crm` | nein | portal = aus dem vorgelagerten Partnerportal gespiegelt, crm = nur im CRM |
| `external_ref` | Text | ja | Kennung im vorgelagerten System |
| `article_id` | Kennung (UUID) → preisverzeichnis.csv | ja | Artikel |
| `title` | Text | nein | Bezeichnung |
| `billing_period` | Auswahl: `monthly`, `yearly` | nein | Abrechnungsrhythmus |
| `setup_cents` | Ganzzahl: in Cent (1/100 der Währungseinheit) | nein | Einrichtungsgebühr netto in Cent |
| `bill_setup` | Wahrheitswert | nein | Einrichtung wird berechnet |
| `tax_rate_bp` | Ganzzahl: in Basispunkten (1/100 Prozent) | nein | Umsatzsteuersatz in Basispunkten (1900 = 19 %) |
| `start_date` | Datum | nein | Vertragsbeginn |
| `billing_start` | Datum | ja | Abrechnung ab |
| `auto_invoice` | Wahrheitswert | nein | Wird im Monatslauf abgerechnet |
| `send_mode` | Auswahl: `draft`, `auto` | nein | Rechnung als Entwurf oder automatisch |
| `payment_method` | Auswahl: `transfer`, `direct_debit` | nein | Überweisung oder Lastschrift |
| `status` | Auswahl: `active`, `paused`, `cancelled`, `completed` | nein | Aktiv, pausiert, gekündigt oder beendet |
| `cancelled_at` | Datum | ja | Letzter Vertragstag bei Kündigung/Ende |
| `paused_from` | Datum | ja | Laufende Pause: ab |
| `resumed_on` | Datum | ja | Laufende Pause: wieder ab |
| `enabled_by` | Kennung (UUID) → benutzer.csv | ja | Abrechnung eingeschaltet von |
| `enabled_at` | Zeitpunkt | ja | Abrechnung eingeschaltet am |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Angelegt von |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |
| `source_updated_at` | Zeitpunkt | ja | Stand im vorgelagerten System, zuletzt übernommen |
| `open_periods_ack_until` | Monat | ja | Offene Monate bis einschließlich dieses Monats freigegeben |

### abo-pausen.csv

Frühere, beendete Pausen eines Abo-Vertrags (ab paused_from bis vor resumed_on).

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `contract_id` | Kennung (UUID) → abo-vertraege.csv | nein | Vertrag |
| `paused_from` | Datum | nein | Pause ab |
| `resumed_on` | Datum | nein | Wieder ab |
| `source` | Auswahl: `crm`, `portal` | nein | Erfasst im CRM oder vom Portal |
| `recorded_by` | Kennung (UUID) → benutzer.csv | ja | Erfasst von |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |
| `voided_at` | Zeitpunkt | ja | Aufgehoben am; dann zählt die Zeile nicht |
| `voided_by` | Kennung (UUID) → benutzer.csv | ja | Aufgehoben von |

### abo-preise.csv

Preis eines Abo-Vertrags je Periode ab einem Monat (beim Jahresvertrag der Jahresbetrag).

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `contract_id` | Kennung (UUID) → abo-vertraege.csv | nein | Vertrag |
| `valid_from_month` | Monat | nein | Gültig ab Monat |
| `price_cents` | Ganzzahl: in Cent (1/100 der Währungseinheit) | nein | Preis netto je Periode in Cent |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Angelegt von |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### abo-zusatzposten.csv

Zusatzposten eines Abo-Vertrags (z. B. weitere Zugänge).

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `contract_id` | Kennung (UUID) → abo-vertraege.csv | nein | Vertrag |
| `article_id` | Kennung (UUID) → preisverzeichnis.csv | ja | Artikel |
| `text` | Text | nein | Bezeichnung |
| `quantity` | Ganzzahl | nein | Anzahl |
| `unit_price_cents` | Ganzzahl: in Cent (1/100 der Währungseinheit) | nein | Monatspreis je Stück netto in Cent (auch bei Jahresverträgen) |
| `from_day` | Datum | nein | Ab Tag |
| `until_day` | Datum | ja | Bis einschließlich Tag |
| `source` | Auswahl: `manual`, `mailagent` | nein | Erfasst von Hand oder vom E-Mail-Agenten |
| `external_ref` | Text | ja | Kennung im vorgelagerten System |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Angelegt von |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |

### abrechnungslaeufe.csv

Monatliche Abrechnungsläufe (einer je Monat).

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `run_month` | Monat | nein | Abgerechneter Monat |
| `status` | Auswahl: `running`, `done` | nein | Läuft oder fertig |
| `source` | Auswahl: `worker`, `manual` | nein | Automatisch oder von Hand gestartet |
| `started_by` | Kennung (UUID) → benutzer.csv | ja | Gestartet von |
| `started_at` | Zeitpunkt | nein | Gestartet am |
| `finished_at` | Zeitpunkt | ja | Beendet am |
| `summary` | JSON | nein | Zusammenfassung als JSON-Objekt (Zähler je Ergebnis) |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### abrechnungslauf-posten.csv

Ergebnis eines Abrechnungslaufs je Firma.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `run_id` | Kennung (UUID) → abrechnungslaeufe.csv | nein | Abrechnungslauf |
| `company_id` | Kennung (UUID) → firmen.csv | nein | Firma |
| `status` | Auswahl: `planned`, `blocked`, `draft`, `failed`, `discarded` | nein | Geplant, gesperrt, Entwurf erzeugt, fehlgeschlagen oder verworfen |
| `block_reason` | Auswahl: `company_missing`, `address_incomplete`, `country_not_de`, `too_many_open_periods`, `missing_price`, `missing_cancel_date`, `zero_tax_rate` | ja | Grund der Sperre |
| `blocked_contracts` | JSON | nein | Gesperrte Verträge als JSON-Array von Objekten (contractId, reason, openPeriods) |
| `document_id` | Kennung (UUID) → belege.csv | ja | Erzeugter Rechnungsentwurf |
| `net_cents` | Ganzzahl: in Cent (1/100 der Währungseinheit) | ja | Summe netto in Cent |
| `error` | Text | ja | Fehlermeldung |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |

### abgerechnet.csv

Welche Abrechnungsperiode schon berechnet ist und auf welchem Beleg — verhindert Doppelrechnungen.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `billing_key` | Text | nein | Eindeutiger Schlüssel der Periode |
| `kind` | Auswahl: `setup`, `contract`, `addon` | nein | Einrichtung, Vertragsperiode oder Zusatzposten |
| `contract_id` | Kennung (UUID) → abo-vertraege.csv | nein | Vertrag |
| `addon_id` | Kennung (UUID) → abo-zusatzposten.csv | ja | Zusatzposten |
| `run_id` | Kennung (UUID) → abrechnungslaeufe.csv | ja | Abrechnungslauf |
| `document_id` | Kennung (UUID) → belege.csv | ja | Rechnung |
| `document_item_id` | Kennung (UUID) → beleg-positionen.csv | ja | Rechnungsposition |
| `period_start` | Datum | nein | Periode: Beginn |
| `period_end` | Datum | nein | Periode: Ende |
| `amount_cents` | Ganzzahl: in Cent (1/100 der Währungseinheit) | nein | Betrag netto in Cent |
| `released_at` | Zeitpunkt | ja | Freigegeben am (wieder abrechenbar) |
| `release_reason` | Auswahl: `draft_discarded`, `storno_rebill` | ja | Grund der Freigabe: Entwurf verworfen oder Storno mit Neuabrechnung |
| `released_by` | Kennung (UUID) → benutzer.csv | ja | Freigegeben von |
| `rebill_on_storno_id` | Kennung (UUID) → belege.csv | ja | Storno, mit dem neu abgerechnet wird |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### belegnummern.csv

Stand der Nummernkreise je Belegart und Jahr.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `kind` | Auswahl: `quote`, `order_confirmation`, `invoice`, `credit_note` | nein | Belegart |
| `year` | Ganzzahl | nein | Jahr |
| `last_no` | Ganzzahl | nein | Zuletzt vergebene laufende Nummer |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |

### briefvorlagen.csv

Vorlagen für Einleitung und Schluss je Belegart.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `kind` | Auswahl: `quote`, `order_confirmation`, `invoice`, `credit_note` | nein | Belegart |
| `title` | Text | ja | Titel |
| `intro` | Text | ja | Einleitungstext (mit Platzhaltern) |
| `outro` | Text | ja | Schlusstext (mit Platzhaltern) |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |

### pipelines.csv

Pipelines (Abfolgen von Phasen für Deals).

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `name` | Text | nein | Name |
| `is_default` | Wahrheitswert | nein | Standard-Pipeline |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### pipeline-phasen.csv

Phasen einer Pipeline.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `pipeline_id` | Kennung (UUID) → pipelines.csv | nein | Pipeline |
| `name` | Text | nein | Name |
| `position` | Ganzzahl | nein | Reihenfolge |
| `probability` | Ganzzahl: in Prozent | ja | Abschlusswahrscheinlichkeit in Prozent (0–100) |
| `is_won` | Wahrheitswert | nein | Phase bedeutet „gewonnen“ |
| `is_lost` | Wahrheitswert | nein | Phase bedeutet „verloren“ |

### anrufe.csv

Telefonate, z. B. vom Sprachassistenten, mit Ergebnis und vereinbartem Termin.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `external_id` | Text | ja | Kennung im liefernden System |
| `contact_id` | Kennung (UUID) → kontakte.csv | ja | Zugehöriger Kontakt |
| `agent_id` | Kennung (UUID) → vertriebspartner.csv | ja | Vertriebspartner |
| `reached` | Wahrheitswert | ja | Gesprächspartner erreicht; leer = unbekannt |
| `direction` | Auswahl: `inbound`, `outbound` | nein | Eingehend oder ausgehend |
| `from_number` | Telefonnummer | ja | Anrufende Nummer |
| `to_number` | Telefonnummer | ja | Angerufene Nummer |
| `started_at` | Zeitpunkt | ja | Beginn |
| `ended_at` | Zeitpunkt | ja | Ende |
| `duration_seconds` | Ganzzahl: in Sekunden | ja | Dauer in Sekunden |
| `status` | Text | nein | Status, wie vom Telefonsystem gemeldet |
| `summary` | Text | ja | Zusammenfassung |
| `intent` | Text | ja | Anliegen |
| `outcome` | Text | ja | Ergebnis |
| `department` | Text | ja | Abteilung |
| `follow_up_required` | Wahrheitswert | nein | Rückruf nötig |
| `appointment_at` | Zeitpunkt | ja | Vereinbarter Termin |
| `appointment_status` | Auswahl: `confirmed`, `tentative`, `cancelled`, `held`, `no_show` | ja | Stand des vereinbarten Termins |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `deleted_at` | Zeitpunkt | ja | In den Papierkorb gelegt am; leer = nicht gelöscht |

### gespraechsprotokolle.csv

Wortlaut der Gespräche (im System verschlüsselt, im Export lesbar).

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `call_id` | Kennung (UUID) → anrufe.csv | nein | Anruf |
| `content` | Text | nein | Wortlaut |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `expires_at` | Zeitpunkt | ja | Wird gelöscht ab |

### verarbeitungszwecke.csv

Zwecke, zu denen personenbezogene Daten verarbeitet werden.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `name` | Text | nein | Name des Zwecks |
| `description` | Text | ja | Beschreibung |
| `affects_email` | Wahrheitswert | nein | Ein Widerruf zu diesem Zweck sperrt den E-Mail-Versand an den Kontakt |
| `active` | Wahrheitswert | nein | Aktiv |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### einwilligungen.csv

Rechtsgrundlage je Kontakt und Zweck, mit Einwilligung und Widerruf.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `contact_id` | Kennung (UUID) → kontakte.csv | nein | Kontakt |
| `purpose_id` | Kennung (UUID) → verarbeitungszwecke.csv | nein | Zweck |
| `legal_basis` | Auswahl: `consent`, `contract`, `legal_obligation`, `vital_interest`, `public_task`, `legitimate_interest` | nein | Rechtsgrundlage nach Art. 6 Abs. 1 DSGVO |
| `consent_given` | Wahrheitswert | nein | Einwilligung erteilt |
| `source` | Text | ja | Herkunft der Angabe |
| `note` | Text | ja | Bemerkung |
| `granted_at` | Zeitpunkt | ja | Erteilt am |
| `withdrawn_at` | Zeitpunkt | ja | Widerrufen am |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### werbewidersprueche.csv

Werbewidersprüche (Art. 21 Abs. 3 DSGVO): die Sperrliste gegen Direktwerbung, eine Zeile je Kennung (Telefonnummer, E-Mail-Adresse oder Firmen-Domain) und Umfang. Sie gilt auch für Kontakte, die später angelegt werden, und bleibt bestehen, wenn der Kontakt gelöscht wird. Eine Zeile wird nie gelöscht, nur aufgehoben. Die Kennung selbst steht im System nur als Schlüsselhash, der nur in dieser Installation etwas bedeutet — er ist nicht in der Datei; hint zeigt sie absichtlich unvollständig. Wer die Sperrliste in ein anderes System übernimmt, trägt die Widersprüche dort anhand der Kontakte neu ein.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `kind` | Auswahl: `phone`, `email`, `domain` | nein | Art der Kennung: phone = Telefonnummer, email = E-Mail-Adresse, domain = Domain einer geschäftlichen E-Mail-Adresse (z. B. firma.de) |
| `scope` | Auswahl: `person`, `unternehmen` | nein | Umfang: person = Telefon und E-Mail der Person; unternehmen (Vorgabe) = dazu die Firmen-Domain (nie die eines Freemail-Anbieters) und die Telefonnummer ihrer Firma |
| `hint` | Text | ja | Die Kennung, absichtlich unvollständig (z. B. „+49 151 ••••• 78“, „a•••@firma.de“, „firma.de“); leer, sobald ein passender Kontakt gelöscht oder anonymisiert wurde |
| `objected_at` | Zeitpunkt | nein | Wann die Person widersprochen hat — nicht, wann es eingetragen wurde (von Hand mit Tagesangabe: Beginn dieses Tages, deutsche Zeit) |
| `source` | Auswahl: `portal`, `manual` | nein | Herkunft: portal = aus einem Verkaufsanruf, den das Partnerportal gemeldet hat, manual = von Hand im CRM eingetragen |
| `source_ref` | Text | ja | Bei portal die Kennung des Anrufs im liefernden System (external_id in anrufe.csv); sonst leer. Geleert, sobald ein passender Kontakt gelöscht oder anonymisiert wurde |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Wer eingetragen hat; leer beim nachträglichen Abgleich mit den Anrufen oder wenn der Benutzer gelöscht ist |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `review_due_at` | Zeitpunkt | nein | Wann gefragt wird, ob noch Direktwerbung betrieben wird: Widerspruch plus drei Jahre, nach jeder Bestätigung erneut drei Jahre |
| `lifted_at` | Zeitpunkt | ja | Aufgehoben am; leer = der Widerspruch gilt |
| `lifted_by` | Kennung (UUID) → benutzer.csv | ja | Wer aufgehoben hat; leer, wenn nicht aufgehoben oder der Benutzer gelöscht ist |
| `lift_grund` | Auswahl: `zurueckgenommen`, `irrtum` | ja | Grund des Aufhebens: zurueckgenommen = die Person hat ihren Widerspruch zurückgenommen, irrtum = nie widersprochen, falsch eingetragen; leer, wenn nicht aufgehoben |
| `lift_datum` | Datum | ja | Nur bei zurueckgenommen: der Tag (deutsche Zeit), an dem die Person zurückgenommen hat |
| `lift_nachweis` | Text | ja | Bei zurueckgenommen Form und Beleg der Rücknahme (z. B. „Mail vom 03.11.2026“), bei irrtum die Erklärung; leer, wenn nicht aufgehoben |

### aufgaben.csv

Aufgaben und Wiedervorlagen.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `title` | Text | nein | Titel |
| `notes` | Text | ja | Notizen (Freitext) |
| `due_at` | Zeitpunkt | ja | Fällig am |
| `status` | Auswahl: `open`, `done` | nein | Offen oder erledigt |
| `completed_at` | Zeitpunkt | ja | Erledigt am |
| `lead_id` | Kennung (UUID) → anfragen.csv | ja | Zugehörige Anfrage |
| `contact_id` | Kennung (UUID) → kontakte.csv | ja | Zugehöriger Kontakt |
| `owner_id` | Kennung (UUID) → benutzer.csv | ja | Zuständige Person |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `deleted_at` | Zeitpunkt | ja | In den Papierkorb gelegt am; leer = nicht gelöscht |

### notizen.csv

Notizen an Kontakten, Firmen, Anfragen, Deals und Objekten.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `object_type` | Auswahl: `contact`, `company`, `lead`, `deal`, `asset` | nein | Art des Datensatzes, an dem dies hängt |
| `record_id` | Kennung (UUID) | nein | Kennung des Datensatzes, an dem dies hängt (Datei je nach object_type) |
| `body` | Text | nein | Text der Notiz |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Angelegt von |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |
| `deleted_at` | Zeitpunkt | ja | In den Papierkorb gelegt am; leer = nicht gelöscht |

### beleg-dateien.csv

Abgelegte Beleg-PDFs: Größe und Fingerabdruck. Die Dateien selbst liefert das Dateipaket.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `document_id` | Kennung (UUID) → belege.csv | nein | Beleg |
| `sha256` | SHA-256-Prüfsumme | nein | SHA-256 der PDF-Datei |
| `bytes` | Ganzzahl: in Bytes | nein | Größe in Bytes |
| `created_at` | Zeitpunkt | nein | Abgelegt am |

### e-rechnungen.csv

Ausgestellte E-Rechnungen (XML): Spezifikation, Größe, Fingerabdruck.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `document_id` | Kennung (UUID) → belege.csv | nein | Rechnung oder Storno |
| `guideline_id` | Auswahl: `urn:cen.eu:en16931:2017`, `urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0` | nein | Kennung der Spezifikation (BT-24) |
| `sha256` | SHA-256-Prüfsumme | nein | SHA-256 der XML-Datei |
| `bytes` | Ganzzahl: in Bytes | nein | Größe in Bytes |
| `generator_version` | Text | nein | Fassung des Erzeugers der XML |
| `created_at` | Zeitpunkt | nein | Ausgestellt am |

### dateien.csv

Hochgeladene Dateien: Name, Typ, Größe. Die Dateien selbst liefert das Dateipaket.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `object_type` | Auswahl: `contact`, `company`, `lead`, `deal`, `asset` | nein | Art des Datensatzes, an dem dies hängt |
| `record_id` | Kennung (UUID) | nein | Kennung des Datensatzes, an dem dies hängt (Datei je nach object_type) |
| `filename` | Text | nein | Ursprünglicher Dateiname |
| `content_type` | Text | nein | MIME-Typ beim Hochladen |
| `size_bytes` | Ganzzahl: in Bytes | nein | Größe in Bytes |
| `uploaded_by` | Kennung (UUID) → benutzer.csv | ja | Hochgeladen von |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `deleted_at` | Zeitpunkt | ja | In den Papierkorb gelegt am; leer = nicht gelöscht |

### mails.csv

Ein- und ausgehende E-Mails zu Kontakten.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `contact_id` | Kennung (UUID) → kontakte.csv | ja | Zugehöriger Kontakt |
| `direction` | Auswahl: `out`, `in` | nein | out = von Ihnen, in = an Sie |
| `to_email` | E-Mail-Adresse | nein | Empfängeradresse |
| `from_email` | E-Mail-Adresse | ja | Absenderadresse (eingehend) |
| `sender_address` | E-Mail-Adresse | ja | Postfach, aus dem gesendet wurde |
| `keine_werbung` | Wahrheitswert | nein | Beim Schreiben bestätigt, dass die Mail keine Werbung und keine werblichen Zusätze enthält — verlangt bei einer Mail oder einem Angebot an eine Person, die der Werbung widersprochen hat (werbewidersprueche.csv), nicht bei Rechnung, Storno und Auftragsbestätigung; ohne die Bestätigung geht eine solche Mail nicht hinaus. false = nicht bestätigt, so auch bei eingegangenen Mails und jeder Mail, die vor dem 01.11.2026 geschrieben wurde |
| `subject` | Text | nein | Betreff |
| `body` | Text | nein | Text |
| `status` | Auswahl: `pending`, `sent`, `failed`, `dead`, `received` | nein | Versandstand; received = eingegangen |
| `attempts` | Ganzzahl | nein | Anzahl Versandversuche |
| `last_error` | Text | ja | Letzte Fehlermeldung |
| `provider_message_id` | Text | ja | Kennung der Nachricht (Message-ID) |
| `in_reply_to_id` | Kennung (UUID) → mails.csv | ja | Antwort auf diese Mail |
| `document_id` | Kennung (UUID) → belege.csv | ja | Mit dieser Mail verschickter Beleg |
| `sent_at` | Zeitpunkt | ja | Versandt am |
| `created_by` | Kennung (UUID) → benutzer.csv | ja | Angelegt von |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### mail-anhaenge.csv

Welche Mail welchen Beleg als Anhang trug — Verweis, Dateiname, Größe, Fingerabdruck.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `email_id` | Kennung (UUID) → mails.csv | nein | Mail |
| `position` | Ganzzahl | nein | Reihenfolge der Anhänge |
| `document_id` | Kennung (UUID) → belege.csv | nein | Beleg |
| `variant` | Auswahl: `pdf`, `einvoice` | nein | pdf = Beleg-PDF (beleg-dateien.csv), einvoice = XML der E-Rechnung (e-rechnungen.csv) |
| `filename` | Text | nein | Dateiname im Anhang |
| `content_type` | Text | nein | MIME-Typ |
| `bytes` | Ganzzahl: in Bytes | nein | Größe in Bytes |
| `sha256` | SHA-256-Prüfsumme | nein | SHA-256 der Datei |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### zusatzfelder.csv

Selbst angelegte Zusatzfelder je Datensatzart.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `object_type` | Auswahl: `contact`, `company`, `lead`, `deal`, `asset` | nein | Datensatzart |
| `key` | Text | nein | Technischer Schlüssel |
| `label` | Text | nein | Beschriftung |
| `type` | Auswahl: `text`, `long_text`, `number`, `currency`, `date`, `datetime`, `checkbox`, `dropdown`, `multi_select`, `phone`, `email`, `url` | nein | Feldtyp |
| `options` | JSON | ja | Auswahlmöglichkeiten als JSON-Array von Texten (nur Auswahlfelder) |
| `required` | Wahrheitswert | nein | Pflichtfeld |
| `position` | Ganzzahl | nein | Reihenfolge |

### zusatzfeld-werte.csv

Werte der Zusatzfelder.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `definition_id` | Kennung (UUID) → zusatzfelder.csv | nein | Zusatzfeld |
| `record_id` | Kennung (UUID) | nein | Datensatz (Art laut zusatzfelder.csv object_type) |
| `value` | JSON | ja | Wert als JSON: Text in Anführungszeichen, Zahl, true/false, Mehrfachauswahl als Array |

### gespeicherte-ansichten.csv

Gespeicherte Ansichten (Filter) der Listen.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `owner_id` | Kennung (UUID) → benutzer.csv | nein | Angelegt von |
| `scope` | Auswahl: `contacts`, `leads`, `deals`, `tasks`, `reports`, `calls`, `assets` | nein | Liste, zu der die Ansicht gehört |
| `name` | Text | nein | Name |
| `params` | JSON | nein | Filter als JSON-Objekt (Name → Wert) |
| `is_shared` | Wahrheitswert | nein | Mit allen geteilt |
| `is_default` | Wahrheitswert | nein | Standardansicht |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### aenderungshistorie.csv

Änderungsprotokoll: wer wann was getan hat.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `actor_id` | Kennung (UUID) → benutzer.csv | ja | Handelnde Person; leer = System |
| `action` | Text | nein | Handlung (z. B. contact.created) |
| `entity_type` | Text | ja | Art des betroffenen Datensatzes |
| `entity_id` | Kennung (UUID) | ja | Betroffener Datensatz |
| `metadata` | JSON | ja | Angaben zur Handlung als JSON-Objekt |
| `ip` | Text | ja | IP-Adresse der Anfrage, falls erfasst |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### aufbewahrungsregeln.csv

Aufbewahrungs- und Löschregeln je Datenart.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `entity_type` | Auswahl: `contact`, `booking_contact`, `call`, `lead`, `appointment`, `contact_email`, `note`, `attachment` | nein | Datenart |
| `retention_days` | Ganzzahl: in Tagen | nein | Aufbewahrungsfrist in Tagen |
| `action` | Auswahl: `soft_delete`, `hard_delete`, `anonymize`, `pseudonymize` | nein | Was nach Ablauf geschieht |
| `basis` | Auswahl: `created`, `activity` | nein | Frist ab Anlage oder ab letzter Aktivität |
| `active` | Wahrheitswert | nein | Aktiv |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |

### loeschauftraege.csv

Nachweis durchgeführter Löschungen und Anonymisierungen.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `entity_type` | Text | nein | Datenart (z. B. contact, call) |
| `entity_id` | Kennung (UUID) | ja | Betroffener Datensatz |
| `action` | Text | nein | Durchgeführte Maßnahme (u. a. soft_delete, hard_delete, anonymize, pseudonymize, kept_legal_obligation) |
| `status` | Auswahl: `done`, `failed` | nein | Erledigt oder fehlgeschlagen |
| `reason` | Text | ja | Anlass (z. B. retention, dsr) |
| `error` | Text | ja | Fehlermeldung |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### systemereignisse.csv

Ereignisse im System (Zeitleiste, Auslöser für Automatisierungen und Webhooks).

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `event_type` | Text | nein | Ereignis (z. B. deal.stageChanged) |
| `aggregate_type` | Text | nein | Art des betroffenen Datensatzes |
| `aggregate_id` | Kennung (UUID) | ja | Betroffener Datensatz |
| `contact_id` | Kennung (UUID) → kontakte.csv | ja | Zugehöriger Kontakt |
| `payload` | JSON | ja | Inhalt des Ereignisses als JSON-Objekt |
| `actor_id` | Kennung (UUID) → benutzer.csv | ja | Auslösende Person; leer = System |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### benutzer.csv

Benutzerkonten — ohne Passwort und ohne Zwei-Faktor-Geheimnis.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `email` | E-Mail-Adresse | nein | Anmeldeadresse |
| `display_name` | Text | ja | Anzeigename |
| `status` | Auswahl: `active`, `disabled` | nein | Aktiv oder gesperrt |
| `last_login_at` | Zeitpunkt | ja | Letzte Anmeldung |
| `is_platform_admin` | Wahrheitswert | nein | Konto des Betreibers (NexAI) |
| `theme_preference` | Auswahl: `system`, `light`, `dark` | nein | Gewähltes Aussehen (system, hell, dunkel) |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `deleted_at` | Zeitpunkt | ja | In den Papierkorb gelegt am; leer = nicht gelöscht |

### rollen.csv

Rollen.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `name` | Text | nein | Name |
| `description` | Text | ja | Beschreibung |
| `is_system` | Wahrheitswert | nein | Mitgelieferte Rolle |

### rollenrechte.csv

Rechte je Rolle.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `role_id` | Kennung (UUID) → rollen.csv | nein | Rolle |
| `permission_key` | Text | nein | Recht (z. B. contacts.read); * = alle Rechte |

### benutzerrollen.csv

Welche Person welche Rolle hat.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `user_id` | Kennung (UUID) → benutzer.csv | nein | Person |
| `role_id` | Kennung (UUID) → rollen.csv | nein | Rolle |

### vertriebspartner.csv

Vertriebspartner, wie sie aus dem Partnerportal gemeldet werden.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `external_id` | Text | nein | Kennung im Partnerportal |
| `partner_no` | Ganzzahl | ja | Partnernummer |
| `display_name` | Text | nein | Name |
| `email` | E-Mail-Adresse | ja | E-Mail-Adresse |
| `phone` | Telefonnummer | ja | Telefonnummer |
| `sales_role` | Auswahl: `setter`, `closer`, `both` | ja | Rolle im Vertrieb |
| `level` | Auswahl: `junior`, `senior` | ja | Stufe |
| `senior_since` | Datum | ja | Stufe senior seit |
| `probation_start` | Datum | ja | Beginn der Probezeit |
| `status` | Auswahl: `active`, `inactive` | nein | Aktiv oder inaktiv |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### einstellungen.csv

Einstellungen der Organisation: Absender auf Belegen, Bankverbindung, Schalter. Ohne Logo — das steht als Bilddatei im Dateipaket (einstellungen/logo.…).

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `tenant_id` | Kennung (UUID) | nein | Kennung der Organisation |
| `notify_email` | E-Mail-Adresse | ja | Adresse für Benachrichtigungen |
| `lead_notifications_enabled` | Wahrheitswert | nein | Benachrichtigung bei neuen Anfragen |
| `brand_name` | Text | ja | Angezeigter Name |
| `brand_color` | Text | ja | Markenfarbe als #RRGGBB |
| `currency` | Auswahl: `EUR`, `CHF` | nein | Währung (ISO 4217) |
| `company_name` | Text | ja | Firmenname |
| `company_street` | Text | ja | Straße und Hausnummer |
| `company_postal_code` | Text | ja | Postleitzahl |
| `company_city` | Text | ja | Ort |
| `company_country` | Text | ja | Land (Name) |
| `country_code` | Ländercode | ja | Land als Code |
| `company_phone` | Telefonnummer | ja | Telefonnummer |
| `company_email` | E-Mail-Adresse | ja | E-Mail-Adresse |
| `company_website` | Internetadresse | ja | Internetseite |
| `vat_id` | Text | ja | USt-IdNr. |
| `tax_number` | Text | ja | Steuernummer |
| `register_id` | Text | ja | Handelsregisternummer |
| `invoice_contact_name` | Text | ja | Ansprechpartner für Rechnungen |
| `company_legal` | Text | ja | Pflichtangaben (Fußzeile) |
| `bank_name` | Text | ja | Bank |
| `iban` | Text | ja | IBAN |
| `bic` | Text | ja | BIC |
| `small_business` | Wahrheitswert | nein | Kleinunternehmer (§ 19 UStG) |
| `payment_terms_days` | Ganzzahl: in Tagen | nein | Zahlungsziel in Tagen |
| `einvoice_enabled` | Wahrheitswert | nein | E-Rechnung eingeschaltet |
| `billing_enabled` | Wahrheitswert | nein | Abo-Abrechnung eingeschaltet |
| `billing_auto_enable_from` | Datum | ja | Gespiegelte Verträge ab diesem Tag automatisch als Entwurf abrechnen |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |

### webhooks.csv

Ausgehende Webhooks — ohne das Signaturgeheimnis.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `url` | Internetadresse | nein | Zieladresse |
| `event_types` | JSON | nein | Abonnierte Ereignisse als JSON-Array von Texten |
| `active` | Wahrheitswert | nein | Aktiv |
| `description` | Text | ja | Beschreibung |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### integrationen.csv

Verbundene Dienste — ohne Geheimnis und ohne Konfiguration.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `provider` | Auswahl: `vapi`, `n8n`, `nextime` | nein | Dienst |
| `name` | Text | nein | Name |
| `active` | Wahrheitswert | nein | Aktiv |
| `created_at` | Zeitpunkt | nein | Angelegt am |

### standorte.csv

Standorte (Filialen).

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `name` | Text | nein | Name |
| `active` | Wahrheitswert | nein | Aktiv |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |

### standort-zuordnung.csv

Welche Person zu welchem Standort gehört.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `location_id` | Kennung (UUID) → standorte.csv | nein | Standort |
| `user_id` | Kennung (UUID) → benutzer.csv | nein | Person |
| `added_at` | Zeitpunkt | nein | Zugeordnet am |

### teams.csv

Teams.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `name` | Text | nein | Name |
| `lead_id` | Kennung (UUID) → benutzer.csv | ja | Teamleitung |
| `created_at` | Zeitpunkt | nein | Angelegt am |
| `updated_at` | Zeitpunkt | nein | Zuletzt geändert am |

### team-zuordnung.csv

Wer zu welchem Team gehört.

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `team_id` | Kennung (UUID) → teams.csv | nein | Team |
| `user_id` | Kennung (UUID) → benutzer.csv | nein | Person |
| `added_at` | Zeitpunkt | nein | Zugeordnet am |

### hinweise.csv

Hinweise des Systems an die Verwaltung (z. B. Betriebsstörungen).

| Spalte | Typ und Format | Kann leer sein | Bedeutung |
|---|---|---|---|
| `id` | Kennung (UUID) | nein | Kennung des Datensatzes |
| `severity` | Auswahl: `info`, `warning`, `error` | nein | Schwere |
| `source` | Text | nein | Herkunft des Hinweises |
| `message` | Text | nein | Meldungstext |
| `message_key` | Text | ja | Schlüssel der Meldung (für Übersetzungen) |
| `message_params` | JSON | ja | Werte zur Meldung als JSON-Objekt |
| `acknowledged_at` | Zeitpunkt | ja | Zur Kenntnis genommen am |
| `created_at` | Zeitpunkt | nein | Angelegt am |
