Datenschutzerklärung
1. Verantwortlicher
Verantwortlich für die Datenverarbeitung auf dieser Website ist:
NEULAND. GmbH, Schmiedeweg 4, 51789 Lindlar
E-Mail: datenschutz@neuland-agentur.com
2. Hosting und Infrastruktur
Diese Website wird bei Vercel Inc. gehostet. Die Datenbank wird bei Supabase (AWS eu-central-1, Frankfurt) betrieben. Die Datenverarbeitung erfolgt auf Grundlage von Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an einer zuverlässigen Bereitstellung).
3. Auftragsverarbeiter (Sub-Processors)
Zur Erbringung unserer Dienste setzen wir folgende Auftragsverarbeiter ein:
| Anbieter | Zweck | Daten | Standort | DPA |
|---|---|---|---|---|
| Supabase Inc. | Datenbank, Authentifizierung, Datei-Speicher, Echtzeit-Kommunikation | Nutzerdaten, Projektdaten, Dateien | AWS eu-central-1 (Frankfurt) | Link |
| Vercel Inc. | Hosting, Edge Functions, Cron Jobs, Custom Domains | IP-Adresse, Request-Daten, Domain-Namen | Global (EU-bevorzugt) | Link |
| Vimeo, Inc. | Video-Embed-Player für CMS Page Builder Video-Atom (PROJ-847): Wenn ein Agentur-Mitarbeiter im CMS Page Builder ein Video-Element vom Typ `vimeo` einbettet und im Editor anzeigt, wird im Browser des eingeloggten Mitarbeiters ein iframe von `https://player.vimeo.com/video/{videoId}` geladen. Vimeo erhält dabei IP-Adresse + User-Agent des Mitarbeiters sowie die abgerufene Video-ID. Übermittlung erfolgt ausschließlich im authentifizierten Editor-Kontext (Workspace-Mitarbeiter mit Beschäftigungsverhältnis zur Agentur, Art. 88 BDSG / Art. 6 Abs. 1 lit. f DSGVO). Vimeo kann beim Player-Laden Cookies setzen, sofern der Browser sie zulässt. Hinweis: Aktuell werden Paket-3-Atome (inkl. Video) ausschließlich im Editor gerendert — die Anbindung an den öffentlichen Renderer (mit dann notwendigem 2-Klick-Consent-Pattern für End-Besucher) erfolgt in einem separaten Folge-Paket. | IP-Adresse, User-Agent, Vimeo-Video-ID (öffentliche Identifikatoren auf vimeo.com) | USA (Standardvertragsklauseln / DPF) | Link |
| Resend Inc. | Transaktionaler E-Mail-Versand, Inbound-E-Mail-Empfang (Shop-CRM Kundenberatung), Sales-Portfolio-Versand mit PDF-Anhang (PROJ-489 Phase 4 — Empfänger-E-Mail, Empfänger-Name, Reply-To-Adresse, Betreff, HTML-/Text-Body, Portfolio-PDF-Anhang) inkl. Open-Tracking via Resend-Webhook (resend_email_id, email_opened_at, email_open_count auf sales_portfolios), SOP-Einladungs-Versand (PROJ-502 — Empfänger-E-Mail, SOP-Titel, sicherer Einlöse-Link mit ablaufendem Token), Interview-Einladungs-Versand (PROJ-635 — Empfänger-E-Mail des Experten, Empfänger-Name, Interview-Topic, sicherer Einlöse-Link mit 30-Tage-Token zum öffentlichen Interview-Formular), Beleg-Versand AB/Angebot/Rechnung (PROJ-901 — Empfänger-E-Mail-Adresse(n) inkl. zusätzliche TO-Empfänger und optionale CC/BCC-Adressen, Empfänger-Name, Reply-To-Adresse der versendenden Agentur-Person (PROJ-928 — geschäftliche Mitarbeiter-E-Mail, damit Kundenantworten direkt beim Vertrieb landen), Betreff im Format Belegtyp Nummer vom Datum, HTML-Body im NEULAND.-Standardtext und Dankesgruß sowie ggf. SEPA-Lastschrift-Hinweis. Vertragsdokumente AVV (Art. 28 DSGVO) + AGB der Plattform werden seit PROJ-928 ausschließlich an der Auftragsbestätigung bereitgestellt — als Links auf die öffentlichen PDF-Versionen in deren Online-Ansicht; bei Angeboten und Rechnungen werden AVV/AGB NICHT versendet. Es handelt sich um statische Dokumente ohne Empfänger-PII. Versand erfolgt über bestehendes sendTrackedEmail-Pattern mit Resend-Open-Tracking auf order_confirmations/quotes/invoices), Nachfreigabe-E-Mail bei Variantenwechsel (PROJ-1451 — Empfänger-E-Mail des Kunden-Kontakts, Aufgabentitel, Vorher/Jetzt-Variante inkl. Preis, sicherer login-freier Einlöse-Link mit 30-Tage-Token zur öffentlichen Nachfreigabe-Seite), Inbound-E-Mail-Empfang für die Contao-Formular-Datenquelle (PROJ-2167, Alias-Modell — jede Contao-Integration erhält eine automatisch erzeugte, nicht erratbare eindeutige Empfänger-Adresse `contao-<token>@post.neuland-agentur.com`; der Kunde leitet die Contao-Benachrichtigungsmail seiner Website an genau diese Adresse weiter. Die Zuordnung zur richtigen Kunden-Datenquelle erfolgt AUSSCHLIESSLICH deterministisch über diese provider-authentifizierte Empfänger-Adresse — kein Absender-/Betreff-Matching, kein Fehlrouting-Risiko. Die extrahierten Formularfelder werden über den Datenquellen-Kontrakt angehängt (source_channel 'email'); eine Anfrage gelangt strukturell nie in die Agentur-eigene Sales-Pipeline (sales_deals/leads/quotes). Die Roh-E-Mail wird in NEULAND. OS NICHT dauerhaft gespeichert — nur die extrahierten Felder (seit PROJ-2271 einschließlich des E-Mail-Betreffs, auf 500 Zeichen gekappt, als Datengrundlage der Betreff-Dimension im Spalten-Katalog; Impressum-/Signatur-Zeilen aus dem Mail-Body werden dabei nicht mehr als Formularfelder in den Auswertungs-Katalog übernommen und wurden aus Bestandsdaten entfernt — Datenminimierung) sowie PII-redigierte Reject-Logs (Absender-Domain, gekürzter redigierter Betreff, redigierter Fehlertext); die Retention der Roh-Mail liegt bei Resend. Der AVV mit Resend (Art. 28 DSGVO) deckt laut Resend-DPA sowohl Versand als auch Empfang ab; primäre Verarbeitung USA/SCC) | E-Mail-Adresse, Name, E-Mail-Inhalte (bei Inbound-Empfang: Betreff, Body, Anhänge), Portfolio-PDF-Anhänge (sichtbar Empfänger-Name + Empfänger-E-Mail im PDF), Resend-Message-ID + Open-Events, statische Plattform-Vertragsdokumente AVV+AGB (seit PROJ-928 nur an der Auftragsbestätigung als verlinkte PDFs in deren öffentlicher Online-Ansicht; bei Angeboten/Rechnungen nicht mehr versendet), Nachfreigabe-E-Mail-Inhalte (PROJ-1451 — Empfänger-E-Mail, Aufgabentitel, Vorher/Jetzt-Preis, Einlöse-Link), Contao-Formular-Datenquelle E-Mail-Intake (PROJ-2167 — im weitergeleiteten E-Mail-Body enthaltene Website-Formular-Felder des Endbesuchers, je nach Formular z. B. Name, E-Mail-Adresse, Telefonnummer, Nachricht/Freitext; im Ereignis-Log nur Absender-Domain + gekürzter, PII-redigierter Betreff) | USA (SCCs) | Link |
| Anthropic PBC | KI-Assistent, SSOT-Vorschläge, benutzerdefinierte KI-Assistenten, Prompt-Builder & Prompt-Optimierer (KI-gestützte System-Prompt-Erstellung und -Verbesserung durch iterativen Admin-Chat — ephemer, keine Datenpersistenz), KI-Mitarbeiter, KI-Buchhalter, OCR-Dokumentenerkennung, KI-gestützte Asset-Text-Generierung, Marketing-Strategie-Wizard, KI-Seitenersteller, KI-Workflow-Pipelines, Meeting-Zusammenfassung, Sales Deal Zusammenfassung (PROJ-1188, Claude Sonnet 4.5 — Gesprächsauswertungen/Gesprächsnotizen, interne Notizen, Deal-Kommunikation, Aktivitäten, Angebote und Coaching-Feedback werden transient an Anthropic übermittelt und als KI-generierter Zusammenfassungstext in deal_sales_summaries gespeichert; kein Training, kein Auto-Versand), Web-Recherche-Qualifizierung (KI-gestützte Filterung öffentlicher Unternehmensdaten), Gmail-Kategorisierung & Zusammenfassung, KI-Antwortvorschlag im Postfach (PROJ-1135 Phase 1, Claude Sonnet 4.6 - erzeugt aus der eingegangenen E-Mail einen editierbaren Antwortentwurf; Input: Betreff und Body der Original-Mail, transient, kein Training, kein Auto-Versand), Persoenliches E-Mail-Stil-Profil (PROJ-1135 Phase 2, Claude Sonnet 4.6 - leitet auf Knopfdruck aus den eigenen gesendeten Mails des Nutzers ein Stil-Profil ab; transient, nur Stilmerkmale ohne Inhalts- oder Namensuebernahme, kein Training, nutzergebundene Speicherung in user_email_writing_styles, jederzeit loeschbar), KI-Antwortvorschlag fuer Kommentare & @Mentions (PROJ-2349, Claude Sonnet 4.6 - erzeugt bei einer @Erwaehnung oder bei einer Antwort auf den eigenen Kommentar ohne @Erwaehnung (PROJ-2399, pro Nutzer abschaltbar in den persoenlichen Einstellungen) proaktiv einen editierbaren Antwortentwurf mit Confidence-Angabe fuer die betroffene Person; Input: PII-sanierter Kommentar-Thread plus Aufgaben-/Projekt-Stammdaten, transient, kein Training, kein Auto-Versand, Speicherung des Entwurfs strikt empfaenger-gebunden in comment_reply_suggestions), Schreibstil-Kalibrierung fuer Kommentar-Antwortvorschlaege (PROJ-2357, Claude Sonnet 4.6 - analysiert einmalig pro Nutzer eine PII-sanierte Stichprobe der eigenen Bestandskommentare inkl. importierter Alt-Kommentare und leitet daraus einen Ton-Vorschlag formell/locker/direkt ab; transient, kein Training, gespeichert wird nur Ton-Wert plus kurze Begruendung in user_comment_reply_settings, wirksam erst nach aktiver Bestaetigung durch den Nutzer), Stil-Mimikry fuer Kommentar-Antwortvorschlaege (PROJ-2362, Claude Sonnet 4.6 - woechentlicher Cron verdichtet die neuesten bis zu 2.000 eigenen Bestandskommentare des Nutzers per Map-Reduce-Verfahren zu einem Schreibstil-Profil aus max. 6.000 Zeichen Freitext (Wortwahl, Satzbau, typische Wendungen, Emoji-/Anrede-Gewohnheiten; ausdruecklich ohne Uebernahme von Inhalten, Fakten oder Namen); Profil wird nutzergebunden in user_comment_reply_settings.style_profile_text gespeichert, entsteht nur ab 5 eigenen Bestandskommentaren und nur solange 'Proaktive Antwortvorschlaege' aktiv ist, fliesst ausschliesslich in die kuenftigen eigenen Antwortvorschlaege desselben Nutzers ein, transient an Anthropic uebermittelt, kein Training, jederzeit ueber Abschalten der proaktiven Antwortvorschlaege sowie durch Loeschung mit den Bestandsfeldern deaktivierbar), Voice-Diktat-Optimierung (persönlicher Schreibassistent), Voice-Agent-Klassifizierung (Intent-Erkennung für mobile Spracheingabe), Feature-Briefing Startscreen-Anhänge (PROJ-889): Bilder/PDFs/Texte die der PM vor Chat-Start hochlädt werden transient via Vision-/Document-Parse (Claude Sonnet 4.6) analysiert — Anhänge können PII enthalten wenn PM Screenshots mit Kundendaten hochlädt; kein Training, kein Speichern bei Anthropic, KI-Briefing-Assistent für Aufgabenbeauftragungen im Kundenworkspace, Texteditor PROJ-837 SSOT-Check (Claude Haiku 4.5 — strukturierter Tool-Use-Output 'report_text_editor_ssot_check' mit 6 Dimensionen status+hint; Input: Editor-Inhalt max. 6000 Zeichen + SSOT-Kontext-Snapshot; transient, kein Training), Texteditor PROJ-838 KI-Targeted-Element-Change (Claude Haiku 4.5 — strukturierter Tool-Use-Output 'targeted_change' mit kind='change' oder kind='clarification'; Input: aktueller editor_state.blocks + natürlichsprachige User-Instruction max. 2000 Zeichen + briefing_snapshot_json-Kontext aus content_intelligence_jobs; transient, kein Training, Prompt-Caching via cache_control:ephemeral), Texteditor PROJ-839 KI-Variantengenerierung und SEA-RSA-Generator (Claude Haiku 4.5 — Social-Media-Post-Varianten in EINEM Multi-Variant-Call inkl. unterschiedlicher Tonalität/Winkel, Bing-RSA-Headlines max. 30 Zeichen pro Item / 4 Descriptions max. 90 Zeichen pro Item, sowie Element-spezifische Targeted-Changes für Headlines/Descriptions/Paths/Final-URL; Input: SSOT-Snapshot + Plattform-Constraints aus text_editor_platforms + aktueller Post-/Feld-Inhalt + optional briefing_snapshot_json target_keyword; transient, kein Training, Prompt-Caching via cache_control:ephemeral), Cluster-CI-Analyse PROJ-1116 (gebündelte Content-Intelligence-Analyse auf Cluster-Ebene: cluster_ci_jobs koordiniert N Einzel-content_intelligence_jobs eines Keyword-Clusters und speichert nur Job-Metadaten — workspace_id, cluster_id, contact_id, auslösender Nutzer, Batch-Konfig (Zielregion/Zielsprache/Workflow-Modus); keine neue personenbezogene Datenkategorie gegenüber dem bestehenden CI-Processing, keine neuen Auftragsverarbeiter, Löschung via ON DELETE CASCADE auf contact_id), Texteditor PROJ-841 KI-Fragen-Engine (Claude Haiku 4.5 — proaktive Hinweise während des Schreibens via strukturiertem Tool-Use-Output 'report_proactive_hints' mit max. 3 hints[] {id, type ∈ competitor|engagement|keyword|tonality|structure, message ≤500 Zeichen, severity ∈ info|warning|opportunity}; Input: editor_state-Slice max. 4000 Zeichen + SSOT-Snapshot + Plattform-Best-Practices aus text_editor_platforms + optional briefing_snapshot_json; max_tokens 800, 8s Timeout, Rate-Limit 6/min pro (workspace, user); transient, kein Training, Prompt-Caching via cache_control:ephemeral), Texteditor PROJ-890 CI-Vorausfüllung FAQ-Normalisierung (Claude Haiku 4.5 — strukturierter JSON-Output mit normalisierten FAQ-Einträgen aus SERP-PAA-Fragen; Input: max. 10 Roh-PAA-Fragen aus briefing_snapshot_json + Tone-of-Voice + primäres Keyword + Marketingziel + H2-Outline; kein PII — alle Inputs sind editorielle CI-Daten ohne Personenbezug; max_tokens 1500, 12s Timeout, Rate-Limit 10/min pro (workspace, user); transient, kein Training, ai_feature-Enum-Wert `text_editor_faq_normalization`), Texteditor PROJ-1306 CI-Vorausfüllung Fließtext-Generierung (Claude Sonnet 4.6 — generiert pro H2-Überschrift einen Fließtext-Entwurf für die BODY-TEXT-Blöcke; Input: H2-Outline + must_cover_topics + primäres/sekundäre Keywords + Tonalität + verifizierte Fakten aus briefing_snapshot_json; kein PII — alle Inputs sind editorielle CI-Daten ohne Personenbezug; max_tokens 6000, 45s Timeout, Rate-Limit 10/min pro (workspace, user); transient, kein Training, ai_feature-Enum-Wert `text_editor_body_generation`), Feature-Briefing-Systemabgleich (PROJ-811): KI-gestütztes Mapping von PM-Beschreibungen auf konkrete DB-Tabellen und -Spalten via Claude Haiku 4.5. Übermittelt werden: (a) Freie PM-Beschreibung des Features/Bugs (interner Inhalt — kein End-Nutzer-PII; Erstellung ausschließlich durch eingeloggte Workspace-Mitarbeiter), (b) gecachter DB-Schema-Snapshot (50 public-Tabellen, nur Tabellen-/Spalten-Namen + Datentyp, KEINE Werte/Inhalte/PII — sensible Spalten wie *_encrypted, *_token, *_secret werden ausgefiltert). Output: strukturiertes JSON-Array mit Feldzuordnungen (PM-Begriff → tabellen.spalte mit Confidence-Score). Transient, kein Training. Feature-Briefing-Mockup-Generierung (PROJ-813): KI-gestützte JSX-Code-Generierung via Claude Sonnet 4.6 auf Basis statischem shadcn-Komponenten-Snapshot. Übermittelt werden: (a) Freie PM-Beschreibung der Design-Anpassung (interner Inhalt, kein End-Nutzer-PII; Erstellung ausschließlich durch eingeloggte Workspace-Mitarbeiter), (b) statischer shadcn/ui-Komponenten-Snapshot (60 Komponenten-Namen + Import-Pfade — kein Personenbezug), (c) bisherige Iterations-History aller Feedback-Texte derselben Briefing-Session. Output: einzelnes JSX-Fragment ohne State, ohne Imports, max 10 Iterationen pro Briefing. Transient, kein Training, Prompt-Caching via cache_control:ephemeral ab Iteration 3. Feature-Briefing-Akzeptanzkriterien-Vorschlag (PROJ-811 Bugfix 2026-05-27): KI-gestützte Generierung von 5–8 übergeordneten Akzeptanzkriterien via Claude Haiku 4.5. Übermittelt werden: (a) Freie PM-Beschreibung des Features/Bugs (interner Inhalt, kein End-Nutzer-PII; Erstellung ausschließlich durch eingeloggte Workspace-Mitarbeiter), (b) Titel und Beschreibungstexte der bereits definierten Deployment-Schritte (interner Inhalt), (c) optional bereits vorhandene Akzeptanzkriterien als Anti-Duplikat-Hinweis im Prompt. Output: JSON-Array von outcome-orientierten deutschen Kriterien-Strings (jeweils ≤ 200 Zeichen). Transient, kein Training, Prompt-Caching via cache_control:ephemeral, 30s Timeout. Token-Tracking via logTokenUsage(feature=feature_briefs_suggest_acs). Feature-Briefing Unified Entry Point (PROJ-842): Drei KI-Endpunkte — (a) analyze-and-create: PM-Freitexteingabe (max 20.000 Zeichen, intern, kein End-Nutzer-PII) sowie optionale Dateianhänge (PNG/JPG/WebP/PDF/TXT/MD, max. 10 Dateien x 10 MB, temporär 24h in Supabase Storage EU, danach Cleanup-Cron) — PROJ-889: Bild- und Dokumentinhalt transient via Claude Sonnet Vision-/Document-Parse analysiert (kein Training; Anhänge können PII enthalten wenn PM Screenshots mit Kundendaten hochlädt) + gecachter NEULAND-OS Modul-Katalog (Modul-Labels, keine Werte/PII) zu Branch-Erkennung + Reifegrad-Analyse + erste Assistent-Antwort, via Claude Haiku 4.5 (bzw. Claude Sonnet 4.6 bei Bild-/PDF-Anhang); (b) chat: PM-Turn-Text (max 2.000 Zeichen) + conversation_log + Modul-Katalog zu Assistent-Antwort + transition_ready-Signal, via Claude Opus 4.8 (PROJ-1377, zuvor Claude Sonnet 4.6 seit PROJ-860 — komplexeste Reasoning-Arbeit des Dialogs); (c) transition-to-wizard: conversation_log + entry_input zu Briefing-Objekt (title, description, deployment_steps, ACs), via Claude Haiku 4.5. Alle drei: 45s Timeout, transient, kein Training, Prompt-Caching via cache_control:ephemeral, Token-Tracking via logTokenUsage(feature=feature_briefs_analyze_and_create / feature_briefs_chat / feature_briefs_transition_to_wizard). Feature-Briefing-Synthese (PROJ-1377, zuvor PROJ-811/813 — feature_briefs_synthesis): Erzeugt aus dem vollständigen conversation_log + entry_input das finale Briefing-Dokument (title, description, deployment_steps, acceptance_criteria, edge_cases) via Claude Opus 4.8. Übermittelt werden ausschließlich bereits im Chat erfasste interne PM-Inhalte (kein zusätzliches End-Nutzer-PII gegenüber den Chat-Endpunkten). Transient, kein Training, Prompt-Caching via cache_control:ephemeral, Token-Tracking via logTokenUsage(feature=feature_briefs_synthesis). Marktpotenzial-Analyse auf der Angebots-Signing-Seite (öffentlicher KI-Chat, transient — keine Datenpersistenz), Identity-Anchor-Input-Validierung (anchor_validity_check: semantische Spam-Erkennung via Claude Haiku — nur Eingabelänge und Anchor-Name, keine Originalinhalte), Identity-Anchor-OCR (anchor_ocr: Bilderkennung via Claude Sonnet Vision — Bild nur in-memory, nicht gespeichert), Agency Brain Kampagnen-Analyse (vollständig anonymisierte Kampagnenmetriken — keine personenbezogenen Daten, keine Workspace-IDs oder Unternehmensnamen), Fokus-Queue-Priorisierung (focus_queue_ranking: Aufgaben-Titel und Benachrichtigungs-Titel werden transient an Claude Haiku zur Dringlichkeits-Priorisierung gesendet — Titel können Personenbezug enthalten, kein PII-Scrubbing, da Inhalte vom eingeloggten Mitarbeiter selbst erstellt wurden, keine dauerhafte Speicherung durch Anthropic), Component Lab (PROJ-409): KI-gestützte Generierung von React-Komponenten (TSX) aus Admin-Freitext-Briefings — Prompts werden direkt an Claude Sonnet übermittelt; Prompts sind interne Arbeitsanweisungen ohne Kunden-PBD-Scrubbing, da sie vom eingeloggten Admin selbst erstellt werden, Semantische Feld-Normalisierung (PROJ-410): Rohe HTML-Formular-Feldnamen (z. B. "FNAME", "vorname", "prenom") und optionale field_type-Attribute werden an Claude Haiku gesendet um einen semantischen Standardschlüssel zu klassifizieren (STD_FIRST_NAME, STD_EMAIL, STD_PHONE, ...). Übermittelt werden ausschließlich anonyme Feld-IDs — keine Eingabewerte, keine Kontaktinformationen, kein Personenbezug. Ergebnis wird als Mapping persistiert (tracking_form_field_mappings) und mit Konfidenz-Score bewertet, Release-Changelog-Generierung (PROJ-426): Beim Deploy eines Features wird die Feature-Spezifikation (max. 8.000 Zeichen) und der Commit-Diff (max. 8.000 Zeichen) an Claude Sonnet 4.6 (Fallback Haiku 4.5) übermittelt, um eine detaillierte 4-Sektionen-Beschreibung des Updates zu generieren. Prompt-Caching ist aktiv (ephemeral cache_control). Input enthält ausschließlich technische Software-Dokumentation und Code-Änderungen — keine personenbezogenen Daten, keine Workspace-/Nutzerinhalte. Ergebnis wird als Markdown in app_releases.detailed_description gespeichert und plattformweit angezeigt (mit ✦ KI-generiert-Kennzeichnung gemäß EU AI Act Art. 50). Zusätzlich Backfill-Pfad (PROJ-426 Follow-up): Für historische Release-Einträge ohne detailed_description wird auf Admin-Trigger ein Hintergrund-Worker angesteuert, der pro Eintrag nur Titel und Kurzbeschreibung an dieselbe Anthropic-API übermittelt — keine Feature-Spec und kein Commit-Diff, da diese für alte Einträge nicht rekonstruierbar sind. Gleiche Verarbeitungsklasse, kleinerer Input-Umfang, ABM Traffic Triage und Intent Scoring (PROJ-433): Asynchrone LLM-Klassifikation erkannter Unternehmens-Sessions als B2B-Lead oder Infrastruktur sowie semantische Kaufabsichts-Bewertung (0–100) aus URL-Pfad-Journey. Übermittelt werden ausschließlich: (1) Über IPinfo aufgelöste Unternehmensnamen (z. B. 'Kachelmann Getriebe GmbH') — kein direkter Personenbezug, da IP-Lookup auf Unternehmensebene; (2) Anonymisierte URL-Pfade ohne Query-Parameter (z. B. '/leistungen', '/kontakt') — Query-Parameter werden vor Übermittlung entfernt. Keine IP-Adressen, Namen, E-Mails oder andere PBD werden übertragen, Tracking-Insight Root-Cause-Analyse (PROJ-436 — tracking_root_cause_analysis): On-Demand-Erklärung erkannter Anomalien im Website-Tracking-Dashboard. Claude Haiku erhält ausschließlich anonyme Aggregat-Metriken: Insight-Typ (z. B. anomaly_bounce_spike), aggregiertes Metrik-Delta zur Baseline (Prozent-Wert), UTM-/Kanal-/Device-Scope (kategorische Werte ohne Klartext-IDs). Keine einzelnen Sessions, keine IP-Adressen, keine Nutzer-Agents, keine URL-Pfade mit Query-Parametern. Antwort ist eine strukturierte LLM-Erklärung mit 1–3 Hypothesen und Handlungsempfehlungen, gespeichert in tracking_insights.llm_explanation (TTL 7 Tage), Focal-Point-Erkennung für Markenassets (PROJ-420 — focal_point_detection): Claude Sonnet Vision analysiert hochgeladene Master-Files (JPEG/PNG/WebP oder aus Sharp konvertierte Thumbnails) um das visuelle Hauptmotiv zu erkennen. Ergebnis sind x/y-Koordinaten (0.0–1.0) für automatische, inhaltsbewusste Crops in 5 Seitenverhältnissen. Übermittelt wird das Bild selbst (transient, keine dauerhafte Speicherung durch Anthropic) — Bilder können PBD enthalten wenn Personen im Motiv sind. Aufruf erfolgt asynchron über Job-Queue, nicht in User-Interaction. Token-Tracking via logTokenUsage(feature=focal_point_detection), Semantische Metadaten-Generierung für Markenassets (PROJ-421 — asset_metadata_generation): Claude Sonnet Vision analysiert das Asset und erzeugt in einem einzigen API-Call 9 Metadaten-Felder: Alt-Texte (DE/EN, WCAG-konform, max. 125 Zeichen), semantische Beschreibung (150–300 Wörter, LLM-optimiert), Caption (1-Satz-Zusammenfassung), erkannte Objekte (Array), dominante Farben (Hex-Codes), Stimmungs-Tags, Content-Rating (safe/sensitive/nsfw). Bild wird transient übermittelt (keine dauerhafte Speicherung durch Anthropic) — Bilder können PBD enthalten wenn Personen im Motiv sind. NSFW-klassifizierte Assets werden automatisch mit Zugriffsbeschränkung versehen und Platform-Admins via Inbox-Notification benachrichtigt. Token-Tracking via logTokenUsage(feature=asset_metadata_generation), Automatische Bug-Triage (PROJ-260 + PROJ-448 Release-Bug-Erweiterung — bug_report_triage): Claude Haiku analysiert automatisch aufgetretene technische Fehler (Fehlermeldung + Stack Trace + Seiten-URL) sowie manuell via /updates-Seite gemeldete Release-Bugs (zusätzlich user_description als Freitext-Beschreibung des Einreichers, max. 5.000 Zeichen, kann Personenbezug enthalten da Nutzer frei schreibt). Ergebnis: strukturierte JSON-Antwort mit Severity-Einschätzung (critical/high/medium/low) + Fix-Vorschlag (max. 500 Zeichen) + Skill-Empfehlung (frontend/backend/bugfix). Gespeichert in bug_reports.ai_severity/ai_fix_suggestion/ai_suggested_skill. EU-AI-Act-kennzeichnung als ✦ KI-generiert in der Admin-Triage-Ansicht. Token-Tracking via logTokenUsage(feature=bug_report_triage), Heatmap Semantic Labels (PROJ-453 — heatmap_semantic_labels): Claude Haiku generiert pro (Workspace, Domain, CSS-Selektor) einen kurzen lesbaren deutschen Element-Namen (max. 50 Zeichen, Format 'Typ: Text' wie 'Button: Jetzt anfragen'). Übermittelt werden ausschließlich der CSS-Selektor (max. 500 Zeichen) und der häufigste sichtbare Elementtext (click_inner_text, max. 200 Zeichen, mit Input-Masking in snippet.js). Täglicher Cron 02:00 UTC, max. 50 Selektoren pro Workspace und Lauf. Ergebnis wird in heatmap_element_labels gecacht und nach 30 Tagen automatisch regeneriert. Fallback auf regelbasiertes Label bei LLM-Timeout. Transient — keine Datenpersistenz bei Anthropic, Heatmap Segment-Analyse (PROJ-454 — heatmap_segment_analysis): Claude Haiku generiert natürlichsprachige deutsche Insights (max. 300 Zeichen) für signifikante Klick-Divergenzen zwischen Traffic-Segmenten (Paid/Organic/Direct/Social/Email). Übermittelt werden ausschließlich aggregierte Klickstatistiken: Segment-Kategorien, Klickzahlen, prozentuale Anteile, CSS-Selektor, KI-Label aus PROJ-453, Divergenz-Faktor — keine einzelnen Sessions, keine Session-Hashes, keine IP-Adressen, keine UTM-Kampagnen-Namen (nur anonymisierte Kategorie-Zuordnung). Output: Insight-Text + Klassifikation in 4 Typen (top_interaction, friction, segment_anomaly, optimization). Täglicher Cron 03:00 UTC, max. 10 Insights pro Heatmap-Config und Lauf. Ergebnis wird in heatmap_insights gecacht, nach 7 Tagen regeneriert und nach 90 Tagen per Cleanup-Cron gelöscht. Transient — keine Datenpersistenz bei Anthropic, ABM Firmennamen-Vorschlag (PROJ-456 — abm_name_suggestion): On-Demand-LLM-Namensvorschlag für eine ABM-Domain. Claude Haiku 4.5 erhält ausschließlich den Domain-Namen (z. B. 'hetzner.com', 'sap.com') — öffentliche Information, kein direkter Personenbezug. Ziel: Ermittlung des offiziellen Firmennamens der Organisation hinter der Domain (nicht ISP/Hoster). Auslöser: explizit Admin-/Manager-Klick auf 'KI-Vorschlag'-Button, nicht automatisch oder Bulk. Output: Firmenname (max. 200 Zeichen) oder 'UNKNOWN'. Ergebnis wird nicht gespeichert — der Admin entscheidet, ob er den Vorschlag als Override übernimmt. Bei Übernahme: manuelles Speichern in abm_domain_overrides.company_name_override. Transient — keine Datenpersistenz bei Anthropic, Timeout 10 s, Header-KI-Assistent Feature-Wissensbasis (PROJ-460 — header_assistant_global): Erweiterung des bestehenden globalen KI-Assistenten (Bot-Icon im Header). Bei jeder Nutzer-Frage werden via pgvector-Ähnlichkeit die 3 thematisch passendsten veröffentlichten Hilfe-Artikel geladen (nur public Produktdokumentation, keine PII) sowie eine statische App-Feature-Übersicht (Menü-Pfade, Kurzbeschreibungen deployed Features). Diese Wissensbasis wird als zusätzliche System-Prompt-Schicht an Claude Haiku übermittelt, gemeinsam mit der Nutzer-Frage und ggf. vorhandenem Projekt-/Seitenkontext. Ein Heuristik-Filter erkennt, wenn die KI signalisiert, eine Frage nicht beantworten zu können — der Fragentext wird dann im Audit-Log ai_assistant_unanswered_questions gespeichert (30 Tage Retention, Zugriff nur eigener Nutzer + Platform-Admins). Zweck: kontinuierliche Verbesserung der Wissensbasis durch gezieltes Schließen von Dokumentationslücken. , Anlass-Kontakt-KI-Match (PROJ-459 — occasion_contact_matching): Täglicher Cron (03:00 UTC) analysiert für jeden Agency-Kontakt mit SSOT-Kontext die aktiven Anlass-Tage der nächsten 90 Tage. Übermittelt werden: Branche des Kontakts (kategorisch, kein Name), zusammengefasste Persona-Namen (max. 3, anonymisiert), Top-Produkte/Leistungen aus Bedarfsgruppen (max. 5 Stichpunkte, anonymisiert), Anlass-Titel und kurze Beschreibungen (public knowledge). Kein PII des Endkunden, keine Kontaktnamen, keine E-Mails. Output: Score 0–100 + 1-Satz-Begründung pro Anlass-Tag. Gespeichert in contact_occasion_relevance (Retention 90 Tage, Cleanup-Cron). Kein KI-Call bei leerem SSOT-Kontext, Anlass-Briefing-Vorschlag (PROJ-459 — editorial_occasion_briefing): On-Demand-Call auf Nutzer-Klick beim Quick-Create im Redaktionsplan. Übermittelt: Anlass-Titel + Beschreibung (public knowledge), Branche des Kontakts (kategorisch), Persona-Namen und Leistungs-Stichpunkte (anonymisiert, max. 5). Keine PII des Kontakts, kein Kontaktname, keine E-Mail. Output: Content-Aufhänger ca. 150 Zeichen. Nicht gespeichert — User kann Text übernehmen oder verwerfen. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Dialog. Transient — keine Datenpersistenz bei Anthropic, ABM Lead Quality Score (PROJ-466 — abm_quality_score): Asynchrone Hintergrund-Bewertung pro (Workspace, Domain) ob die erkannte Firma ein qualifizierter Lead-Kandidat für eine Digital-Agentur ist. Pre-Filter klassifiziert Infrastruktur (VPN/Datacenter/ISP) und Wettbewerber (Agency/Competitor) deterministisch ohne LLM-Call. Nur bei B2B-Firmen ohne negative Signale wird Claude Haiku mit folgenden anonymen Aggregat-Daten aufgerufen: Firmenname aus IPinfo-Lookup (öffentliche B2B-Information), Domain-Name, Kategorie-Label, Mitarbeiter-Range (company_size_range). Keine IP-Adressen, keine Personennamen, keine E-Mails. Output: Score 0–100 + Label ('lead' | 'unlikely') — gespeichert in abm_domain_overrides.quality_score/quality_label. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Dashboard. Transient — keine Datenpersistenz bei Anthropic, ABM Insight Text & Interessen-Tags (PROJ-466 — abm_insight_text): Explizit Admin-/Manager-ausgelöster Claude Haiku Call zur Generierung einer 2–3-sätzigen deutschen Visit-Story (max. 1000 Zeichen) und bis zu 5 Interessen-Tags aus einer serverseitigen Whitelist (#SEO, #EmployerBranding, #LeadGen, #Performance, #WebDesign, #SocialMedia, #Branding, #Entwicklung, #Tracking, #CRM). Übermittelt werden ausschließlich anonyme Aggregate: Anzahl Sessions, Erst-/Letzt-Besuchs-Zeitstempel, UTM-Kanal/Medium/Kampagne (kategorisch), Top-10 URL-Pfade ohne Query-Parameter + aggregierte Verweildauern, Formular-Interaktions-Anzahl, maximale Scroll-Tiefe. Keine IP-Adressen, keine Session-Hashes, keine Klartext-IDs, keine Personennamen. Input-Firmenname stammt aus IPinfo (öffentliche B2B-Information). Output wird in abm_domain_overrides.insight_text/insight_tags gespeichert (pro Workspace × Domain). Rate-Limit 10 Requests/Min/Workspace. Timeout 15 s. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Sheet. Transient — keine Datenpersistenz bei Anthropic, KI-Keyword-Seiten-Mapping (PROJ-470 — keyword_page_ai_mapping): Asynchroner Worker-Cron (minütlich, Chunks à 50 Keywords) ordnet unzugeordnete Keywords semantisch passenden Bedarfsgruppen-Seiten eines Kontakts zu. Übermittelt werden ausschließlich Keyword-Begriffe (Suchbegriffe aus SSOT-Marketing-Intelligenz, kein direkter Personenbezug) und Bedarfsgruppen-Seitennamen (kunden-spezifische Seitentitel aus ssot_items.data, kein direkter Personenbezug). System-Prompt enthält die vollständige Seiten-Liste mit cache_control: ephemeral für Token-Kostenoptimierung. Output: Top-3-Vorschläge pro Keyword mit Konfidenz-Score (0–100) und Reasoning, gespeichert in keyword_page_mapping_suggestions (TTL 24h). Akzeptierte Vorschläge werden via bestehender keyword-page-assignments-API materialisiert (PROJ-275). Keine PII, E-Mails oder Kontaktdaten werden übermittelt. Rate-Limit 5 Job-Starts/Stunde/Workspace. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung in Review-UI. Transient — keine Datenpersistenz bei Anthropic, Mehrsprachige Markenasset-Alt-Texte (PROJ-474 — asset_metadata_multilingual): Erweitert PROJ-421 (asset_metadata_generation) um parallele Alt-Text-Generierung für bis zu 10 Ziel-Sprachen pro Markenasset (z. B. de/en/fr/es/it/nl/pl/cs/tr/pt). Claude Haiku Vision analysiert das Asset in einem API-Call und erzeugt WCAG-konforme Alt-Texte (max. 125 Zeichen pro Sprache) gemäß den Ziel-Sprachen, die der Kontakt (Workspace-Admin) zuvor konfiguriert hat. Übermittelt werden: Bild-URL (transient abrufbar durch Anthropic während der Verarbeitung — Bilder können PBD enthalten wenn Personen im Motiv sind), Liste der Ziel-Sprach-Codes (z. B. ['de','en','fr']), optional vorhandener semantischer Kontext (PROJ-421 semantic_description, WCAG-Ziel). Ergebnis wird pro (Asset, Sprache) in brand_asset_alt_texts gespeichert (language_code, alt_text, is_ai_generated, generated_at, model_used). Zwei Trigger: (1) automatische Generierung beim Upload neuer Assets via Job-Queue (job_type: generate_multilingual_alt_texts), (2) Backfill-Job beim Hinzufügen einer neuen Ziel-Sprache via Kontakt-Konfiguration (job_type: backfill_alt_text_language — einzelne Sprache für alle bestehenden Assets des Kontakts). Manuell vom Nutzer editierte Alt-Texte werden beim Backfill übersprungen (manually_edited_at IS NOT NULL). Nach Abschluss eines Backfill-Jobs wird eine Zusammenfassungs-Notification an den auslösenden Admin gesendet. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Asset-Detail-Dialog. Transient — keine Datenpersistenz bei Anthropic, Autonome Tracking-Analyse (PROJ-475 — autonomous_tracking_setup): Drei-Phasen-Analyse zur automatischen Tracking-Blueprint-Generierung auf User-Trigger (nicht automatisch). Phase 1 Topologie-Klassifizierung: Claude Haiku erhält eine Liste der häufigsten URL-Pfade einer Kundendomain (aus tracking_events, ohne Query-Parameter) und ordnet sie einem oder mehreren Topologie-Typen zu (standard_leadgen, produktkatalog, ecommerce, event_veranstaltung, blog_content). Phase 2 Semantic Event Matching: Bei unbekannten Button-Klick-Events werden ausschließlich die Button-Labels und href-Attribute (z. B. 'Jetzt anfragen', '/kontakt') an Claude Haiku übermittelt, der sie auf Standard-Event-Typen (lead_form_submit, add_to_cart, checkout_complete, etc.) mappt. Phase 3 Content-Theme-Clustering: Heading-Texte (h2/h3) aus content_engaged-Events (4-Sekunden-Viewport-Timer) werden aggregiert und an Claude Haiku zum Clustering in thematische Label-Gruppen übermittelt. Keine personenbezogenen Daten — ausschließlich URL-Pfade ohne Query-Parameter, Button-Labels, öffentliche Heading-Texte aus der Kundenwebsite. Keine IP-Adressen, Session-Hashes, Nutzer-Agenten oder PII. Ergebnisse gespeichert in tracking_blueprints, tracking_event_suggestions, tracking_content_themes, tracking_content_theme_matches (alle workspace-scoped, CASCADE-DELETE bei Workspace-/Domain-Löschung). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung bei Blueprint-Vorschlägen und Event-Mapping-Empfehlungen im Setup-UI. Transient — keine Datenpersistenz bei Anthropic, ABM KI-Firmenbereinigung (PROJ-477 — abm_resolve_domain): Asynchroner Hintergrund-Worker (abm-llm-worker Phase 4, 5-Min-Takt, max. 50 Domains/Run) bereinigt pro (Workspace, Domain) den IPinfo-company_name, wenn die Domain zu einem ISP, Hoster, Telco oder VPN-Provider gehört. Claude Haiku 4.5 erhält ausschließlich die Domain (z. B. 'hetzner.com', 'vodafone.de') — öffentliche Information, kein direkter Personenbezug, kein IPinfo-Firmenname als Input. Output: Firmenname (max. 200 Zeichen) der Organisation hinter der Domain ODER 'UNKNOWN' (= als ISP/Infrastruktur klassifiziert). Ergebnis wird in abm_domain_overrides.ai_is_isp_domain / ai_resolved_name / ai_resolved_at persistiert mit 24h-Cache. Erneute Klassifikation nur bei TTL-Ablauf. Zusätzlich Admin-/Manager-triggerbarer Batch-Backfill-Endpunkt für Bestandsdaten (POST /abm/backfill-resolution, 1 Run/Stunde/IP). Timeout 15 s pro LLM-Call. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im ABM-Dashboard bei KI-korrigierten Einträgen (Sparkles-Icon + Tooltip). Transient — keine Datenpersistenz bei Anthropic, Sales Deal-Wert-Schätzung (PROJ-479 — sales_deal_value_estimate): Bei der Anlage eines neuen Verkaufschancen-Deals im Sales-CRM erzeugt Claude Haiku 4.5 eine initiale Wertschätzung in EUR-Cent auf Basis von Leistungsbereich (kategorisch: website/seo/recruiting/app/…), Firmenname des Kontakts (B2B-Kontakt, kein direkter Personenbezug), Branche und Unternehmensgröße (kategorisch, z. B. Mitarbeiter-Range), sowie der historischen gewonnenen/verlorenen Deals desselben Kontakts (Dealname + Wert in Cent + Status — anonymisierte Aggregate, keine Kommunikationsinhalte). Output: Dealwert in Cent (clampbar auf 0–10 Mrd.) + Confidence (high/medium/low) + kurze Begründung (max. 400 Zeichen, auf Deutsch). Auslöser: automatisch nach POST /api/sales/deals, fire-and-forget, keine blockierende User-Interaktion. Ergebnis wird in sales_deals.deal_value_estimated_cents gespeichert und mit deal_value_source='ki_estimate' markiert. Der Wert kann jederzeit manuell überschrieben oder durch einen konkreten Angebotswert ersetzt werden. Prompt-Caching (R-658): der statische System-Prompt mit Branchen-Preisspannen ist ephemeral gecached. Rate-Limit via sales-deals:write (30 req/min/IP). Timeout 30 s. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Deal-Detail-Sheet. Transient — keine Datenpersistenz bei Anthropic, Sales Task-Priorisierung (PROJ-480 — sales_task_prioritize): Bewertet eine einzelne Sales-Task mit einer Priorität (hoch/mittel/niedrig) auf Basis von Task-Kanal und -Ziel (kategorisch, z. B. anrufen/mail_senden × nachfassen/entscheidung_einholen), Fälligkeitsdatum, Days-overdue, Deal-Kontext (Dealname, Stage-Name, geschätzter Wert in Cent, Health-Score 0–100, Deal-Herkunft, Kundenkategorie A/B/C) sowie anonymisierten Aktivitäts-Kennzahlen (Days seit letzter Deal-Aktivität, Days seit letzter Task auf demselben Deal). Keine Kommunikationsinhalte, keine Kontaktnamen, keine E-Mails, keine Telefonnummern. Output: priority + max. 300 Zeichen deutsche Begründung + max. 4 Schlagworte als Faktoren. Auslöser: (a) fire-and-forget nach POST /api/sales-tasks bei neu erstellten Tasks ohne manuelle Priorität, (b) Admin/Manager-getriggerter Batch-Reprioritize-Endpunkt für bestehende Tasks (max. 50 pro Aufruf). Ergebnis wird in sales_tasks.priority + priority_source='ki' + ki_priority_reasoning (JSONB) gespeichert. Manuell vom Nutzer gesetzte Prioritäten (priority_source='manual') werden NICHT überschrieben. Prompt-Caching (R-658): statischer Bewertungs-Leitfaden ist ephemeral gecached. Rate-Limit via sales-tasks:action/write. Timeout 20 s. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Task-Detail + Tooltip mit Reasoning. Transient — keine Datenpersistenz bei Anthropic, Sales Communication AI-Signal-Extraction (PROJ-481 — sales_communication_signal_extraction): On-Demand oder fire-and-forget Aufruf bei content-INSERT in sales_communication_log. Claude Haiku 4.5 erhält ausschließlich den Volltext-Inhalt einer Kommunikation (E-Mail-Body, Call-Notes, Meeting-Transkript, max 50.000 Zeichen — kann PII enthalten da User-erstellt) sowie kategorische Kanal-Information (email/phone/video_meeting/in_person/note). Output: strukturiertes JSON mit pain_points (Array bis 5, max 60 Zeichen pro Eintrag), objections (Array bis 5), next_steps (Array bis 5), competitor_mentioned (boolean) — keine Volltext-Zitate, nur kategorische Aggregate. Gespeichert in sales_communication_log.ai_extracted_signals (JSONB). Bei competitor_mentioned=true wird zusätzlich eine Inbox-Notification an den zuständigen Vertriebler ausgelöst. Trigger nur wenn content >= 200 Zeichen UND ai_extracted_signals leer ist. Prompt-Caching (R-658): statischer Extraktions-Leitfaden ist ephemeral gecached. Timeout 30 s. max_tokens 768 (R-697). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung der Signal-Badges in der Timeline-View. Transient — keine Datenpersistenz bei Anthropic, Sales KI-Coaching-Feedback (PROJ-486 — sales_coaching_feedback): Asynchroner Coach-Aufruf nach Won/Lost-Deals oder Communication-Events. Claude Haiku 4.5 erhält ausschließlich kategorische Deal-Aggregate: deal_name (intern, Workspace-Begriff), stage_type (kategorisch), deal_value_cents, deal_herkunft (kategorisch), customer_industry (kategorisch optional), customer_size_range (kategorisch optional), total_communications_count, days_in_pipeline, ai_extracted_signals (kategorische Aggregate aus PROJ-481). KEINE Volltext-Kommunikationsinhalte, KEINE Endkunden-Personennamen, KEINE E-Mails, KEINE Telefonnummern. Output: feedback_text (max 2000 Zeichen Deutsch), key_observations (max 5 Stichpunkte), improvement_suggestions (max 5 Stichpunkte). Gespeichert in sales_coaching_feedback. Prompt-Caching (R-658) ephemeral aktiv. Timeout 30 s. max_tokens 800 (R-697). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Coaching-Detail. Transient — keine Datenpersistenz bei Anthropic, Markenasset KI-Metadaten-Suche (PROJ-495 — asset_metadata_generation, erweitert PROJ-421): Asynchroner Cron-Worker (5-Min-Takt, max. 10 Assets pro Lauf) analysiert Markenasset-Bilder via Claude Haiku 4.5 Vision und erzeugt suchbare Metadaten in einem JSON-Format mit 4 Feldern: detected_objects (Array allgemeiner Objekte/Konzepte, z. B. 'Person', 'Laptop', 'Büro' — KEINE biometrische Identifikation, keine Gesichtserkennung, keine Personenidentifikation), mood_tags (Stimmungs-Tags, z. B. 'professionell', 'warm'), dominant_colors (Hex-Codes mit Prozentanteil), ai_full_description (150–300 Wörter Deutsch). Bild wird transient als Base64 übermittelt (keine dauerhafte Speicherung durch Anthropic) — Bilder können PBD enthalten wenn Personen im Motiv sind, der System-Prompt instruiert das Modell explizit Personen nur als 'Person' zu kennzeichnen ohne Identifikationsmerkmale. Auslöser: (a) automatisches Enqueue beim Asset-Upload (POST /api/contacts/:id/brand-assets) mit status='pending', (b) Einzeltrigger über POST /:contactId/brand-assets/:assetId/analyze, (c) Bulk-Trigger über POST /:contactId/brand-assets/analyze-all (admin/manager). Ergebnisse gespeichert in brand_asset_ai_metadata (asset_id, workspace_id, alle 4 Felder, analysis_status, analyzed_at, model_used). Volltext-Suche (tsvector deutsch) auf ai_full_description, JSONB-Containment-Suche auf detected_objects/mood_tags/dominant_colors. Prompt-Caching (R-658) ephemeral aktiv. Timeout 60 s. max_tokens 2000 (R-697). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Asset-Detail-Sheet. Transient — keine Datenpersistenz bei Anthropic, Sales Pre-Call-Briefing (PROJ-482 — sales_call_briefing): Auf User-Trigger (Vertriebler klickt auf Briefing-Button vor einem Vertriebsgespräch) erzeugt Claude Haiku 4.5 ein konkretes Briefing für das anstehende Gespräch. Übermittelt werden ausschließlich kategorische Aggregate: Gesprächstyp (kategorisch enum), Branche (kategorisch optional), Unternehmensgröße-Bereich (kategorisch optional), Deal-Wert-Bereich (z. B. '5.000–10.000 €'), Health-Score (0–100), Pipeline-Tage, letzte 5 Communication-Typen mit days_ago, sowie aggregierte Pain-Points/Einwände/NextSteps aus PROJ-481 Signal-Extraction (kategorische Aggregate, keine Volltext-Zitate). KEINE Endkunden-Personennamen, KEINE E-Mails, KEINE Telefonnummern, KEINE Volltext-Kommunikationsinhalte. Output: agenda (3-5 Bullet-Points), open_topics (0-5), potential_questions (3-5 konkrete Fragen), warning_signals (0-3). Gespeichert in sales_call_sessions.pre_call_briefing (JSONB) + ki_briefing_model. Prompt-Caching (R-658) ephemeral aktiv. Timeout 30 s. max_tokens 1024 (R-697). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Briefing-UI. Transient — keine Datenpersistenz bei Anthropic, Sales Post-Call-Summary (PROJ-482 — sales_call_summary): Nach Gesprächsende erzeugt Claude Haiku 4.5 eine strukturierte Zusammenfassung. Übermittelt werden: ENTWEDER ein Live-Transkript-Volltext (transcript_text, max 50.000 Zeichen — kann Endkunden-PII enthalten, vom Vertriebler explizit übergeben) ODER Vertriebler-Notizen (talking_points-Array, max 50 Einträge à 2000 Zeichen) als Fallback. Zusätzlich kategorischer Kontext: Gesprächstyp, Branche. Output: summary (2-5 Sätze, max 2000 Zeichen Deutsch), pain_points/objections/next_steps/decision_makers (jeweils 0-5 Stichpunkte), recommended_score_change (-20 bis +20, server-seitig auf Range geclampt). Gespeichert in sales_call_sessions.post_call_summary + Aggregat-Arrays + new_score_after_call. Optional: Live-Update von sales_deals.health_score basierend auf recommended_score_change. Prompt-Caching (R-658) ephemeral aktiv. Timeout 30 s. max_tokens 1500 (R-697). Score-Range-Clamping auf -20..+20 (R-670 analog). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung in der Summary-Anzeige. Transient — keine Datenpersistenz bei Anthropic, Sales Followup-Draft (PROJ-483 — sales_followup_draft): Bei expliziter User-Anforderung (POST /api/sales-followup/drafts) generiert Claude Haiku 4.5 einen Mail-Entwurf für einen Sales-Deal. Übermittelt werden ausschließlich kategorische Aggregate: deal_name (intern, Workspace-Begriff), draft_type (kategorisch enum: follow_up_after_call/follow_up_after_quote/re_engage/answer_objection/meeting_request), tone (kategorisch: formal/casual/direkt/empathisch), contact_industry (kategorisch optional), detected_pain_points + detected_objections (max 3 je, aus PROJ-481 Signal-Extraction), days_since_last_contact, optional last_communication_summary (max 1000 Zeichen — kann PII enthalten wenn vom User selbst übergeben). KEINE Endkunden-Personennamen, KEINE E-Mails, KEINE Telefonnummern direkt. Output: subject (max 200 Zeichen), body_text (max 10.000 Zeichen Deutsch), ki_reasoning (max 500 Zeichen). Gespeichert in sales_followup_drafts (User entscheidet manuell ob/wann gesendet wird). Prompt-Caching (R-658) ephemeral aktiv. Timeout 30 s. max_tokens 1500 (R-697). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Editor. Transient — keine Datenpersistenz bei Anthropic, SOP Voice-Dictation KI-Stil-Assistent (PROJ-503 — sop_voice_dictation): Auf User-Trigger im SOP-Editor (Mikrofon-Button in der Toolbar) wird ein Sprach-Diktat zunächst via OpenAI Whisper transkribiert (siehe OpenAI-PROCESSORS-Eintrag) und anschließend an Claude Haiku 4.5 übermittelt um den informellen Rohtext in strukturiertes SOP-Markdown nach dem Workspace-spezifischen Stil umzuwandeln. Übermittelt werden: (1) der von Whisper erzeugte Rohtranskript-Volltext (max 25 MB Audio = typisch <5.000 Zeichen Text — kann betriebsinterne Inhalte enthalten, vom User explizit eingesprochen, kein Endkunden-PII typischerweise erwartet), (2) workspace_settings.sop_style_config (Tonalität-Kategorie, Struktur-Vorgabe-Freitext, bevorzugte/verbotene Begriffslisten, Stil-Beispiel-Absatz — Workspace-Konfiguration ohne PII). Output: strukturiertes Markdown (max 4096 Output-Tokens) das im Frontend zu TipTap-JSON konvertiert und an der Cursor-Position im SOP-Editor eingefügt wird. Bei KI-Fehler (Timeout, max_tokens, Service-Unavailable) Fallback auf Rohtranskript als Plain-Text. Audio-Daten werden NICHT an Anthropic gesendet (nur OpenAI Whisper, danach verworfen). Token-Tracking via logTokenUsage(feature=sop_voice_dictation). Timeout 15 s. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung beim Insert-Toast. Transient — keine Datenpersistenz bei Anthropic, Signing-Seite KI-Übersetzung (PROJ-506 — signing_translation): On-Demand Aufruf, wenn ein Empfänger der öffentlichen Angebots-Signing-Seite (/angebot/[token]) eine Zielsprache wählt. Übermittelt werden ausschließlich die textuellen Inhalte des Angebots: Titel, Notes, Projektbeschreibung (Plain-Text-Extraktion aus dem JSONB-Feld), Audio-Zusammenfassungs-Text, Anrede sowie Name und Beschreibung der Plan-Items (max. 40 Items pro Aufruf, max. 8.000 Zeichen pro Feld). Quelle ist bei signierten Angeboten der signing_snapshot (R-318), bei Entwurf/gesendet die Live-Felder. Diese Inhalte können personenbezogene Daten enthalten (z.B. Kundennamen in Beschreibungen) — der System-Prompt instruiert Claude Haiku 4.5 ausdrücklich, Eigennamen, Firmennamen, Markennamen, Preise, Zahlen, Datumsangaben, E-Mails, URLs und Produktcodes unübersetzt zu lassen. Output: strukturiertes JSON-Mapping {schlüssel: übersetzter-text} — wird in quote_translations (workspace-scoped, 90-Tage-Cache via Content-Hash) gespeichert. Cache invalidiert sich automatisch bei Inhaltsänderungen am Angebot. Prompt-Caching aktiv (System-Prompt mit cache_control: ephemeral). Rate-Limit 30 Übersetzungen/24h pro IP. Timeout 30s. Token-Tracking via logTokenUsage(feature=signing_translation). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Sprach-Switcher und während des Loadings. Cleanup-Cron quote-translations-cleanup (täglich 04:30 UTC). Transient — keine Datenpersistenz bei Anthropic, SOP Konsistenz-Check (PROJ-504 — sop_consistency_check): Auf User-Trigger im SOP-Editor (Sparkles-Button 'Konsistenz prüfen') wird der aktuelle SOP-Inhalt (TipTap-JSON, transient zu Markdown serialisiert, max 5.000 Zeichen) gemeinsam mit der workspace_settings.sop_style_config (Tonalität-Kategorie, Struktur-Vorgabe, bevorzugte/verbotene Begriffslisten, Stil-Beispiel-Absatz — Workspace-Konfiguration ohne PII) an Claude Haiku 4.5 übermittelt. Output: strukturiertes JSON-Array mit max. 5 Konsistenz-Vorschlägen pro Aufruf (id, type ∈ {wording, structure, tonality, forbidden_term}, original-Textstelle, suggestion-Umformulierung, reason-Begründung). Vorschläge werden NICHT in der DB gespeichert — sie existieren nur während der Browser-Session und werden vom User entweder per Klick übernommen (Inhalt-Replace im Editor) oder ignoriert (Diff-Banner ausblenden). Kein automatisches Speichern, keine Hintergrund-Verarbeitung. SOP-Inhalte sollen generische Prozess-Beschreibungen sein und können betriebsinterne Texte enthalten — vom User selbst geschrieben, kein Endkunden-PII typischerweise erwartet. Token-Tracking via logTokenUsage(feature=sop_consistency_check). Rate-Limit 20 req/min/Workspace + 200 req/24h/Workspace. Timeout 15 s. max_tokens 2048. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Vorschlags-Banner. Pflicht-Toggle pro Workspace (sop_consistency_check_enabled, default FALSE) — Feature ist opt-in. Transient — keine Datenpersistenz bei Anthropic, Coding Operations Platform (PROJ-510 — coding_ops_session): Multi-Turn-Konversations-Sessions zwischen authentifizierten Workspace-Mitgliedern und Coding-Agent über das Anthropic Agent SDK. Übermittelt werden: (a) User-Task-Beschreibungen (Bug-Reports, Feature-Wünsche — vom Workspace-Mitglied selbst eingegeben, max. 50.000 Zeichen, können Endkunden-Bezug enthalten wenn Bug-Report einen konkreten Kunden-Workflow betrifft, kein PII-Scrubbing weil Inhalte vom Mitarbeiter selbst kontrolliert werden); (b) Code-Snippets aus dem Repository (Repository-Quelldateien — interne Software-Artefakte, keine Endkunden-PBD); (c) Konversations-Historie der laufenden Session (rollierende Multi-Turn-Nachrichten, persistiert in coding_ops_session_messages mit RLS-Sichtbarkeit nur für Session-Owner + Workspace-Admin/Manager + Plattform-Admin); (d) strukturierte Knowledge-Graph-Auszüge (Top-K relevante Regeln und Code-Index-Einträge — interne technische Dokumentation, keine PBD). Modelle: Claude Haiku 4.5 für Lookups, Claude Sonnet 4.6 für Implementation, Claude Opus 4.7 on-demand für Architektur-Entscheidungen. Multi-Modell-Routing über Agent-SDK-Konfiguration. Output: Code-Änderungen, Tool-Calls (Read/Write/Edit/Bash/query_knowledge_graph/query_code_index/ask_user_decision/request_admin_approval), strukturierte Decision-Cards. Token-Tracking via logTokenUsage(feature=coding_ops_session). Cost-Estimate vor Session-Start, Hard-Stop bei Workspace-Budget-Überschreitung. Phase-1-Sessions sind intern (du + Plattform-Admins). Phase-2 erweitert auf Workspace-Mitglieder mit Junior/Trusted/Admin-Permission-Modi. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung an allen Agent-erzeugten Code-Vorschlägen und PR-Beschreibungen. Transient — keine Datenpersistenz bei Anthropic. Konversations-Historie liegt ausschließlich in eigener DB (coding_ops_session_messages), kein Anthropic-API-side Memory, SOP-Feedback-Vorschlag (PROJ-515 — sop_feedback_proposal): Bei Inline-Feedback an einer SOP wird der aktuelle SOP-Inhalt (TipTap content_json transient zu JSON serialisiert, max 60.000 Zeichen — Truncation mit head+tail bei längeren SOPs) gemeinsam mit der workspace_settings.sop_style_config (Tonalität, Struktur-Vorgabe, bevorzugte/verbotene Begriffe) und dem Feedback-Text an Claude Haiku 4.5 gesendet. Output: vollständiger, überarbeiteter content_json-Vorschlag plus Kurz-Zusammenfassung (max 280 Zeichen). SOP-Inhalte können personenbezogene Daten enthalten — Mitarbeiter beschreibt Freitext-Verbesserungsvorschläge die konkrete Personen, Projekte oder Kunden referenzieren können. Async (fire-and-forget) ausgelöst aus POST /api/sop/articles/:id/feedback, Timeout 60s. Token-Tracking via logTokenUsage(feature=sop_feedback_proposal). Rate-Limit 10 Submits/h/User + 5 Retry/h/User. Bei Fehler/Timeout bleibt ai_proposal_json NULL und ai_run_status='failed'/'timeout'. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Vorschlags-Sheet. Transient — keine Datenpersistenz bei Anthropic, Kampagnen-Konzept-Entwicklung (PROJ-517 — campaign_development): KI-gestützter Chat-Assistent zur Konzeptentwicklung im SSOT-Kampagnen-Wizard. Übermittelt werden ausschließlich strategische SSOT-Kontextdaten des Workspace-Admins/Managers: Touchpoint-Kategorie, Zielmärkte, Marketingziele, Zielgruppen, Personas (interne Bezeichnungen), Kanäle (Kategorien), Funnel-Phase (Awareness/Consideration/Conversion/Loyalty) sowie der Konversations-Verlauf des Wizard-Dialogs. System-Prompt ist vom Workspace-Admin konfigurierbar (slug: campaign-development). Kein Endkunden-PII. Chat-Verlauf ephemer im React-State, wird nicht in ai_conversations persistiert. Transient — keine Datenpersistenz bei Anthropic, Kampagnen-Redakteure und Website-Autoren (PROJ-289 + PROJ-688 — campaign-*-redakteur + website-autor-*): Benutzerdefinierte KI-Assistenten für Social-Media-Beiträge (LinkedIn, Instagram, Facebook, YouTube, TikTok, X, Google Business) und Website-Texte (Blog, Corporate, Landingpage, News & Termine, Recruiting, Stellenangebote). Übermittelt werden System-Prompt, Kampagnenkonzept und SSOT-Markenstrategieprofil (Tonalität, Zielgruppe, Marketingziele des Workspaces) — kein Endkunden-PII. Provisionierung workspace-spezifisch via /api/campaigns/provision-ai-assistants (idempotent). PROJ-688 ergänzt Blog als Kanal. Transient — keine Datenpersistenz bei Anthropic, SSOT Favicon-KI-Berater (PROJ-519, ssot_favicon_advisor): Claude Vision Haiku analysiert das hochgeladene Logo (Bild als URL-Referenz) zusammen mit den hinterlegten CI-Brand-Farben (bis zu 5 Hex-Werte) und dem Brand-Namen, um eine Crop-Region (1:1-Verhältnis), Background-Farbe und Padding-Empfehlung für die Favicon-Generierung vorzuschlagen. Bild-Analyse ist transient — Anthropic speichert weder Bild noch Empfehlung persistent. Kein Endkunden-PII. Anthropic-Prompt-Caching aktiv für den System-Prompt, SSOT CI Automatisches KI-Design-Erfassen (PROJ-520, ssot_ci_analysis): Claude Sonnet 4.5 Vision analysiert eine Kombination aus URL-Quellen (HTML-Hinweise wie favicon-link, theme-color, og:image, Google-Fonts-Imports, css-color-hints aus Cheerio-Scrape + Above-the-fold-Screenshots der Kunden-Webseite via Playwright/Chromium) und vom Nutzer hochgeladenen Brand-Manuals (PDF, PNG, JPEG — max 3 URLs + 5 Dateien je max 20 MB; bei Analyse-Typ Kommunikation/Beides zusätzlich TXT, MD und Word .docx, PROJ-1424). Übermittelt werden: (1) Web-Screenshots der Kundenwebseite (transient als Base64-PNG, kann öffentliches Brand-Material und potenziell Personenfotos enthalten wenn die Webseite Personen zeigt), (2) HTML-Strukturhinweise (favicon-URL, theme-color-Hex, og:image-URL, Google-Fonts-Liste, max 20 Hex-Codes aus inline style-Blöcken, html_excerpt mit Title+Meta-Description max 5000 Zeichen — öffentliche Webseiten-Inhalte), (3) hochgeladene Dokumente als Base64 (transient — Brand-Manuals enthalten typischerweise Marken-Design-Inhalte, in seltenen Fällen mittelbar personenbezogene Daten wie Inhaberporträts). System-Prompt mit cache_control: ephemeral (R-658). Output: strukturiertes JSON mit bis zu 12 CI-Vorschlägen (section, data, confidence: 'high'|'low', source: 'url'|'file', source_label, suggestion_id, reasoning) — der Nutzer entscheidet pro Vorschlag, ob übernommen wird. Single-Field-Suggester (zusätzlich, ohne Vision): Claude Haiku 4.5 erzeugt punktuelle Vorschläge für ein einzelnes leeres CI-Feld basierend auf bestehendem SSOT-Kontext (Farben, Schriften, Tonalität). Job-Lifecycle: ssot_ci_analysis_jobs (status pending → processing → done/failed/discarded). Hochgeladene Quell-Dateien werden 24h nach Job-Abschluss vom Cleanup-Cron 'ssot-ci-analysis-cleanup' automatisch aus dem ssot-media-Bucket gelöscht (DSGVO-Datenminimierung). Job-Audit-Metadaten 90 Tage. Token-Tracking via logTokenUsage(feature=ssot_ci_analysis). Rate-Limit 5 Job-Starts/min/IP. Async Worker-Cron 'ssot-ci-analysis-worker' (minütlich, max 3 Jobs/Run). Notifications ssot_ci_analysis_completed/failed an den auslösenden Nutzer. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung in der Vorschlags-Vorschau. Transient — keine Datenpersistenz bei Anthropic. PROJ-574 erweitert dieselbe Job-Infrastruktur um analysis_type='communication'|'both': Sprach-/Markensprache-Analyse aus Website-Texten (gescraped, max 24k Zeichen) und PDFs — Output Tonalität, Dos/Don'ts, Beispielsätze, Wording-Whitelist/Blacklist und USPs in ssot_ci_language bzw. ssot_items section='usp'. Bei reinem Communication-Modus: KEIN Vision-Call, nur Text/PDF an Claude Sonnet — gleiche Transient-Garantie, UTM-Vorschlags-KI (PROJ-521 — utm_assignment_suggestion): Hybrid-Vorschlagsfunktion zur Zuordnung erkannter UTM-Kombinationen an Touchpoints und Marketingziele. Phase 1 regelbasiert ohne KI-Call (utm_source-Match auf channel_matrix). KI-Fallback nur wenn keine Regel greift: Claude Haiku 4.5 erhält UTM-Werte (utm_campaign, utm_source, utm_medium) und eine Liste der konfigurierten Touchpoints des Workspaces (interner Touchpoint-Name, channel_matrix-Konfiguration, Marketingziel-IDs). UTM-Werte können theoretisch personenbezogene Daten enthalten wenn Kampagnen unsachgemäß befüllt werden — Prävention durch UI-Hinweise auf der Konfigurationsseite. Output: JSON mit empfohlener Touchpoint-/Marketingziel-ID + Score 0,0–1,0 + Begründung (max. 120 Zeichen). Halluzinations-Guard: zurückgegebene UUIDs werden gegen die übermittelte Liste validiert. In-Memory-Cache 24 h pro Workspace × UTM-Tripel. Token-Tracking via logTokenUsage(feature=utm_assignment_suggestion). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Vorschlags-Banner des Zuweisen-Dialogs. Transient — keine Datenpersistenz bei Anthropic, Semantische UTM-Klassifizierung (PROJ-530 — channel_semantic_classification): Letzter Fallback der semantischen Attribution-Engine. Wenn weder Curated Sources, Workspace Overrides noch Spezialregeln (Dark Social, GSC Brand-Split, Customer Referral, UTM-Heuristiken) eine UTM-Kombination klassifizieren können, sendet der attribution-semantic-worker bis zu 20 unbekannte Kombinationen pro Anthropic-Call (Claude Haiku 4.5) zur Klassifizierung. Eingabe pro Item: utm_source, utm_medium, utm_campaign, referrer_domain (Hostname ohne Pfad), landing_page_category (homepage/deep_url/shallow_url) — keine personenbezogenen Daten, keine User-Agents, keine IP-Adressen, keine vollständigen URLs, keine Telefonnummern, keine E-Mail-Adressen. Output: { channel, confidence: high|medium|low, reasoning } pro Item. Nur high/medium werden als override_source=ai_suggestion in attribution_workspace_overrides gespeichert (warten auf Admin-Bestätigung in PROJ-531-UI); low → Queue-Status skipped. Anthropic Prompt-Caching auf System-Prompt (cache_control: ephemeral, R-658). Token-Tracking via logTokenUsage(feature=channel_semantic_classification). Timeout 30 s, max_tokens 3500 (R-697), stop_reason-Check vor JSON.parse (R-698). Transient — keine Datenpersistenz bei Anthropic, AI Site Planner Wireframe-Generierung (PROJ-587 — ai_site_planner_wireframe): Auf Trigger eines Agentur-Admins/Managers erzeugt Claude Haiku 4.5 ein strukturelles Text-Wireframe (5–12 Sections mit Name, Purpose, target_component_type) für eine neue CMS-Landingpage. Übermittelt werden ausschließlich SSOT-Daten der Agentur: ausgewählte Bedarfsgruppen-Namen + -Beschreibungen, Personas-Namen + -Beschreibungen, USP-Texte und freie Stichworte des Triggers — alle vor Übertragung via sanitizePii() von potentiellen PII-Tokens (E-Mail, Telefonnummern, Klarnamen) bereinigt. Tool-Use-Schema mit target_component_type-Enum aus den Master-Komponenten des Workspaces (lab_components.component_type). Output: 5–12 strukturierte Sections als JSON, gespeichert in ai_site_planner_jobs.wireframe_data. R-697 max_tokens 4000, R-698 stop_reason-Check, R-665 AbortSignal 60s. Token-Tracking via logTokenUsage(feature=ai_site_planner_wireframe). Section-Reformulierung (User-Anweisung pro Section) nutzt dasselbe Modell mit max_tokens 800. Auslöser: nur Agentur-Admin/Manager (RLS + API-Layer). Endkunden-Workspaces sehen die Tabelle nie. Rate-Limit 5 Triggers/min. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Wireframe-Editor. Transient — keine Datenpersistenz bei Anthropic, Insert-Tag KI-Übersetzung (PROJ-591 — cms_insert_tag_translation): Auf User-Trigger im Insert-Tag-Manager wird der Default-Wert (deutscher Marketing-Text) eines Custom-Insert-Tags + optionale Tag-Description an Claude Haiku 4.5 übermittelt, um Übersetzungs-Vorschläge für die ausgewählten Ziel-Sprachen zu generieren. Nur agentureigene Marketing-Bausteine — keine Endkunden-Daten, keine Kontaktnamen, keine E-Mails. Output: JSON-Map locale → translation, validiert auf max. 5000 Zeichen pro Vorschlag. max_tokens dynamisch berechnet aus target_locales (R-697), stop_reason-Check vor JSON.parse (R-698). User prüft Vorschläge und entscheidet pro Locale ob übernommen wird. Rate-Limit 5 req/min/IP (insertTagsAiLimiter). Token-Tracking via logTokenUsage(feature=cms_insert_tag_translation). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Tag-Editor. Transient — keine Datenpersistenz bei Anthropic, AI Site Planner Cloudcode Content-Befüllung (PROJ-587 — ai_site_planner_cloudcode_text): Asynchroner pg_cron-Worker (alle 2 Min, max 3 Jobs/Run) erzeugt nach Wireframe-Freigabe pro Section deutsche Marketing-Inhalte via Claude Sonnet 4.5. Übermittelt werden pro Section: Section-Briefing (Name, Purpose, target_component_type) + SSOT-Kontext (Bedarfsgruppen-Namen + -Beschreibungen, Personas-Namen + -Beschreibungen, USP-Texte, CI-Tone aus ssot_items section='ci_guideline') — alle vor Übertragung via sanitizePii() bereinigt. Output: Tool-Use-Schema mit Component-Type-spezifischen Inhalten (Hero-Headlines, Feature-Items, Testimonial-Quotes, FAQ-Items, CTA-Texte etc.). Token-Tracking via logTokenUsage(feature=ai_site_planner_cloudcode_text). max_tokens 1500/Section, AbortSignal 60s/Section, globaler 8-Min-Job-Timeout. Atomic UPDATE ... WHERE status='approved' RETURNING (R-589) verhindert Doppelverarbeitung. Cloudcode-Engine erstellt anschließend cms_pages-Eintrag (status='draft') mit replace_cms_blocks-RPC + Inbox-Notification an triggered_by_user_id. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung an erzeugten CMS-Blocks. Transient — keine Datenpersistenz bei Anthropic, Sales-Deal-Pre-Fill bei Webhook-Auto-Anlage (PROJ-618 — sales_deal_prefill): Synchroner Aufruf im Webhook-Receiver (Contao-Forms-Webhook in webhook-routing.ts + Matelso-Call-Tracking-Webhook in tracking.ts) bei jedem eingehenden Webhook der einen Auto-Deal in der Neukunden-Pipeline erzeugt. Claude Haiku 4.5 erhält den Webhook-Payload (E-Mail, Telefon, Firmenname, Kontaktname, Nachricht, Form-Type) — bei Matelso-Calls wird die un-gehashte caller_number ausschließlich zur Pre-Fill-Auswertung übermittelt und NICHT persistiert (sales_deals.webhook_payload speichert ein sanitized payload mit caller_number=[REDACTED], der Hash bleibt nur in matelso_calls.phone_hash). Output: deal_name (max 80 Zeichen, Format 'Firma — Anliegen'), leistungsbereich (kategorisch aus Whitelist: website/print/software/marketing/branding/sonstiges), kundenkategorie (kategorisch: a/b/c). Bei KI-Timeout, HTTP-Fehler, max_tokens-Truncation oder JSON-Parse-Fehler werden Fallback-Werte gesetzt (deal_name='Neue Anfrage', leistungsbereich='website', kundenkategorie='c') — der Deal wird trotzdem angelegt. ki_prefill_meta JSONB dokumentiert den Source (ki|fallback), Modell, Latenz, Token-Counts und ggf. fallback_reason. Anthropic Prompt-Caching aktiv (cache_control: ephemeral) für den statischen System-Prompt. max_tokens 300 (R-697 dokumentierte Token-Kalkulation), stop_reason-Check vor JSON.parse (R-698), AbortSignal.timeout 15s (R-665), trackError mit Provider-Isolation (R-662). Token-Tracking via logTokenUsage(feature=sales_deal_prefill). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Deal-Detail (deal_name, leistungsbereich, kundenkategorie zeigen Pre-Fill-Marker). Transient — keine Datenpersistenz bei Anthropic, Interview-Fragebogen-Generierung (PROJ-635 — interview_questionnaire): Auf Mitarbeiter-Trigger im SSOT-Top-Level-Step Interviews generiert Claude Sonnet 4 einen strukturierten Fragebogen (3-5 Cluster mit 10-20 offenen Fragen) für ein geplantes Experten-/Mitarbeiter-/Stakeholder-/Kundeninterview. Übermittelt werden: Interview-Topic (vom Mitarbeiter selbst eingegeben, max. 1000 Zeichen), Interview-Typ (kategorisch: expert/employee/stakeholder/customer/other), optionaler Name der zu befragenden Person (max. 200 Zeichen, kann PII enthalten — vom Mitarbeiter selbst eingegeben), verlinkte SSOT-Entity (Bedarfsgruppe/Persona/Zielgruppe/Marketingziel/CI — Workspace-interne Marketing-Strategie-Daten), serialisierter SSOT-Kontext des verknüpften Kontakts (Marketingziele, Zielgruppen-Branchen, Personas, Bedarfsgruppen-Bezeichnungen, USPs, CI-Tonalität — Workspace-interne Strategie-Daten ohne Endkunden-PII), sowie optional bis zu 5 Deep-Research-Snippets aus SerpAPI (Titel + öffentliche Suchergebnis-Snippets als zusätzlicher Themenkontext). Output: strukturiertes JSON mit clusters[].name + clusters[].questions[] — wird in interview_questions als KI-generierte Fragen (is_custom=false) gespeichert und der Session-Status von 'preparing' auf 'ready' gesetzt. research_context (snippets + sources + ssot_summary) wird ebenfalls in interview_sessions persistiert (Workspace-scoped, RLS-geschützt). Prompt-Caching aktiv (cache_control: ephemeral) für den statischen System-Prompt. max_tokens 5000 (R-697 dokumentierte Token-Kalkulation), stop_reason-Check vor JSON.parse (R-698), AbortSignal.timeout 50s (R-665), Provider-Isolation (R-662). Rate-Limit 5 req/min/IP. Token-Tracking via logTokenUsage(feature=interview_questionnaire). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung an erzeugten Fragen. Transient — keine Datenpersistenz bei Anthropic. KI-CD-Generator (PROJ-652): Synthese von Moodboard-Konzepten, vollständigen Farbpaletten (10 Variablen pro Route × 3 Routen) und Typografie-Paarungen (Google Fonts + 7 Textfarben) aus Briefing-Texten, SSOT-Snapshot und hochgeladenen Referenzbildern (Vision via image-Content-Block, Signed-URL 15min TTL). Transkript-Extraktion: PDF/DOCX/Text-Inhalte werden an Claude Sonnet 4.6 zur Antwort-Strukturierung gesendet (transient). Prompt-Caching auf System-Prompts (cache_control: ephemeral, R-658). Max_tokens kalkuliert + stop_reason-Check vor JSON.parse (R-697/R-698). Provider-Isolation in eigenen try/catch-Blöcken (R-662), Virtual Text Generator (PROJ-655): KI-gestützte Text-Generierung für Marketing-Inhalte (Website-Texte, Landingpages, Slogans, Storyboards, Social-Media-Posts) im Kunden-Workspace. Übermittelt werden: User-Prompt (max. 8.000 Zeichen) + SSOT-Kontext-Snapshot (Marketingziel, Bedarfsgruppen, Tonalität, Zielregion, Markenfarben) als strukturierter System-Prompt-Block + gewählte KI-Rolle (SEO-optimiert, Conversion-optimiert, Storyboard, Storytelling, Social Media Post). Model: Claude Sonnet 4.6 mit Anthropic-Prompt-Caching auf SSOT-Kontext (R-658). Token-Verbrauch via logTokenUsage(feature=virtual_text_generator). Max_tokens explizit kalkuliert (R-697) + stop_reason-Check vor JSON.parse (R-698). Provider-Isolation in eigenem try/catch (R-662). Keine Datenpersistenz bei Anthropic (transient). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung an generierten Texten. Virtual Text Generator — QA-Score (PROJ-656): SSOT-Abgleich via Claude Haiku 4.5 (10× günstiger als Sonnet 4.6) zur 4-Aspekte-Bewertung (Marketingziel, Bedarfsgruppen, Tonalität, Zielregion). Eigener Tool-Use mit strukturierter JSON-Antwort, max_tokens=600 (R-697), stop_reason-Check vor Tool-Use-Extraktion (R-698), Provider-Isolation in eigenem try/catch (R-662), AbortSignal.timeout(5_000) (R-665). Prompt-Caching auf SSOT-Kontext-Block (cache_control: ephemeral, R-658). Übermittlung des bereits generierten Assistant-Texts (max. 6.000 Zeichen) + SSOT-Snapshot (Marketingziel, Bedarfsgruppen, Tonalität, Zielregion, USPs) + KI-Rolle. Keine dauerhafte Speicherung bei Anthropic (transient). Token-Verbrauch via logTokenUsage(feature=virtual_text_generator_qa). Virtual Text Generator — Bereichs-Generierung (PROJ-657): Pro CMS-Seite wird Block-Typ-Struktur (Block-Typ-Registry JSON-Schema) + SSOT-Kontext an Claude Sonnet 4.6 übermittelt (strukturierter JSON-Output). Prompt-Caching auf SSOT-Kontext (R-658). Keine Klartext-Block-Inhalte übermittelt. Keine dauerhafte Speicherung bei Anthropic (transient). Virtual Text Generator — Block-Verfeinerung (PROJ-658): Pro Block (Headline/Teaser/Body/CTA) wird aktueller Block-Inhalt + User-Hinweis + SSOT-Kontext + Block-Type-Schema an Claude Sonnet 4.6 uebermittelt. Ergebnis ist Vorschlag den der User explizit annehmen muss. Audit-Trail in virtual_text_review_refinements. Keine dauerhafte Speicherung bei Anthropic (transient). Virtual Text Generator — SSOT-Vorschlag-Erkennung (PROJ-659): Nach jedem Generierungs-/Verfeinerungs-Auftrag wird User-Prompt + generierter Text + bestehender SSOT-Kontext an Claude Haiku 4.5 uebermittelt zur Identifikation neuer SSOT-relevanter Informationen. Strukturierter JSON-Output mit confidence 0-1. Backend filtert Werte < 0.6 serverseitig. Keine dauerhafte Speicherung bei Anthropic (transient). Impact-Analyse bei SSOT-Änderungen (PROJ-660): Pro neuer SSOT-Änderung (ssot_history-Zeile mit Section marketing_goal/target_group/persona/usp) wird Claude Haiku 4.5 fuer die Severity-Klassifikation (low/medium/high) genutzt; bei medium/high laeuft ein Claude Sonnet 4.6-Call pro betroffener CMS-Seite (max. 20 Seiten pro Event) zur Identifikation veralteter Textstellen mit konkretem Anpassungs-Vorschlag. Uebermittelt werden: SSOT-Delta (previous_data + new_data), Block-Liste der Seite (block_id + Typ + current_content). Konfidenz-Threshold 0.5 + Programm-Konsistenz-Check (Vorschlag muss mindestens ein Keyword aus new_data enthalten) verwerfen Halluzinationen serverseitig. Prompt-Caching auf System-Block (R-658), max_tokens explizit kalkuliert (R-697), stop_reason-Check vor Tool-Use-Extraktion (R-698), AbortSignal.timeout 10s/30s (R-665), Provider-Isolation in eigenem try/catch (R-662). Keine dauerhafte Speicherung bei Anthropic (transient). Brand Vision Studio (PROJ-654): Claude Vision (claude-sonnet-4-6) analysiert hochgeladene Kunden-Rohbilder zur Master-Prompt-Synthese (Stil-Stichworte, Komposition, Licht-Erkennung) — Bild via signed URL transient an Claude übermittelt, kein persistentes Speichern bei Anthropic. Zusätzlich Claude Haiku 4.5 für Kategorie-Erkennung (Phase 3 — Mapping User-Beschreibung → 1 von 5 Bildkategorien Portrait/Action/Product/Lifestyle/Abstract). Prompt-Caching auf System-Prompts (cache_control: ephemeral, R-658). AbortSignal.timeout 60s (R-665). Provider-Isolation in eigenem try/catch (R-662), Virtual Text Generator (PROJ-655): Dedizierter KI-Text-Generator im Kunden-Workspace. Pro Generierung werden User-Prompt (max. 8.000 Zeichen) + strukturierter SSOT-Kontext-Block (Marketingziele, Bedarfsgruppen, Tonalität, Zielregion, Markenfarben) an Claude Sonnet 4.6 übermittelt. Anthropic Prompt-Caching auf SSOT-Kontext-Block (cache_control: ephemeral, R-658). Potenzielle PII in User-Prompts (Klarnamen Dritter) — PII-Disclaimer-Banner im UI informiert Nutzer; kein serverseitiges PII-Scrubbing, da der Nutzer selbst verantwortlich ist. Keine dauerhafte Speicherung bei Anthropic. Brand Vision Studio (PROJ-654): Claude Vision (claude-sonnet-4-6) analysiert hochgeladene Kunden-Rohbilder (via signed URL, transient) zur Master-Prompt-Synthese — Bilder können Personen zeigen, nicht dauerhaft bei Anthropic gespeichert. Claude Haiku 4.5 klassifiziert User-Prompts in Bildkategorien (portrait/action/product/lifestyle/abstract) — rein kategorisch, kein PII-Bezug. KI-Requirements-Assistent (PROJ-662 + PROJ-664): Claude Sonnet 4.5 führt durch 5-Phasen-Konversation (Kern-Idee → User Stories → Acceptance Criteria → Edge Cases → Scope) und generiert daraus eine strukturierte Feature-Spezifikation (Markdown). System-Prompt wird workspace-spezifisch in ai_assistants.system_prompt gepflegt (Admin-editierbar). Chat-Verlauf in ai_conversation_messages persistiert. PROJ-664-Erweiterung: Mitarbeiter können pro Chat-Nachricht 1–5 Anhänge (PNG/JPG/WebP/GIF/PDF, max. 10 MB pro Datei) hochladen. Bilder werden serverseitig resized (sharp, max. 2048 px Längstkante) und als Base64-Vision-Block im messages.create()-Call mitgeschickt. PDFs werden serverseitig zu Plain-Text extrahiert (pdf-parse, max. 100k Zeichen) und als Text-Block vor die User-Nachricht in den Content-Array gemerged. Beide Datenpfade sind transient — Anthropic speichert weder Bilder noch PDF-Text dauerhaft, kein Training auf den Daten. Mitarbeiter trägt PII-Verantwortung für hochgeladene Inhalte (Mockups können Klarnamen/E-Mail-Adressen enthalten), Spec-Generierung als separater Sonnet-Call mit Prompt-Caching (R-658). User-Eingaben können Feature-Beschreibungen mit Bezug zu Kunden, Mitarbeitern oder Dritten enthalten — Workspace-Admin trägt Verantwortung für Inhalts-Prüfung vor GitHub-Commit. Keine dauerhafte Speicherung bei Anthropic. PROJ-621 Open Graph Tag-Generation aus CMS-Seitenkontext (Page-Title + extrahierter Block-Inhalt, max 2.000 Zeichen): Generiert og:title, og:description, twitter:title, twitter:description in mehreren Sprachen für Social-Media-Sharing-Karten via Claude Haiku. Workspace-Opt-In via workspace_og_settings.ki_generation_enabled (Default false); Eingabe enthält Marketing-Texte der Workspace-Pages, keine Endkunden-PII aus CRM/Identity-Systemen. Keine dauerhafte Speicherung bei Anthropic. AI Talk Studio (PROJ-666): KI-Dialog-Gesprächsführung als NORA-Persona (Neuland Operations & Reasoning Assistant) — System-Prompt enthält statisches NEULAND-Unternehmenswissen + NeulandOS-Featureliste (keine Endkunden-PII). Conversation-History wird pro Turn an Anthropic übermittelt (transient, kein Training, keine dauerhafte Speicherung). max_tokens 400 pro Antwort (ca. 120 Wörter). Prompt-Caching auf statischem System-Prompt-Block (cache_control: ephemeral). Keine Personaldaten, Kundendaten oder PII im Prompt — ausschließlich eigene Agenturdaten als Gesprächskontext. Image-Prompt-Enhancer (PROJ-683 Phase 4, image_prompt_enhance via Claude Sonnet 4.6): KI-gestützte Anreicherung von User-Prompts im CMS-KI-Studio vor der Bildgenerierung — der User-Prompt plus Kontextfelder (Aspect-Ratio, Kamera-Preset-Summary, Face-Lock-Status, Brand-Style-Beschreibung, Brand-Avoid-List) wird transient an Anthropic uebermittelt; Original-Prompt bleibt erhalten, Enhancer ist additiv. Keine personenbezogenen Daten im Standardfluss — Brand-Style-Beschreibungen sind Unternehmens-Stilrichtlinien (Art. 6 Abs. 1 lit. f DSGVO, berechtigtes Interesse an effektiver Bildgenerierung). Prompt-Caching (cache_control: ephemeral) auf System-Prompt + Modifikator-Bibliothek; keine Conversation-History-Persistenz bei Anthropic, kein Training. Shop-Suche LLM-Re-Ranking (PROJ-767 Stufe 3): rohe Such-Anfrage des Endkunden + Top-12-Produkt-Kandidaten (Name + Brand + Preis) werden transient an Claude Haiku 4.5 zur Relevanz-Re-Ordnung übermittelt; max_tokens=1200, JSON-Antwort mit re-rangierter ID-Liste. System-Prompt cacheable für 5-Min-Window (Cost-Reduktion ~90 %). Workspace-Tagesbudget (Default 10 €) via shop_config.search_llm_daily_cap_cents — bei Überschreitung Fallback auf RRF-Fusion ohne Re-Rank. Opt-out pro Workspace via shop_config.search_llm_rerank=false. Endkunden-Queries können implizit PII enthalten (z.B. wenn jemand seinen Namen tippt) — werden in der Shop-DB mit Hash-IP gespeichert (180-Tage-Retention). Steuerrelevanz-Klassifikation von Dokumenten für die Einkommensteuer-Checkliste (PROJ-877, Claude Haiku — Input: OCR-Text des Dokuments gekürzt auf max. 1500 Zeichen + Checklisten-Punkt-Definitionen; Output: Zuordnungsvorschlag zum passenden Checklisten-Punkt + Konfidenz + kurze Begründung; transient, kein Training, Prompt-Caching via cache_control:ephemeral). Eingangsrechnungs-Feld-Extraktion (PROJ-905, Claude Haiku 4.5 — Input: OCR-Text einer Lieferantenrechnung gekürzt auf max. 12000 Zeichen; Output: strukturierte Rechnungsfelder inkl. Lieferantenname, IBAN, BIC, Beträge, Rechnungs-/Fälligkeitsdatum, Skonto, Zahlungsart + Konfidenz; transient, kein Training, Prompt-Caching via cache_control:ephemeral)., Präsentations-Slide-Generierung (PROJ-942): KI-generierte Slide-Struktur (Claude Sonnet 4.6) aus PM-Freitext-Briefing + optionalem Template-Typ (sales_pitch/logo_presentation/product_overview); Input: prompt_text max. 5000 Zeichen + Template-Preset-Kontext; transient, kein Training, kein Speichern bei Anthropic, Kampagnen-Konfigurator (KI-Ableitung von Targeting/Badges aus Kampagnenziel, Landingpage-Inhalt und SSOT-Kontext) (PROJ-955): Claude Sonnet 4 leitet aus Kampagnenziel-Freitext, durchgereichtem Landingpage-Inhalt (Titel/Meta/H1/Body-Auszug) und SSOT-Kontext strukturierte Targeting-Empfehlungen und Konfigurator-Badges pro Werbenetzwerk ab; transient, kein Training, keine Persistenz bei Anthropic, Bug-/Wunsch-Status-Abgleich (PROJ-978): Titel/Beschreibungen offener Bug-Reports und Feature-Wünsche werden transient gegen Release-Changelogs abgeglichen, um wahrscheinlich-behobene oder Duplikat-Kandidaten zu markieren (Claude Sonnet 4.6); transient, kein Training, keine Persistenz, Potenzialanalyse-Dashboard-Generierung (PROJ-995): Im Sales-Modul werden gesammelte Analyse-Daten (öffentliche Website-Inhalte, Keyword-/SERP-Metriken, Social-Media-Treffer, Branchen-/Zielgruppen-Stammdaten) an Claude Haiku 4.5 übermittelt, um eine redaktionelle Website-Bewertung sowie ein kundentaugliches Dashboard (9 Ampeln, Handlungsempfehlungen, Gesprächsfragen) zu generieren; transient, kein Training, keine Persistenz bei Anthropic, Prompt-Caching via cache_control:ephemeral, Bedarfsgruppen-KI-Assistent (PROJ-1027): SSOT-Marketingdaten (Zielmärkte, Marketingziele, Keywords aus der keywords-Tabelle), gecrawlte Navigationsstruktur der eigenen Kunden-Domain (Seitentitel, URL, Hierarchieebene — ausschließlich öffentlich zugängliche Seiten) und DataForSEO-Domain-Sichtbarkeitswerte (eigene Domain + bis zu 20 Wettbewerber-Domains) werden transient an Claude übermittelt (Modell konfigurierbar in ai_assistants.workflow_config.model, Systemprompt aus ai_assistants.system_prompt), um eine vollständig befüllte Bedarfsgruppen-Seitenstruktur (Segmenttyp, Navigationsebene, Sichtbarkeit, Mehrsprachigkeit) zu generieren; ausschließlich Unternehmens-Marketing-Daten ohne Endnutzer-PII; transient, kein Training, keine Persistenz bei Anthropic, GMC-Titeloptimierung (PROJ-1062, Claude Sonnet 4.6 — Optimierung von Produkttiteln für das Google Merchant Center; Input: Produkttitel + Kontextspalten Kategorie/Marke/Attribute aus einem Google-Sheet; reine Produktdaten ohne Personenbezug; transient, kein Training, keine Persistenz bei Anthropic; Systemprompt aus ai_assistants.system_prompt; seit PROJ-1318 zusätzlich Plattform-Admin-only Debug-Log in hawego_title_optimization_debug_log — Systemprompt und Rohantwort jedes LLM-Calls, Erfolg und Fehlschlag, ausschließlich Produkttitel/SKU-Bezug ohne Personenbezug, 30 Tage Retention via täglichen Cleanup-Cron, RLS deny-all mit Zugriff nur über Service-Role und isPlatformAdmin-Gate; seit PROJ-1460 zusätzlich Einzel-Artikel-Aufruf aus dem Dashboard-Fokus-Panel — identischer Zweck/Prompt/Modell wie der bestehende Batch-Lauf, nur pro einzelnem Artikel statt im Batch, beliebig oft wiederholbar über „Erneut iterieren“, KI-Vorschlag im UI mit Modellname gekennzeichnet), Kundenportal-Demo-Generierung (PROJ-1257, Claude Haiku 4.5 — Dealkontext (Dealname, Leistungsbereich) wird transient übermittelt um fiktive Demo-Inhalte zu generieren; kein Training, keine Persistenz bei Anthropic), System-Demo Slideshow (PROJ-1262, Claude Haiku 4.5 — Dealkontext und Kundenname werden transient übermittelt um fiktive branchenspezifische Slideshow-Demo-Inhalte zu generieren; kein Training, keine Persistenz bei Anthropic), Content Intelligence Phase 03a–05 (PROJ-1305, ab 2026-06-28, erweitert PROJ-1401 ab 2026-07-05, PROJ-1406, Claude Sonnet 4.6 — KI-Analyse für CI-Phasen Topic Blueprint/Cluster-Analyse/Konsolidierung/Conversion/Textgenerierung; ersetzt die frühere Gemini-Anbindung (PROJ-785/786). Übermittelt: SSOT-Markdown des Kunden (Unternehmensname, Branche, Marketingziele, Bedarfsgruppen-Beschreibungen — können in seltenen Fällen Personennamen enthalten), Target-Keyword + URL, SERP-Top-10-URLs (Wettbewerber-Domains), PAA-Questions (öffentliche Suchergebnisse), Search Intent, HTML-Wettbewerber-Inhalte (öffentlich), bei Phase 05 zusätzlich Content-Plan-Seiten + Grounding-/Validierungs-Befunde aus Phase 03c/04 + AI-Overview-Text und Related-Searches (öffentliche Google-Suchdaten, PROJ-1387, PROJ-1406). Output: Topic Blueprint, Cluster-Analyse, Content-Fahrplan, Conversion-Strategien, bei Phase 05 vollständige Seitentexte inkl. Claim-Level-Reasoning (grounded/generated/open_question) — als strukturierter JSON zurückgegeben. Prompt-Caching aktiv (R-658). Transient, kein Training auf Kundendaten, keine Persistenz bei Anthropic. Token-Usage in content_intelligence_jobs.token_usage_total pro Job), SSOT Initial-Multi-Source-Befüllung (PROJ-1378, Claude Haiku 4.5 — Rohtext aus bis zu 6 Quellentypen (Website-Crawl-Text, Google-Drive-Dateiinhalte, Datei-Uploads (Bild/PDF via OCR; TXT/MD/Word .docx seit PROJ-1424 direkt als Text, ohne OCR), NotebookLM-Export-Text, interne Kommentare/Kommunikationshistorie, Meeting-/Call-Transkripte) wird transient zur Extraktion strukturierter SSOT-Vorschläge (Enrich/Create/Conflict + Confidence-Score) übermittelt. Interne Kommentare werden vor der Übermittlung von @Mention-Personenverweisen bereinigt (anonymizeMentions()). Kein Training, kein Auto-Schreiben — jeder Vorschlag durchläuft eine manuelle Bestätigung vor Übernahme in die SSOT), SSOT Domain-Re-Crawl-Validierung (PROJ-1379, Claude Haiku 4.5 — beim manuellen Re-Crawl der hinterlegten Kundendomain wird der neu gecrawlte Website-Text zusammen mit den bestehenden SSOT-Werten (Zielgruppen/Personas/Marketingziel-Beschreibungen des Kontakts) als Vergleichsbasis transient an Anthropic übermittelt, um Enrich/Create/Conflict-Vorschläge zu erzeugen. Anders als bei PROJ-1378 fließen hier bereits gespeicherte SSOT-Daten in denselben Anthropic-Call ein — diese können in Einzelfällen Namen von Geschäftsführern/Ansprechpartnern enthalten, falls entsprechende SSOT-Items hinterlegt sind. Tabu-Felder (Budget, Vertragskennzahlen TCQ/ACV, Laufzeiten) werden vor Übermittlung serverseitig aus dem Kontext entfernt (stripTabooFromData()) und aus KI-Antworten verworfen. Kein Training, kein Auto-Schreiben — jeder Vorschlag durchläuft eine manuelle Bestätigung vor Übernahme in die SSOT), SSOT laufende Aktualisierung aus NEULAND-Aktivität (PROJ-1380, Claude Haiku 4.5 — wöchentlicher, automatisierter Scan pro aktivem Kunden-Kontakt mit gepflegter SSOT: Kommentare (Kontakt/Projekt/Aufgabe), Deal-Notizen, Vertriebs-Gesprächsauswertungen, Meeting-Transkripte und Google-Drive-Dateiänderungen (inkl. OCR-Text) werden gebündelt in einem KI-Call ausgewertet, um konsolidierte SSOT-Vorschläge mit Zuordnungs- und Änderungs-Confidence zu erzeugen. @Mention-Personenverweise werden vor jeder Übermittlung aus allen Quellen entfernt (anonymizeMentions()). Kein Training, kein Auto-Schreiben — jeder Vorschlag durchläuft eine manuelle Bestätigung durch einen zuständigen Agentur-Mitarbeiter vor Übernahme in die SSOT; Kunden haben keinen Zugriff auf diese Vorschläge. Zusätzlich manueller Sofort-Trigger pro Kontakt möglich, max. 3×/Tag), Bid4it-Künstler-Anreicherung (PROJ-1429, Custom-Modul Nagel Auktionen, opt-in, Claude Sonnet, generateObject mit SerpAPI-Suchergebnissen als Beleg-Kontext, temperature=0 — extrahiert NUR in den Suchergebnissen belegte biografische Eckdaten öffentlicher, teils lebender Künstler aus dem Auktionskatalog, erfindet keine unbelegten Fakten, kein Training, Ergebnis landet ausschließlich im Google Sheet), Organic-Social Content-Thema-Klassifikation (PROJ-1469, Claude Haiku 4.5, temperature=0 — ordnet veröffentlichten Social-Media-Beiträgen des Workspace genau ein Content-Thema aus einer geschlossenen, workspace-eigenen Themenliste zu; Input: Beitragstext gekürzt auf 600 Zeichen, transient, kein Training, Ergebnis ist ausschließlich eine Themen-ID in social_post_performance), Organic-Social Beitrags-Ziel-Klassifikation (PROJ-1837, Claude Haiku 4.5, temperature=0 — schlägt nachträglich geladenen Altbeiträgen ein Beitrags-Ziel aus einer geschlossenen, fest im Code hinterlegten Werteliste vor; Input: Beitragstext gekürzt auf 600 Zeichen, transient, kein Training; Ergebnis ist ausschließlich ein Zielwert plus dessen Herkunft in social_post_performance; Beiträge ohne Text werden gar nicht erst übermittelt, ein von Hand gesetztes Ziel wird nie überschrieben), KI-Briefing-Abgleich gegen SSOT (PROJ-1535, Claude Haiku 4.5, temperature=0 — prüft auf manuellen Button-Klick das Beschreibungsfeld einer Redaktions-Aufgabe gegen die SSOT-Bedarfsgruppen des Kunden; Input: Aufgaben-Titel + Beschreibung (max. 6.000 Zeichen) + Bedarfsgruppen-Bezeichnungen, transient, kein Training; Ergebnis (erkanntes Thema, Zielgruppen-Treffer/Lücke, deterministisch ermittelte SEO-Überschneidungen) wird als Momentaufnahme in task_briefing_checks gespeichert), Modul-Style-KI-Assistent (PROJ-1620, Claude Haiku 4.5 — schlägt Style-Änderungen an CMS-Modul-Konfigurationen vor, Input: aktuelle Modul-Config-Felder + Nutzeranweisung + optional CI-Farbpalette, alles rein technische Konfigurations-/Markendaten ohne PII, transient, kein Training), Server-Advisor (PROJ-1575, erweitert PROJ-1664, manuell angestoßene KI-Wartungsempfehlungen für betreute Kundenserver — Input: Server-Alias/Hostname, Infrastruktur-Messwerte und Kapazitätswerte inkl. der vier Fallback-Kapazitätswerte aus contao_servers, NIEMALS SSH-Zugangsdaten/Passwörter/Keys/SQL-Query-Texte; Ergebnis: Text-Empfehlungen in server_advisor_findings, transient, kein Training, keine automatischen Aktionen), KI-Website-Vollgenerierung Schritt 9 — Seiteninhalte (PROJ-1776, Claude Sonnet 4.6 — befüllt die per Website-Generierung angelegten CMS-Seiten mit Fließtexten; Input: SSOT-Marketing-Kontext der Marke (Bedarfsgruppen, Tonalität, USPs, Personas, Dos&Don'ts, Wording-Listen) — Bedarfsgruppen-/Seitendaten nach sanitizePii-Filterung, CI-Vorgaben (Tonalität/USPs/Dos&Don'ts/Wording-Listen) nach sanitizeForPrompt-Filterung (Steuerzeichen-/Injection-Schutz, kein PII-Bezug), KEINE Kontaktdaten im Klartext (Telefon/E-Mail/Anschrift werden als Insert-Tag-Platzhalter referenziert); Ergebnis wird als Seiteninhalt in cms_pagebuilder_pages gespeichert; transient, kein Training), Wallbox-Ladesitzungsbericht-Extraktion (PROJ-1797, Claude Haiku 4.5 — extrahiert strukturierte Ladevorgangsdaten aus dem als Text vorliegenden PDF-Bericht der privaten Wallbox: Wallbox-Seriennummer, RFID-Karten-Bezeichnung, geladene Energie in kWh, Zählerstände, Zeitstempel je Ladevorgang; die RFID-Karten-Bezeichnung wird vom Betreiber im Wallbox-Portal frei vergeben und kann theoretisch einen Mitarbeiternamen enthalten — Empfehlung: neutrale Bezeichnung statt Klarname verwenden; transient, kein Training, kein Speichern bei Anthropic, Ergebnis wird in wallbox_charging_sessions gespeichert), Bedarfsgruppen-Import-Platzhalter-Umschreibung (PROJ-1805, Claude Sonnet 4.6 — schreibt beim Schnell-Import einer Bedarfsgruppen-Vorlage rohe Klammer-Platzhalter-Bezeichnungen wie „[Daten] > [Branchen]“ in kundenspezifische Navigations-Begriffe um, damit generierte Website-Seiten nie sichtbare Platzhalter zeigen; Input: Firmenname, Branche sowie vorhandene SSOT-Marketing-Ziele/Zielgruppen/Personas/USPs des Kontakts (nur als Kontext, keine wörtliche Übernahme), die zu ersetzenden Segment-Texte; transient, kein Training, kein Speichern bei Anthropic; Ergebnis überschreibt lediglich den bestehenden Platzhalter-Wert in ssot_items.data.bezeichnung, kein neues Datenfeld; greift ausschließlich beim Import einer System-Vorlage, nicht bei Workspace-eigenen (von Menschen gepflegten) Vorlagen; Fehlschlag blockiert den Import nicht (fail-open), ein separates, content-basiertes Sicherheitsnetz verhindert unabhängig davon die Website-Generierung solange noch unaufgelöste Platzhalter vorhanden sind), WaWi-Katalog-Import Spalten-Zuordnung (PROJ-1742 Phase 2d, Claude Haiku 4.5 — schlägt im Prüfschritt vor, welche Spalte eines Kunden-Katalogs auf welches WaWi-Zielfeld abgebildet wird; Input: Spaltenüberschriften plus bis zu drei auf 60 Zeichen gekürzte Beispielwerte je Spalte sowie der Zielfeld-Katalog inkl. registrierter Merkmals-Labels — keine Rohkopie, keine vollständigen Katalogzeilen; enthält der Katalog Ansprechpartner-Spalten, können deren Beispielwerte Namen enthalten; transient, kein Training, kein Speichern bei Anthropic; jeder Vorschlag wird serverseitig gegen den echten Zielfeld-Katalog validiert und ausschließlich vom Menschen im Prüfschritt übernommen, nichts wird automatisch gespeichert); Organic-Social-Insight-Generierung (PROJ-1855, Claude Sonnet 5 — formuliert ein deterministisch ermitteltes Learning aus dem Organic-Social-Cube (PROJ-1824) in einem Satz natürlicher Sprache; Input: bereits berechnete, auf 5er-Schritte gerundete Kennzahlen plus lesbare Dimensions-Bezeichnungen (Format, Netzwerk, Wochentag, Zeitfenster, Content-Thema, Marketingziel-Titel) — keine Rohmetriken, keine Post-Texte, keine Einzelpersonenbezüge; transient, kein Training, kein Speichern bei Anthropic; Kandidaten-Auswahl erfolgt vollständig im Code, das Modell wählt nicht aus; Zahlen-Treue und verbotene Fachbegriffe werden nach der Antwort deterministisch geprüft, bei Verstoß wird der Text verworfen und nicht gespeichert), Strukturprüfung Korrekturvorschläge (PROJ-1886, Claude Sonnet — je Strukturbefund wird beim ersten Öffnen ein Korrekturvorschlag erzeugt und gespeichert, danach nur noch gelesen; übermittelt werden Seitenbezeichnungen, Adressen, Navigationsebene, Segmenttyp und die weiteren SSoT-Konfigurationsfelder der betroffenen Seiten einer Kundenwebsite, keine personenbezogenen Daten, Freitextanteile vorher bereinigt; kein Training, kein automatisches Anwenden — jede Änderung braucht eine ausdrückliche menschliche Übernahme), Strukturprüfung KI-Optimierungsassistent (PROJ-1889, Claude Sonnet — anderer Zweck als der Einzelvorschlag: bündelt beim Öffnen des Wizards die bereits erzeugten Korrekturvorschläge des gesamten offenen Befundbestands eines Kunden zu wenigen Entscheidungsschritten und erklärt sie; übermittelt werden dieselben Seitenbezeichnungen/Adressen/Konfigurationsfelder wie bei PROJ-1886 plus die Vorschlagstitel, außerdem je Befund die Punktkosten (Zahl) und die Score-Dimension (fester Kategoriename aus SCORE_DIMENSION_LABEL, kein Freitext), sowie eine aggregierte SSOT-Kontext-Zeile mit der Gesamtseitenzahl des Kunden und der Seitenzahl je Segment-Bezeichnung (Bugfix AC-B1, 04.08.2026); keine personenbezogenen Daten, alle Freitextanteile (Seitenbezeichnungen, Vorschlagstitel, Segment-Bezeichnungen) vorher bereinigt (sanitizeForPrompt); kein Training, erzeugt selbst keine Feldwerte/Diffs/Score-Zahlen — jede Übernahme bleibt an eine ausdrückliche menschliche Auswahl gebunden), Seitentext-Erzeugung aus Bedarfsgruppen-Knoten (PROJ-1865, Claude — zweiter, gleichwertiger Content-Intelligence-Erzeugungsweg über denselben callCiPhaseAnthropic-Helfer; erzeugt gegliederten Seitentext für einen Bedarfsgruppen-Knoten; übermittelt werden Seitenbezeichnung/-pfad/-typ/-ziel/-KPI, die zuletzt ermittelte Seitenrolle, Marketingziele, Zielgruppen/Personas und USPs aus der SSOT, die Corporate-Language-Vorgaben sowie die zulässigen internen Linkziel-IDs; keine personenbezogenen Daten, Freitextanteile vorher R-1446-sanitisiert; kein Training, kein automatisches Veröffentlichen — der erzeugte Text bleibt Entwurf bis zur ausdrücklichen menschlichen Übernahme), USP-Generik-Klassifikation (PROJ-2114, Claude Sonnet 4.6 — bewertet einmalig je USP-Eintrag aus der SSOT, ob er seitenspezifisch/belegbar oder ein generisches Firmen-Wertversprechen ist; übermittelt werden ausschließlich USP-Titel und -Beschreibung (Firmen-Aussagen, keine personenbezogenen Daten), R-1446-sicher als Daten interpoliert; Ergebnis wird gecacht und überlebt unveränderte USPs ohne erneuten Aufruf; kein Training, keine Speicherung bei Anthropic), Keyword-Universum im SEO/GEO-Research-Portal (PROJ-1891, Claude Haiku 4.5 — schlägt zu einem Research-Keyword Synonyme und Fragen ohne Suchvolumen vor; an das Modell gehen ausschließlich das Keyword und die Zieldomain, keine Kundendaten und keine Freitexte aus der Datenbank; transient, kein Training, keine Speicherung bei Anthropic; die Vorschläge tragen in der Oberfläche sichtbar ihre KI-Herkunft und werden nie als gemessener Wert dargestellt), Kampagnen-Projektzuordnung (PROJ-1874, Claude Haiku) — automatische Vorauswahl bei mehrdeutigen Fällen, Wireframe-KI (PROJ-1866, Claude Sonnet — erzeugt aus dem sanitisierten Kunden-Seitentext (PROJ-1865) eine begründete Wireframe-Elementliste mit Zweck/Begründung/Confidence je Element und Bewertung gegen selbstgesetzte Faktoren; übermittelt werden ausschließlich R-1446-sanitisierte Struktur-, Text- und Faktoren-Freitexte, transient, kein Training, kein automatisches Veröffentlichen), Suchbegriff-Klassifikation für die HAWEGO-Werbekosten-Zuordnung (PROJ-2037, Claude Haiku 4.5 — ein einzelner, deterministisch nicht eindeutig auflösbarer Google-Ads-Suchbegriff/Keyword/Anzeigengruppen-Name wird transient zur Zuordnung auf eine Produktgruppe klassifiziert; Roh-Suchbegriff nur als klar markierte Nutzer-Daten übergeben, nie im System-Prompt interpoliert (R-1446), Ausgabe gegen ein festes Vokabular geprüft; temperature 0, kein Training, kein Auto-Übernehmen — das Ergebnis wird nur als prüfungspflichtiger Vorschlag gespeichert), Unified-Dimensions-Verkabelung & Regelvorschlag (PROJ-2126, Claude Haiku — `POST /axes/suggest-wiring` + `POST /rules/suggest`: aus Feldnamen, je Feld EINEM sanitizePii-redaktierten Beispielwert und der Freitext-Zielbeschreibung schlägt die KI je Quelle die Zuordnungsart (direktes Feld / Formatangleichung / Regelkaskade), das Herkunftsfeld bzw. Ableitungsregeln vor; Nutzer-Freitext nie im System-Prompt interpoliert (R-1446), Ausgabe gegen echtes Quellenschema + Vokabular-Whitelist validiert, transient, kein Training, nur als prüfungspflichtiger Vorschlag), siehe DATA_PROCESSINGS | Nutzereingaben, Konversationsinhalte, Projektdaten (teilweise anonymisiert), ausgewählte Kundendaten (Personas, Markenziele, Zielgruppen), Aufgabeninhalte und Kommentare (anonymisiert) für KI-Mitarbeiter-Ausführungen, Dokumenteninhalte (Rechnungen, Belege) zur OCR-Analyse, Buchhaltungsdaten (Lieferantennamen, Beträge, Buchungstexte, Kontonummern), pseudonymisierte Lohndaten, Marketing-Briefing-Daten (Thema, Tonalität, Keywords) für Asset-Generierung, Marketing-Strategiedaten (Kontaktdaten, Zielgruppen, Suchworte) für Strategie-Beratung, CMS-Kontextdaten (SSOT, Keywords, Bedarfsgruppen) für KI-gestützte Landingpage-Generierung, Workflow-Briefings und SSOT-Kontextdaten (anonymisiert) für mehrstufige KI-Workflow-Pipelines, Meeting-Transkripte (anonymisiert) für KI-Zusammenfassungen, öffentliche Unternehmensdaten (Firmenname, Snippet — anonymisiert via sanitizePii()) für Web-Recherche-Qualifizierung, E-Mail-Betreff und Textvorschau (anonymisiert via sanitizePii()) für Gmail-Kategorisierung und Zusammenfassung, Diktat-Transkripte (Nutzereingabe, keine Anonymisierung — eigene Diktate des Nutzers) für Voice-Diktat-Optimierung durch persönlichen Schreibassistenten, Sprach-Transkripte (anonymisiert via sanitizePii()) für Voice-Agent-Intent-Klassifizierung (Aufgabenwunsch, Kommentar, Statusabfrage), Briefing-Chat-Verlauf und Vorlagen-Name (in-memory, keine dauerhafte Speicherung) für KI-Briefing-Assistent im Kundenworkspace, freiwillige Geschäftsangaben im Signing-Chat (Branche, Umsatzgröße, Marketing-Budget — kein PII, transient, nicht gespeichert) für Marktpotenzial-Analyse, Aufgaben-Titel und Benachrichtigungs-Titel (transient, können Personenbezug enthalten) für Fokus-Queue-Priorisierung, Redakteurs-Cockpit Kundennachrichten-Generator (PROJ-1276, Claude Haiku 4.5 — Ansprechpartner-Name und ausgewaehlte KI-Empfehlungs-Titel werden transient uebermittelt um 3 Textvarianten fuer professionelle Kundennachrichten zu generieren; kein Training, kein Auto-Versand, keine dauerhafte Speicherung bei Anthropic), Playbook-Ermessens-Schritte (PROJ-1784): Aufgaben-Titel/-Beschreibung, Projekt-Name und — falls die Aufgabenvorlage eine verknüpfte interne Prozess-Dokumentation (SOP-Artikel) hat — deren Inhalt (gekappt auf 8.000 Zeichen) werden analog zu bestehenden KI-Ermessens-Entscheidungen in den System-Prompt eingespeist, alle Freitextfelder via sanitizePii() anonymisiert (E-Mail/Telefon/@Mention-Redaktion) — SOP-Inhalte sind agenturinterne, redaktionell gepflegte Prozessbeschreibungen ohne Kundenbezug | USA (Auftragsverarbeitungsvertrag gemäß Art. 28 DSGVO in Commercial Terms) | Link |
| Google LLC (Generative Language API / Gemini) | Content Intelligence (PROJ-782 Foundation + PROJ-783 Dashboard + PROJ-784 Phase 01/02 + PROJ-785 Phase 03 + PROJ-786 Phase 04 deployed 2026-05-26 — ⚠ Phase 03a–04 seit PROJ-1305 (2026-06-28) zu Anthropic migriert; Gemini wird für CI nicht mehr aktiv genutzt): KI-gestützte Inhaltsanalyse und Content-Strategie-Generierung für CRM-Kontakte. Eingesetzte Endpunkte: chat/completions (OpenAI-kompatibles Format) mit Modellen gemini-2.5-pro und gemini-2.5-flash (frühere Modellvarianten gemini-2.0-flash, gemini-1.5-pro wurden 2026-05 von Google deprecated und werden nicht mehr verwendet). In Foundation (PROJ-782) ist der Workspace-Admin in der Lage, einen Gemini-API-Key zu hinterlegen (AES-256-GCM verschlüsselt gespeichert) und einen Verbindungstest auszuführen (POST /chat/completions, max_tokens=5, Test-Payload `ping` — keine personenbezogenen Daten). Mit PROJ-785 (Phase 03 KI Content-Planung) werden je Analyse-Job folgende Daten an Gemini übermittelt: SSOT-Kontext des Kunden (Unternehmensname, Branche, Marketingziele, Bedarfsgruppen — können personenbezogene Daten enthalten wenn SSOT-Items Kontaktpersonen erwähnen), Target-Keyword + URL, SERP-Top-10-URLs (Wettbewerber-Domains), PAA-Questions (öffentliche Google-Suchergebnisse), HTML-Inhalte der eigenen Website + Top-10-Wettbewerber (öffentlich zugänglicher Content). Gemini erzeugt strukturierten JSON-Output: Topic Blueprint, Pillar-Cluster, Content-Fahrplan mit Seiten-Vorschlägen, Conversion-Strategien je Seite (Persona, CTAs). Mit PROJ-786 (Phase 04 Conversion Gate) zusätzlich: Conversion-Strategie-Generierung pro geplanter Seite mit SSOT-Marketingzielen und Zielgruppen-Beschreibungen als Input. Prompt-Caching aktiv (R-658) — SSOT-Block wird als cached System-Prompt-Teil markiert. JSON-Mode erzwungen (response_format: {type: 'json_object'}). Gemini-API ist OpenAI-kompatibel — base_url=https://generativelanguage.googleapis.com/v1beta/openai/. Daten werden transient verarbeitet, kein Training auf Customer-Daten gemäß Google Cloud Privacy Notice (Google AI / Gemini API for Workspace-eligible use). Token-Usage wird in jobs.phase_checkpoint.phase_03.token_usage pro Call getrackt. | API-Key (server-seitig, AES-256-GCM verschlüsselt in content_intelligence_settings), Test-Payload für Verbindungstest (max_tokens=5 — keine personenbezogenen Daten). Bei PROJ-785 Phase 03 (deployed 2026-05-26) werden an Gemini übermittelt: Target-Keyword (Marketingbegriff ohne Personenbezug), Target-URL (Kunden-Webseiten-URL), Domain-Namen Top-10-Wettbewerber (öffentliche Geschäftsdaten), SERP-Snippets (öffentliche Google-Antworten), PAA-Questions (öffentliche Google-Antworten), HTML-Inhalte öffentlich zugänglicher Webseiten (eigene + Wettbewerber), SSOT-Markdown (Unternehmensname, Branche, Marketingziele, Bedarfsgruppen-Beschreibungen — können in seltenen Fällen Personennamen enthalten wenn SSOT-Items Geschäftsführer/Ansprechpartner erwähnen). Gemini liefert strukturierten JSON-Output zurück (Topic Blueprint, Content-Plan, Cluster-Analyse, Conversion-Strategie). Alle Ergebnisse werden RLS-geschützt und Workspace-isoliert in content_intelligence_content_plans und content_intelligence_validation gespeichert. Keine Endnutzer-Daten (z.B. Website-Besucher, Leads, Customer-Conversations) werden an Gemini übermittelt. | USA (SCCs / Data Privacy Framework) | Link |
| OpenAI Inc. | Embeddings für Hilfe-Center-Suche, KI-gestützte Bild-Generierung (DALL-E 3 / GPT Image 1), Spracheingabe (Whisper-1), Persona-Profilbild-Generierung (GPT Image 1), Asset-Embedding-Generierung für semantische Ähnlichkeitssuche (text-embedding-3-small, PROJ-421), Knowledge Layer (PROJ-500) — Indexierung & Suche: (a) Indexierung von SOPs und Wissensartikeln zur semantischen Suche via text-embedding-3-small (Feature-Key knowledge_embedding); (b) Query-Embedding-Generierung pro Suchanfrage in /api/knowledge/search und im KI-Assistenten-RAG-Pfad (Feature-Key knowledge_search) — die Suchanfrage des Nutzers wird als Plain-Text an OpenAI gesendet, transient verarbeitet, kein Training. Embeddings werden in pgvector-Tabelle knowledge_documents persistiert; Wissensartikel sind technische Produktdokumentation und Prozess-Beschreibungen ohne personenbezogene Daten, SOP Voice-Dictation Speech-to-Text (PROJ-503 — voice_transcribe): Auf User-Trigger im SOP-Editor wird ein Audio-Blob (multipart/form-data, max 25 MB, WebM/M4A/WAV — Mikrofon-Aufnahme des eingeloggten Mitarbeiters) an OpenAI Whisper (whisper-1, language=de) zur Transkription übermittelt. Audio-Daten sind nur transient verarbeitet — keine dauerhafte Speicherung durch OpenAI, kein Training. Audio kann gesprochene betriebsinterne Inhalte enthalten (Mitarbeiter-Diktat über Prozessabläufe). Rohtranskript wird unmittelbar an Claude Haiku zur Stil-Formatierung weitergereicht (siehe Anthropic-Eintrag) und anschließend verworfen — keine Audio- oder Rohtranskript-Persistenz in eigenen Storage-/DB-Systemen. Token-Tracking via logTokenUsage(feature=voice_transcribe, source=sop_voice_dictation), Coding Operations Platform Knowledge-Index (PROJ-510 — coding_ops_knowledge_embedding): Erweitert PROJ-500 Knowledge Layer um zwei neue Quell-Typen (coding_ops_rule, coding_ops_feature). Pro Rule und Feature werden Title + Body bzw. Title + Summary (max. ~3.200 Zeichen pro Chunk, ~800 Tokens) an OpenAI text-embedding-3-small übermittelt um semantische Vektor-Repräsentationen für die Knowledge-Graph-Suche zu erzeugen. Inhalte sind interne technische Dokumentation (Hard-Blocker-Regeln, Empfehlungen, Feature-Spezifikationen) ohne personenbezogene Daten. Embeddings werden in der bestehenden knowledge_documents-Tabelle persistiert, gleicher Worker und gleiche Cleanup-Logik wie SOP-/Help-Article-Indexierung. OpenAI verarbeitet die Daten transient (kein Training auf API-Daten gemäß OpenAI API Data Usage Policy). Token-Tracking via logTokenUsage(feature='knowledge_embedding', source='coding_ops'). Shop-Suche Hybrid-Embeddings (PROJ-767 Stufe 3): Produkttexte (Name + Brand + Category + Description + ausgewählte field_values) werden via text-embedding-3-small in 1536-dim-Vektoren umgewandelt und in products.embedding gespeichert; Endkunden-Queries werden bei aktiviertem Hybrid-Modus zur Live-kNN-Suche embedded (transient, kein Persist bei OpenAI). Batch-Embed-Cron alle 5 Min, Re-Embed nur bei Text-Änderung (SHA-256-Hash). Cost-Tracking in search_llm_calls (Shop-DB). Knowledge-Hydration v2 (PROJ-821 W-0.2): Volltext-Embeddings für brand_assets (alt_text_de/en, semantic_description, PDF-Text max 50.000 Zeichen) und ssot_items (section + data-JSON) via text-embedding-3-small zur semantischen RAG-Suche in KI-Worker-Dispatches. Übermittelt werden: Bildbeschreibungen, SSOT-Inhalte, extrahierte PDF-Texte aus Marken-Dokumenten (ohne automatische PII-Filterung — Admins werden aufgeklärt, nur intern-erstellte Dokumente ohne Personenbezug zu indexieren). Embeddings in knowledge_documents persistiert; keine Persistenz bei OpenAI, kein Training. Keyword-Marketingziel-Zuordnung (PROJ-861 — keyword_goal_ai_mapping): Keyword-Texte und Marketingziel-Texte (Titel + Beschreibung aus ssot_items.section='marketing_goal') werden via text-embedding-3-small in Vektoren umgewandelt, um per Cosine-Similarity das passendste Marketingziel pro Keyword vorzuschlagen. Übermittelt werden ausschließlich Keyword-Begriffe und vom Workspace selbst gepflegte Marketingziel-Beschreibungen — üblicherweise kein Personenbezug. Verarbeitung transient (kein Training, kein Persist der Texte bei OpenAI); nur Score + Best-Match-Ziel-ID werden in keywords.marketing_goal_ai_suggestion_id/marketing_goal_ai_confidence gespeichert. Token-Tracking via logTokenUsage(feature='keyword_goal_ai_mapping'). | Hilfe-Artikeltexte (keine personenbezogenen Daten), KI-generierte Bild-Prompts für Asset-Hintergrundbilder (keine personenbezogenen Daten), Audio-Daten zur Spracherkennung (transient, nicht gespeichert), Persona-Beschreibungsdaten (Alter, Geschlecht, Beruf, Wohnort) als Bild-Prompt — fiktive Persona-Daten, keine echten Personen, KI-generierte semantische Asset-Beschreibungen für Embedding-Berechnung (keine personenbezogenen Daten), PROJ-500 Knowledge-Layer-Inhalte (Titel + gechunkter Klartext-Inhalt von SOPs, Hilfe-Artikeln und Lektionen — generische Wissensinhalte, keine personenbezogenen Daten), PROJ-821 Brand-Asset-Embedding-Inhalte (alt_text, semantic_description, PDF-Texte aus brand_assets — Workspace-eigene Marken-Dokumente, üblicherweise kein PII; Admins tragen Verantwortung für PII-freie Uploads) | USA (DPA) | Link |
| Deepgram Inc. | Meeting-Transkription mit Sprecher-Erkennung (Nova-3 Modell, Speech-to-Text mit Diarization) | Meeting-Aufzeichnungen (Audio) zur automatischen Transkription mit Sprecher-Erkennung — nur nach expliziter Aufnahme-Aktivierung durch den Gastgeber. Audio-Daten werden nur transient verarbeitet (API-Aufruf, keine dauerhafte Speicherung durch Deepgram) | USA (DPA) | Link |
| Cloudinary Ltd. | Bildkonvertierung für die Asset-Master-Pipeline (PROJ-419) — CMYK-Derivate für Druck-Workflows und Format-Transformation für Master-Files ≥ 50 MB. Fallback auf serverseitige Node.js-Verarbeitung (Sharp) wenn Cloudinary nicht konfiguriert ist — keine automatische Weiterleitung an externe Dienste ohne Admin-Konfiguration | Hochgeladene Bilddateien (TIFF, PSD, AI, EPS, PNG, JPG, SVG, PDF) — keine Personen-Metadaten in Dateinamen, Master-Files werden zur Format-Transformation übermittelt und das Ergebnis zurückgegeben. Dauerhafte Speicherung in Cloudinary-Account des Workspace-Betreibers möglich je nach Konfiguration (standardmäßig nur transient für Transformation) | EU-Region wählbar (Cloudinary EU Cloud, SCCs) | Link |
| Kaleido AI GmbH (remove.bg) | Automatische Hintergrund-Entfernung für Markenassets (PROJ-420 Visual Intelligence). Optional konfigurierbar — ohne REMOVE_BG_API_KEY wird Replicate als Fallback genutzt oder die Funktion deaktiviert. | Hochgeladene Rasterbilder (JPEG, PNG, WebP) werden zur Verarbeitung an remove.bg übermittelt, freigestelltes PNG wird zurückgegeben. Transient-Verarbeitung — keine dauerhafte Speicherung durch remove.bg bei API-Nutzung. | Österreich (EU) — Kaleido AI ist in Wien ansässig | Link |
| Replicate Inc. | KI-Modell-Hosting für Asset-Transformationen (PROJ-420 Visual Intelligence): Background Removal (851-labs/background-remover als Fallback zu remove.bg) und KI-Upscaling (nightmareai/real-esrgan für Bilder < 2 MP). Optional konfigurierbar — Button wird bei fehlendem REPLICATE_API_TOKEN disabled. PROJ-606: Bei zu niedriger Auflösung kann der User explizit ein 2x/4x KI-Upscaling anfordern, um die Print-Tauglichkeit eines Markenassets zu erhöhen — keine automatische Triggerung, immer User-Klick + Hinweis-Modal. PROJ-683 Multi-Provider-KI-Bildgenerierung (Phase 2 aktiv): Ergänzung um Replicate als zweiten Provider neben Higgsfield für direkte Text-to-Image-Generierung im KI-Studio. Verwendete Modelle (Baseline): Stable Diffusion XL (stability-ai/sdxl), Flux dev (black-forest-labs/flux-dev), Realistic Vision (lucataco/realistic-vision-v5.1) — Plattform-Admin kann weitere Modelle via Discovery-UI freischalten. Sanitisierter User-Prompt (max 500 Zeichen, vorab durch Wordlist-Filter aus platform_higgsfield_config gefiltert), optionale Referenz-Bild-URLs (signed URLs aus brand_assets Workspace-Storage), Aspect-Ratio, Variants-Count werden an Replicate übermittelt. Output sind ~1h gültige Asset-URLs (replicate.delivery), die sofort in den Workspace-Storage kopiert werden. Face-Lock-Pfad ist auf Higgsfield-Modelle beschränkt — Replicate erhält keine Face-Identity-Marker. PROJ-683 Post-Production-Pipeline (Phase 3, vorbereitet): Bild-Hochskalierung (Real-ESRGAN), Gesichtsrestauration (GFPGAN), Hautdetail-Enhancement (CodeFormer) als optionale Folge-Jobs auf bereits erzeugte Bilder. Hybrid-Polling: Webhook-Receiver `/api/webhooks/replicate` mit HMAC-SHA256-Signaturprüfung (Standard-Webhooks-Spec) für sofortige Job-Completion, pg_cron `replicate-job-poll` (60s-Intervall) als Safety-Net bei Webhook-Drops. API-Token + Webhook-Signing-Secret werden AES-256-GCM-encrypted in platform_replicate_config gespeichert (REPLICATE_ENCRYPTION_KEY). | Hochgeladene Rasterbilder (JPEG, PNG, WebP) werden zur KI-Verarbeitung an Replicate übermittelt. Output-URL wird zurückgegeben, Ergebnis wird heruntergeladen und im eigenen Storage gespeichert. Replicate behält Inputs standardmäßig bis zu 1 Stunde für Caching (konfigurierbar). PROJ-683 zusätzlich: Sanitisierter User-Prompt (max 500 Zeichen, Personen-Namen/NSFW/Markenrechte vorab geblockt), Provider-Modell-ID (z.B. stability-ai/sdxl), Aspect-Ratio (16:9, 1:1, 4:5, 9:16, 4:3, 3:4), Variants-Count (1-4), optionale signed URLs zu bestehenden brand_assets als Inspirations-Referenz. KEINE Übermittlung von Face-Identity-Markern, KEINE biometrischen Embeddings. Generierte Bilder werden mit is_ai_generated=true + ai_generated_by='replicate' als brand_assets gespeichert (EU AI Act Art. 50 Transparenzkennzeichnung). | USA (SCCs + EU-US-DPF Data Privacy Framework — Replicate Inc. ist beim US Department of Commerce zertifiziert) | Link |
| Upstash Inc. | Rate-Limiting via serverless Redis (Sliding-Window-Zähler, automatische Löschung nach 60 Sekunden) | IP-Adresse (als Zähler-Schlüssel, nicht gehasht), Request-Zähler (kurzlebig, TTL 60 Sekunden) | EU (Frankfurt) | Link |
| Fly.io, Inc. | Infrastruktur-Hosting für den Self-Hosted Screenshot-Service (PROJ-393): Fly.io stellt die virtuelle Maschine in Frankfurt (fra-Region) bereit, auf der der hauseigene Screenshot-Service (Playwright + Chromium) läuft. Der Service rendert öffentliche Kundenwebsites in Desktop- (1280×800) und Mobile-Auflösung (375×812) ohne Cookies und ohne Login-Kontext für die Automatisierte Heatmap-Engine (PROJ-389). Fly.io verarbeitet die weitergereichten Request-Metadaten (Request-IP, HTTP-Headers, Screenshot-API-Request-URL) nur als Netzwerk-Transit, nicht persistent. Kein Zugriff auf Anwendungsdaten — der Service speichert keine Screenshots dauerhaft, Screenshots werden unmittelbar an die Supabase Storage zurückgegeben. | Request-Metadaten während Screenshot-Verarbeitung: IP-Adresse des anfragenden NEULAND. OS-Servers (nicht Endnutzer-IP), API-Key als Authorization-Header (server-seitig), öffentliche Seiten-URL der Kundenwebsite. Keine personenbezogenen Daten im Response-Payload (Screenshots von öffentlichen Seiten ohne Login-Kontext). | Fly.io Frankfurt (fra-Region, EU, kein Drittlandtransfer) | Link |
| jsDelivr (Open-Source-CDN, betrieben von Prospect One Sp. z o.o.) | Session Recordings (PROJ-391): snippet.js lädt die rrweb-Recording-Bibliothek (rrweb@2/dist/rrweb.min.js) dynamisch von https://cdn.jsdelivr.net, um DOM-Aufzeichnungen im Browser des Kundenwebsite-Besuchers zu ermöglichen. Der Abruf erfolgt einmalig pro Session nach erster User-Interaktion und nur wenn der Besucher nicht als Bot erkannt wurde. Keine personenbezogenen Daten werden aktiv übermittelt — aber technisch bedingt erhält der CDN die IP-Adresse und den User-Agent beim Abruf. Component Lab (PROJ-409): Zusätzlich werden @babel/standalone (für client-seitige TSX-zu-JavaScript-Transformation) und axe-core (für WCAG-2.1-AA-Prüfung) aus jsDelivr im iFrame-Sandbox geladen. macOS-Companion-App-Telefonie (PROJ-552): Die versteckte WKWebView der nativen macOS-App lädt das Telnyx WebRTC JS-SDK (@telnyx/webrtc@2.26.4/lib/bundle.js) von https://cdn.jsdelivr.net beim ersten Initialisieren des Telefonie-Stacks pro App-Session — der CDN erhält dabei die IP-Adresse und den User-Agent des macOS-Geräts des Mitarbeiters. macOS-Companion-App-Video-Calls (PROJ-553): Analog zu PROJ-552 lädt die sichtbare WKWebView das @daily-co/daily-js-SDK (Version 0.87.0) von https://cdn.jsdelivr.net beim ersten Beitritt zu einem Meeting pro App-Session — gleiche IP+User-Agent-Übermittlung an den CDN. | IP-Adresse des Besuchers (als technisch notwendige Netzwerk-Information des Requests, nicht persistiert durch den Kunden), User-Agent (Browser-Kennung), Referrer (Kundenwebsite-URL). Zurückgeliefert wird ausschließlich die statische rrweb-Bibliothek (JavaScript-Code) — keine personenbezogenen Daten. | Globales CDN (Cloudflare-Netzwerk + weitere Edge-Nodes). Eigentümer Prospect One Sp. z o.o. (Polen, EU). Einzelne Edge-Nodes können weltweit liegen. | Link |
| unpkg (betrieben von Cloudflare, Inc.) | Component Lab (PROJ-409): Die iFrame-Sandbox im Component Lab lädt React und ReactDOM (UMD-Bundles, Version 18) dynamisch von https://unpkg.com, um KI-generierte React-Komponenten im Admin-Browser rendern zu können. Der Abruf erfolgt einmalig pro iFrame-Rebuild. Keine personenbezogenen Daten werden aktiv übermittelt — aber technisch bedingt erhält Cloudflare als CDN-Betreiber die IP-Adresse und den User-Agent des Admins beim Skript-Abruf. | IP-Adresse des Admins (als technisch notwendige Netzwerk-Information des Requests), User-Agent (Browser-Kennung), Referrer (NEULAND. OS Dashboard-URL). Zurückgeliefert werden ausschließlich die statischen React-UMD-Bundles (JavaScript-Code) — keine personenbezogenen Daten. | USA (Cloudflare Global CDN mit EU-Edge-Nodes) | Link |
| SerpAPI LLC | Drei Verwendungszwecke: (1) Web-Recherche-Assistent: Abruf von Google-Suchergebnissen (Titel, Link, Snippet) für die KI-gestützte Unternehmensrecherche. SerpAPI empfängt ausschließlich server-seitig formulierte Suchanfragen (Branche, Region) — keine personenbezogenen Daten von Endnutzern. (2) Deep-Research für Interview-Vorbereitung (PROJ-635 — interview_questionnaire): Vor der KI-Generierung eines Interview-Fragebogens wird das Interview-Topic plus optionaler Branchen-Hint (aus SSOT-Zielgruppen extrahiert) als Suchanfrage an SerpAPI gesendet, um max. 5 themenbezogene Snippets als zusätzlichen Kontext für Claude zu sammeln. Übermittelt werden ausschließlich der Topic-Text und der kategorische Branchen-Hint — keine Kontakt- oder Personendaten. Snippets + Quell-URLs werden Workspace-isoliert in interview_sessions.research_context gespeichert (RLS-geschützt). (3) PROJ-1429 — Künstler-Anreicherung (Bid4it-Custom-Modul, Kunde Nagel Auktionen, opt-in): Für Künstler mit leeren biografischen Feldern wird der Künstlername als Suchanfrage übermittelt, um Beleg-Snippets für die KI-Recherche (Anthropic) zu sammeln. Übermittelt wird ausschließlich der öffentliche Künstlername aus dem bereits publizierten Auktionskatalog — keine Kontaktdaten. Suchergebnisse werden NICHT in der Plattform-DB gespeichert (nur transient für den jeweiligen KI-Call, Ergebnis landet direkt im Google Sheet). | Suchanfragen (Branche z.B. "Maschinenbau", Region z.B. "Bayern", optionale Zusatzkriterien), API-Key (server-seitig, AES-256-GCM verschlüsselt), IP-Adresse des Servers (nicht des Endnutzers). Suchergebnisse (Titel, URL, Snippet) werden zurückgeliefert und in der Datenbank gespeichert (RLS-geschützt, Workspace-isoliert). | USA (SCCs) | Link |
| DataForSEO Ltd. | Elf Verwendungszwecke: (1) Keyword-Datenanreicherung (PROJ-210): Automatisierter Abruf von SEO-Metriken (Suchvolumen, CPC, Keyword-Intent) für Keywords der Marketing-SSOT. (2) SERP-Ranking-Tracking (PROJ-217): Wöchentliche Positionsabfrage der eigenen Domain und bis zu 3 Wettbewerbsdomains für die Keywords des Kontakts — zur Berechnung des projektspezifischen Sichtbarkeitsindex. (3) Domain-Rank-Overview (PROJ-217): Abruf des Gesamt-Domain-Sichtbarkeitsindex via DataForSEO Labs API — organische Sichtbarkeit, geschätzter Traffic, geranktes Keyword-Volumen für eine Domain. (4) Location-Cache-Sync (PROJ-268, erweitert PROJ-1810): Abruf der verfügbaren DataForSEO-Standortcodes (Länder, Regionen, Städte) zur lokalen Zwischenspeicherung — keine Nutzerdaten, nur öffentliche Standort-Metadaten. Seit PROJ-1810 zwei Endpunkte: die Länderliste inkl. Sprachzuordnung weiterhin über dataforseo_labs/locations_and_languages, die feingranulare Ortsliste je Land bedarfsgesteuert über keywords_data/google_ads/locations/{country}. Übermittelt wird ausschließlich der ISO-Ländercode des angefragten Landes. (5) Content Intelligence Phase 02 (PROJ-784, erweitert PROJ-1387): 5 parallele Calls je Analyse-Job: SERP Desktop (serp/google/organic/live/advanced, seit PROJ-1387 mit load_async_ai_overview + expand_ai_overview für Googles AI-Overview-Text), SERP Mobile, OnPage-Instant (on_page/instant_pages) für die Kunden-Website, Search Intent (dataforseo_labs/google/search_intent/live), Keyword-Volume (keywords_data/google/search_volume/live). Übermittelt werden: Target-Keyword (öffentlicher Suchbegriff ohne Personenbezug), Kunden-Website-URL (öffentlich zugängliche Domain), Zielregion + Sprache (z.B. 2276 Deutschland + de). DataForSEO empfängt ausschließlich server-seitig übermittelte Daten — keine personenbezogenen Daten von Endnutzern. (6) Potenzialanalyse (PROJ-995): Im Sales-Modul wird für einen Deal eine digitale Potenzialanalyse erstellt. Dabei werden Keyword-Anreicherung, Ranking-Prüfung, Domain-Sichtbarkeit (DataForSEO Labs), OnPage-Instant für die Kunden-Website sowie SERP-basierte Social-Media-Profilsuche (site:-Queries für die analysierte Domain/Unternehmensbezeichnung) abgerufen. Übermittelt werden: Marketing-Keywords (öffentliche Suchbegriffe ohne Personenbezug), die analysierte Domain (öffentlich zugängliche Unternehmensdomain), Zielregion + Sprache. Keine personenbezogenen Daten von Endnutzern. (7) Bedarfsgruppen-KI-Assistent (PROJ-1027): Domain-Rank-Overview via DataForSEO Labs API für eigene Kunden-Domain und bis zu 20 Wettbewerber-Domains — liefert organische Sichtbarkeit, geschätzten Traffic und geranktes Keyword-Volumen als Input für die KI-Seitenstruktur-Generierung. Übermittelt werden: eigene Domain-URL (öffentlich zugängliche Unternehmensdomain) und bis zu 20 Wettbewerber-Domain-URLs (öffentlich zugängliche Unternehmensdomains, aus SSOT Corporate Identity). Keine personenbezogenen Daten von Endnutzern. (8) HAWEGO Wettbewerbs-Preismonitoring (PROJ-1452 Etappe 1, erweitert PROJ-1465): Google Shopping Merchant API Sellers-Endpunkt als Fallback-Quelle wenn die Merchant-Center-Price-Competitiveness-Daten (siehe Google-Eintrag) keinen belastbaren Treffer liefern — Produkt-Identifikation über GTIN/MPN/Titel, liefert je Wettbewerber-Domain den Gesamtpreis inkl. Versand. Übermittelt werden ausschließlich Produkt-Identifikatoren (GTIN, MPN, Titel — Geschäftsdaten der Artikel, kein Personenbezug); zurückgeliefert werden Wettbewerber-Domain-Namen und Preise (öffentliche Geschäftsdaten). Hartes Tageslimit für Calls konfigurierbar. Manuell (Batch) oder täglich (Cron) ausgelöst. Repricing-Write-back (PROJ-2001, AP4): Der aus diesen Daten berechnete Zielpreis wird — mit harter, mehrfach abgesicherter Mindestpreis-Garantie — über den Plattform-Service-Account in die Spalte `Aimondo-Repricing` desselben Import-Sheets zurückgeschrieben, aus dem PROJ-743 die Lieferanten-Produktdaten liest (siehe dortiger Eintrag zum Service-Account-Schreibzugriff). Geschrieben werden ausschließlich Preis-Zellwerte je SKU, keine personenbezogenen Daten; jeder übersprungene/fehlgeschlagene Schreibversuch wird protokolliert (hawego_repricing_write_events). Seit PROJ-2334 wird dieser Rückschreibpfad nicht mehr nur vom nächtlichen Cron, sondern zusätzlich durch die manuelle Bulk-Preisübernahme im Artikel-Tab ausgelöst (Agentur-Rolle mind. Manager); jede tatsächlich geschriebene Preisänderung wird dabei revert-fähig in hawego_repricing_price_history mit auslösendem Mitarbeitenden protokolliert (siehe eigener Verarbeitungseintrag „HAWEGO Preisübernahme-Historie"). (9) AI-Overview-Zitat-Monitoring (PROJ-1566): Zweistufig automatisierte Prüfung, ob die eigene Domain in Googles AI-Overview-Antwort für ein getracktes Keyword zitiert wird — wöchentlicher Sweep über alle Keywords via SERP-Advanced-Endpunkt (load_async_ai_overview), tägliches Monitoring nur für Keywords mit bereits bestätigtem Treffer. Übermittelt werden: Target-Keyword (öffentlicher Suchbegriff ohne Personenbezug), Zielregion + Sprache. Zurückgeliefert und in ai_overview_citations gespeichert: ob ein AI-Overview erschien und ob die eigene Domain darin zitiert wurde. Keine personenbezogenen Daten von Endnutzern. (10) Ad-hoc-Research beliebiger Domains im Modul SEO / GEO Research (PROJ-1890/PROJ-1891): Auf Anforderung eines Agentur-Mitarbeitenden werden Suchbegriffe und Domains abgefragt, die NICHT an einen Kontakt der eigenen Kundschaft gebunden sind — insbesondere Domains fremder Unternehmen zur Wettbewerbsrecherche vor einem Vertriebstermin. Genutzte Endpunkte: historical_serps und historical_rank_overview (DataForSEO Labs) sowie domain_rank_overview. Uebermittelt werden ausschliesslich Suchbegriff, Domain, Zielregion und Sprache; zurueckgeliefert und in den research_-Tabellen gespeichert werden Positionen, URLs und Suchvolumina. Keine personenbezogenen Daten — weder von Endnutzern noch von Beschaeftigten der recherchierten Unternehmen. Die Rechtsgrundlage ist das berechtigte Interesse an der Marktbeobachtung (Art. 6 Abs. 1 lit. f DSGVO). (11) Echte Suchdaten fuer BIF/TAS-SEO/TAS-GEO im Seitentext-Runner (PROJ-2116, Content-Intelligence-Pipeline aus PROJ-1865): Fuer die vom LLM erzeugten Ziel-Keywords einer geplanten (noch nicht veroeffentlichten) CMS-Seite werden Suchvolumen/CPC/Wettbewerb (keywords_data/google/search_volume/live), Search-Intent (dataforseo_labs/google/search_intent/live) und eine keyword-basierte SERP-Landschaft (serp/google/organic/live/advanced) abgerufen, um bislang konstante Baseline-Werte durch echte Zahlen zu ersetzen. Uebermittelt werden ausschliesslich Keyword-Texte (oeffentliche Suchbegriffe ohne Personenbezug) sowie Zielregion + Sprache des Kontakts (PROJ-218-Zielmarkt) — keine personenbezogenen Daten von Endnutzern, keine eigene Domain/URL (die Seite ist vor Freigabe nicht live, es gibt daher keine SERP-Position/kein On-Page-Crawl der eigenen Seite zu uebermitteln). Ergebnisse werden workspace-weit (nicht personenbezogen) in ci_keyword_search_data zwischengespeichert (30 Tage Cache-Fenster, danach erneuter Abruf) und fliessen in die calculation_basis der ci_seitentext_scores-Zeilen ein. Harter Call-/Kosten-Cap pro Lauf, jeder kostenpflichtige Call wird in api_cost_entries protokolliert. | Keyword-Texte (Marketingbegriffe ohne Personenbezug, z.B. "SEO Agentur München"), Domain-Namen (Unternehmensdomains der Kunden und ihrer Wettbewerber, z.B. "beispiel.de" — keine personenbezogenen Daten), Standort- und Sprachkonfiguration (DataForSEO Location Code z.B. 2276 für Deutschland, Sprachcode z.B. "de" — konfigurierbar pro Zielmarkt des Kontakts, PROJ-218), Suchmaschinen-Auswahl (google/bing pro Zielmarkt), API-Key (server-seitig, AES-256-GCM verschlüsselt), IP-Adresse des Servers (nicht des Endnutzers). Zurückgeliefert und in der Datenbank gespeichert: SEO-Metriken (Suchvolumen, CPC, Wettbewerb, Intent-Klassifizierung), Ranking-Positionen pro Keyword+Domain, Domain-Sichtbarkeitswerte (Sichtbarkeitsindex, organischer Traffic-Schätzwert, geranktes Keyword-Volumen), AI-Overview-Zitat-Status pro Keyword (PROJ-1566), Suchdaten-Cache fuer BIF/TAS-SEO/TAS-GEO im Seitentext-Runner (ci_keyword_search_data, PROJ-2116, workspace-weit). Alle Ergebnisse sind RLS-geschützt und Workspace-isoliert. | Litauen (EU, kein Drittlandtransfer) | Link |
| OpenStreetMap Foundation (OSMF) | Drei Verwendungszwecke: (1) Kartendarstellung (PROJ-268): Leaflet-Karten-Komponente lädt Karten-Tiles (Bilder) vom OpenStreetMap-Tile-Server für die Zielmarkt-Konfiguration. (2) Reverse Geocoding (PROJ-268): Nominatim-API wandelt GPS-Koordinaten in Ortsnamen um (z.B. 48.137, 11.576 → München). (3) Forward Geocoding (PROJ-298): Nominatim-Search-API wandelt Suchbegriffe (Stadt, PLZ, Adresse) in Koordinaten um (z.B. München → 48.137, 11.576) für die Ortssuche in der Zielmarkt-Konfiguration. Wird ausschließlich im eingeloggten Dashboard verwendet, nicht auf öffentlichen Seiten. | Kartenansicht-Koordinaten (Viewport-Zentrum, Zoomstufe — Geschäftsstandorte ohne Personenbezug), GPS-Koordinaten für Reverse Geocoding (Breitengrad, Längengrad — Geschäftsstandorte), Suchbegriffe für Forward Geocoding (Stadt-/PLZ-Namen — Geschäftsstandorte ohne Personenbezug), IP-Adresse des Nutzers (technisch bei jedem HTTP-Request übermittelt). Keine Speicherung durch OSMF über den Request hinaus (Tile-Server sind zustandslos, Nominatim hat keine Nutzerkonten). | Großbritannien / EU (OSMF ist in England registriert, Server in EU/UK, Angemessenheitsbeschluss UK vorhanden) | Link |
| EverReal GmbH | Immobilienangebots-API (Custom-Modul EverReal-Sync): Server-seitiger Abruf von Immobilienangeboten (Titel, Adresse, Preis, Beschreibungen, Bilder-URLs) über die EverReal GraphQL-API zur automatisierten Synchronisierung in ein Google Sheet. PROJ-941: Zusätzlich werden Immobilien-Anfragen von Website-Besuchern als Interessenten-Erstbewerbung an EverReal übermittelt (Outbound, GraphQL-Mutation upsertCandidateInitialApplication) — hierbei werden personenbezogene Kontaktdaten der Anfragenden an EverReal übertragen. | Immobilienangebotsdaten (Objekttitel, Typ, Status, Preisfelder, Adressdaten der Immobilie, Beschreibungstexte, Bild-URLs, Grundriss-URLs, Verfügbarkeitsdatum). OAuth2-Credentials (Client ID, Client Secret) werden AES-256-GCM verschlüsselt in der Datenbank gespeichert. Access- und Refresh-Tokens werden verschlüsselt gespeichert und automatisch rotiert (1h TTL). PROJ-941 (Outbound-Anfragen): Vor- und Nachname, E-Mail-Adresse, Telefonnummer und Freitext-Nachricht von Immobilien-Interessenten, die ein Anfrageformular auf der Kunden-Website ausfüllen, werden zur Anbahnung der Immobilientransaktion an EverReal übermittelt. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (vorvertragliche Maßnahmen auf Anfrage der betroffenen Person). | Deutschland (EU, kein Drittlandtransfer) | Link |
| Stather IT Consulting (Bid4it) | Bid4it Auktions-API (Custom-Modul Bid4it-Sync für Nagel Auktionen, PROJ-930): Server-seitiger Abruf öffentlicher Auktions-Katalogdaten (Auktionen, Lose/Artikel, Kategorien, Künstler) über die öffentliche Bid4it-Guest-API (nagel-live.de/api/v2/guest, kein Auth-Token) zur automatisierten Synchronisierung in ein Google Sheet. Stather hostet zusätzlich die Artikel-Bilder auf static.stather-it-consulting.de — NEULAND. OS speichert davon nur die Bild-URLs, ruft die Bilddaten selbst nicht serverseitig ab. Überwiegend Sachdaten; enthaltene Künstler-Stammdaten siehe DATA_PROCESSING-Eintrag. | Auktions-/Artikel-Sachdaten (Titel, Losnummern, Beschreibungen, Schätzpreise, Status, Bild-URLs, Kategorien) sowie Künstler-Stammdaten (Name, Lebensdaten/Beschreibung) — öffentliche Katalogdaten des Auktionshauses. | Deutschland (EU, kein Drittlandtransfer) | Link |
| Google LLC | OAuth-Login, Drive-Integration, Calendar, Gmail (persönlicher E-Mail-Zugang, inkl. Workspace-interner Freigabe; seit PROJ-1925 zusätzlich Live-Suche: Der vom Nutzer im Inbox-Suchfeld eingegebene Suchbegriff wird ab 3 Zeichen zur Ausführung der Suche an die Gmail API übermittelt, ebenso beim Öffnen eines Treffers die Gmail-Message-ID zum Abruf des Volltexts — beides ausschließlich zur Anzeige im Browser, keine serverseitige Speicherung), YouTube Data API v3 (Video-Upload, Shorts, geplante Veröffentlichung, Kommentar-Management und -Moderation), Google Business Profile API (Bewertungsmanagement, Local Posts, Standortverwaltung), Google Tag Manager (Webanalyse-Infrastruktur), Google PageSpeed Insights API (Analyse von Kunden-Website-URLs auf Performance — keine personenbezogenen Daten, ausschließlich öffentlich erreichbare URLs), Google Sheets API v4 (automatisierte Immobiliendaten-Synchronisierung aus Drittquellen in Kunden-Google-Sheets via Service Account — keine personenbezogenen Daten, ausschließlich Immobilien-Sachdaten; Auslösung manuell oder, seit PROJ-1941, nach einem je Verbindung einstellbaren Zeitplan (aus, stündlich, täglich oder wöchentlich zu fester Uhrzeit im Halbstunden-Raster, Berliner Zeit) über einen alle 15 Minuten prüfenden Cron), Google Ads API (Enhanced Conversions for Leads: serverseitiger Upload von gclid-basierten Offline-Conversions mit SHA-256-gehashten Nutzerdaten zur Conversion-Attribution; Kampagnen-Performance-Reports via GAQL: Import von Spend-, Klick- und Conversion-Daten aus verbundenen Ads-Konten — Auslösung manuell oder, seit PROJ-1919, nach einem je Workspace einstellbaren Zeitplan (aus, stündlich, täglich oder wöchentlich zu fester Uhrzeit im Halbstunden-Raster, Berliner Zeit) über einen alle 15 Minuten prüfenden Cron; CampaignBudgetSimulation-Daten für KI-Budget-Prognosen; KeywordPlanIdeaService.GenerateKeywordIdeas via gRPC: Abfrage regionaler Suchvolumen (Bundesland, Stadt, PLZ) für Marketing-Keywords der Kunden — übermittelt werden ausschließlich Keyword-Texte ohne Personenbezug und Geo-Target-Criteria-IDs aus DataForSEO-Standortcache; zurückgeliefert werden aggregierte Suchvolumen, Wettbewerbsklassifikation und CPC-Schätzwerte — keine Endnutzerdaten, ausschließlich Kampagnen-Metadaten; Änderungshistorie verbundener Werbekonten via GAQL-Ressource `change_event` (PROJ-1876; läuft im Werbekonten-Import mit und folgt seit PROJ-1919 dessen je Workspace einstellbarem Zeitplan — aus, stündlich, täglich oder wöchentlich zu fester Uhrzeit im Halbstunden-Raster, Berliner Zeit, über einen alle 15 Minuten prüfenden Cron): Abgefragt werden Zeitfenster, Werbekonto-Kennung und Gegenstands-Filter — zurückgeliefert werden neben den Änderungsdaten AUCH DIE KLARTEXT-E-MAIL-ADRESSE der Person, die die Änderung vorgenommen hat (`change_event.user_email`). Diese Adresse wird ausschließlich zur Ableitung einer groben Einordnung — Agentur oder Kunde — verwendet und danach verworfen; sie wird in NEULAND. OS nicht gespeichert und nicht protokolliert. Google ist hier Quelle des Personenbezugs, nicht Empfänger: In Richtung Google fließen bei dieser Abfrage keine personenbezogenen Daten), Google Search Console API v1 (Import von aggregierten Keyword-Ranking-Daten — Klicks, Impressionen, durchschnittliche Position pro Keyword und URL — für verknüpfte Kunden-Domains via OAuth 2.0 Read-only-Scope; Auslösung manuell oder, seit PROJ-1919, nach einem je Workspace einstellbaren Zeitplan (aus, stündlich, täglich oder wöchentlich zu fester Uhrzeit im Halbstunden-Raster, Berliner Zeit) über einen alle 15 Minuten prüfenden Cron. Keine Endnutzer-Identifikatoren in der GSC-Response, ausschließlich aggregierte Such-Metriken — PROJ-417), Google Favicon-Service (öffentliche URL `https://www.google.com/s2/favicons?domain=X&sz=64` zur Darstellung von Kunden-Favicons im Agency-View-Portfolio-Grid und Quick-View-Sheet des Website-Tracking-Dashboards — PROJ-441. Der Request kommt ausschließlich aus dem Browser des eingeloggten Agentur-Admins, nicht vom Tracking-Snippet auf Kunden-Websites. Google erhält nur den Domain-Namen der Kunden-Website als Query-Parameter; keine personenbezogenen Daten des Agentur-Admins oder der Endnutzer werden übermittelt. Falls der Favicon-Service unerreichbar ist oder eine Domain kein Favicon hat, fällt die UI auf einen farbigen Initialbuchstaben-Avatar zurück), Google Fonts API (Visual Style Inventory, PROJ-406): browser-seitiger Abruf von Webfont-Dateien über `https://fonts.googleapis.com/css2?family=X` für Schriften, die im SSOT-CI-Tab mit der Plattform-Angabe `Google Fonts` hinterlegt sind. Wird ausschließlich in der auth-gescoped Embed-Route (`/style-inventory-embed/:contactId`) geladen, d.h. nur bei eingeloggten Agentur-Nutzern mit erteiltem Cookie-Consent. Auf der öffentlichen, Consent-freien Share-Link-Seite (`/style-inventory/[token]`) wird der `@import`-Aufruf aktiv unterdrückt — der Browser nutzt den `system-ui`-Fallback. Google erhält beim Abruf die IP-Adresse + User-Agent des Browsers und den Schriftnamen; keine weiteren personenbezogenen Daten. CMS-Seiten (PROJ-1204, Schriften selbst hosten): Für im CMS verwendete Google-Schriften werden die WOFF2-Dateien einmalig server-seitig beim Setup heruntergeladen (Server-IP von NEULAND. OS kontaktiert Google, NICHT die Besucher-IP) und anschließend aus EU-Storage (Supabase Storage, Frankfurt, Bucket cms-fonts) via @font-face ausgeliefert. Auf öffentlichen CMS-Seiten findet damit KEIN Browser-Kontakt der Website-Besucher zu Google-Servern mehr statt; der bisherige @import-Aufruf an fonts.googleapis.com entfällt, sobald der Download durchgelaufen ist (bis dahin greift übergangsweise der bestehende, Consent-gesteuerte @import-Fallback). Google Fonts Developer API (PROJ-519, server-side mit API-Key): Liste aller verfügbaren Google Fonts (Family-Name, Kategorie, Variants, Subsets) wird im SSOT-CI-Tab über einen server-side Proxy abgerufen, NICHT direkt aus dem Browser. Antworten 24h in Upstash Redis gecacht. TTF-Datei-Downloads für ZIP-Pakete streamen direkt aus dem öffentlichen Google-CDN fonts.gstatic.com (kein Auth, kein API-Key in der Download-URL). Übermittelt werden ausschließlich generische Server-Requests + serverseitiger API-Key — keine User-IPs oder personenbezogenen Daten. Google Ads GoogleAdsService.search (PROJ-569): Discovery aller Ads-Customer-Konten unter dem Google MCC der Agentur via GAQL-Query (`FROM customer_client WHERE customer_client.level <= 1 AND customer_client.manager = FALSE`) zur Befüllung des Werbekonten-Pickers im CRM-Kontakt-Tab. Liefert ID, Anzeigename, Währung, Zeitzone und Manager-Status je Child-Konto. Keine neuen Tokens — Wiederverwendung der bestehenden MCC-OAuth-Verbindung (PROJ-367). Geschäftsdaten der Account-Inhaber, kein End-User-Personenbezug. Google Ads API v24 `/campaignBudgets:mutate` + `/campaigns:mutate` Campaign-Create (PROJ-790, Version-Upgrade auf v24 via PROJ-883): 2-Step-Push für Paid-Campaign-Konfigurator. Erst Campaign-Budget anlegen (Name, AmountMicros, DeliveryMethod, Period), dann Campaign mit Budget-Reference (AdvertisingChannelType, Status=PAUSED, BiddingStrategyType). Atomic-Rollback bei Campaign-Fehler löscht das erstellte Budget. Header: `Authorization: Bearer` + `developer-token` (Env) + `login-customer-id` (Manager-Account). Wiederverwendung der OAuth-Verbindung aus PROJ-367. Geschäftsdaten der Account-Inhaber, kein End-User-Personenbezug. Sales CRM E-Mail Inbox-Sync (PROJ-578): Gmail API v1 (gmail.readonly + gmail.send Scopes) — automatischer Sync neu eingehender und ausgehender Vertriebs-E-Mails alle 5 Minuten; Match-Logik (Sender → CRM-Kontakt → aktiver Deal) läuft serverseitig in NEULAND. OS, KEINE LLM-Übermittlung. Reply-Funktion sendet via gmail.send mit dem OAuth-Token des Postfach-Inhabers (Send-on-Behalf). Wiederverwendung der bestehenden Google-OAuth-Verbindung (PROJ-28). E-Mail-Composer (PROJ-686): Direkt-Versand neuer E-Mails, Antworten (reply) und Weiterleitungen (forward) aus dem Deal-Kommunikations-Tab via gmail.send. Übermittelt werden Betreff, HTML-Body (inkl. optionaler User-/Workspace-Signatur), Empfänger-Adressen (To/CC/BCC), optionale Anhänge aus Storage-Bucket sales-email-attachments und Threading-Header (In-Reply-To/References). Versand-Datenstrom läuft ausschließlich serverseitig. Kein LLM-Einsatz; Variablen-Interpolation aus Vorlagen ({{contact.first_name}} etc.) rein serverseitig. Einheitliche E-Mail-Signaturen (PROJ-1127): Beide Composer (Vertrieb und Postfach) fügen die Signatur nicht mehr aus festen Profil-/Workspace-Feldern, sondern aus zentral verwalteten Signatur-Vorlagen ein (Tabelle email_signature_templates, workspace-scoped, RLS, nur Admin/Manager pflegbar). Platzhalter (Vorname, Nachname, Name, Position, Telefon, E-Mail, Abteilung) werden serverseitig mit den Profildaten des sendenden Nutzers aus profiles und workspace_members gefüllt; das fertige HTML wird serverseitig sanitisiert. Automatischer Abwesenheitshinweis (PROJ-1127 Phase 2): Liegt für den sendenden Nutzer ein genehmigter Urlaub (leave_requests, type=urlaub) im konfigurierbaren Vorlauffenster (workspaces.signature_absence_lead_days, Standard 7 Tage), wird ein Abwesenheitstext mit Zeitraum und — falls hinterlegt — dem Namen der Vertretung automatisch in die Signatur eingefügt und damit an externe E-Mail-Empfänger ausgegeben. Es wird ausschließlich der serverseitig gerenderte Hinweistext übermittelt; rohe Urlaubsdatensätze verlassen den Server nicht zum Client. Workation erzeugt keinen Hinweis. Rechtsgrundlage Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Erreichbarkeits-Transparenz gegenüber Geschäftskontakten); pro Workspace per Schalter signature_absence_enabled deaktivierbar. HAWEGO Lieferanten-Produktdaten-Import (PROJ-743): Lese-Zugriff (drive.readonly + spreadsheets.readonly) auf einen vom Workspace-Admin konfigurierten Drive-Folder, in dem ~49 Hersteller-spezifische Importlisten (`*-importvorlage-shopware.xlsx` als Google Sheets) liegen. Drive API v3 (`files.list`, `files.get`) listet/prüft Files + `modifiedTime` für Skip-Sync-bei-keine-Änderung. Sheets API v4 (`spreadsheets.get` + `values.batchGet`) liest 7 Pflicht-Tabs pro Sheet (Stammdaten, Eigenschaften, Attribute, Kategorien, Preis, Lager und Versand, Bilder) + Generator-Tab (Property-Set-Definitionen). Übermittelt werden ausschließlich serverseitige API-Aufrufe mit dem User-OAuth-Token (Wiederverwendung der bestehenden OAuth-Verbindung aus PROJ-28). Dieser persönliche User-OAuth-Zugang bleibt unverändert read-only — Google erhält darüber keine Datenströme aus NEULAND. OS in Gegenrichtung. Inhalte der Sheets sind Lieferanten-Produktstammdaten (Artikelnummern, EANs, Preise, Eigenschaften); enthalten optional Lieferanten-Kontakt-E-Mails als Geschäftsdaten (Art. 6 Abs. 1 lit. f). Repricing-Write-back (PROJ-2001, AP4): Auf denselben Dateien schreibt zusätzlich — unabhängig vom User-OAuth-Zugang — der bereits seit PROJ-1180 produktiv genutzte Plattform-Service-Account (siehe GMC-Titeloptimierung-Eintrag) auf dem Tab „Preis“ den Zielpreis in die Spalte `Aimondo-Repricing` zurück; geschrieben werden ausschließlich Preis-Zellwerte, keine personenbezogenen Daten. Dieser Schreibpfad besteht unabhängig vom (weiterhin read-only) User-OAuth-Sync. Seit PROJ-2334 wird er nicht mehr nur vom nächtlichen Cron, sondern auch durch die manuelle Bulk-Preisübernahme im Artikel-Tab ausgelöst (Rolle mind. Manager); jede Übernahme wird revert-fähig in hawego_repricing_price_history mit auslösendem Mitarbeitenden protokolliert (siehe Verarbeitungseintrag „HAWEGO Preisübernahme-Historie"). Google Sheets API v4 für Kundentabellen-Synchronisation (PROJ-1005): Lese- und Schreibzugriff (Scope spreadsheets) auf eine vom internen NEULAND-Team pro Kunden-Workspace konfigurierte Google-Sheets-URL. Tabellenblätter werden gelesen (spreadsheets.get + values.get), markierte Zeilen 1:1 (inkl. enthaltenem HTML) in interne Haupttabellenblätter zurückgeschrieben (values.batchUpdate). Ist der Löschabgleich für ein Mapping eingeschaltet (PROJ-1928, Standard aus, Einschalten nur durch Admin/Manager), entfernt der Sync zusätzlich ganze Zeilen im internen Haupttabellenblatt physisch (spreadsheets:batchUpdate mit deleteDimension), deren Abgleichswert im Kunden-Tabellenblatt nicht mehr vorkommt. Das Kunden-Tabellenblatt selbst wird dabei nicht verändert. Übermittelt werden ausschließlich serverseitige API-Aufrufe mit dem User-OAuth-Token (Wiederverwendung der OAuth-Verbindung aus PROJ-28). Inhalte sind Kunden-Tabellendaten (Produkt-/Stammdaten) ohne gesonderten Personenbezug; keine dauerhafte Speicherung der Rohdaten in NEULAND. OS — gespeichert werden die Mapping-Konfiguration sowie, ausschließlich bei aktivem Löschabgleich, der Inhalt der jeweils gelöschten Zeilen (google_sheets_sync_deleted_rows, 90 Tage, siehe eigener Eintrag). Google-Drive-Dateiinhalt-Lesen für SSOT-Befüllung (PROJ-1378): Zusätzlich zum bisherigen Ordner-/Datei-Listing (drive.readonly) wird jetzt für ausgewählte Dateien in einem vom Kontakt-Ordner referenzierten Drive-Verzeichnis auch der Dateiinhalt gelesen (files.export für Google Docs als Text, files.get?alt=media für PDF/Bild-Rohbytes). Der gelesene Inhalt wird serverseitig an Anthropic zur SSOT-Extraktion weitergereicht (siehe Anthropic-PBC-Eintrag, PROJ-1378) — kein weiterer Drittanbieter. GMC-Titeloptimierung Performance-Priorisierung (PROJ-1318 Strang 2): serverseitiger Zugriff auf die Google Merchant Center Reports API (merchantapi.googleapis.com/reports/v1) via Service-Account (Wiederverwendung des bestehenden GOOGLE_SERVICE_ACCOUNT_KEY, Scope content) zum Abruf von Klick-/Impressions-Kennzahlen je Produkt (60-Tage-Fenster, MCQL-Abfrage gegen product_performance_view und product_view) für das hawego-Merchant-Center-Konto; seit PROJ-1460 zusätzlich fetchProductPerformanceWindow() für ein freigabedatum-bezogenes Vorher-/Nachher-Zeitfenster (28 bzw. 42 Tage ab Montag der Freigabewoche) — Zweck: Wirkungsmessung je freigegebenem Titel statt laufendem Scoring, dieselbe API/derselbe Service-Account, ausschließlich aggregierte Klick-/Impressions-/CTR-Kennzahlen ohne Personenbezug. Übermittelt werden ausschließlich die Merchant-Center-Account-ID und die Abfrage-Parameter (Datumsbereich); zurückgeliefert werden aggregierte Produkt-Performance-Kennzahlen (SKU, Klicks, Impressionen, Eligibility-Status) — reine Produktdaten ohne Personenbezug, gespeichert in hawego_title_optimization_scores. Manuell ausgelöst (kein Echtzeit-Polling). HAWEGO Wettbewerbs-Preismonitoring (PROJ-1452 Etappe 1, erweitert PROJ-1465): serverseitiger Zugriff auf die Google Merchant Center Price Competitiveness Reports API für dasselbe hawego-Merchant-Center-Konto — liefert je Produkt einen aggregierten Benchmark-Preis (GTIN-Match über alle gelisteten Anbieter) sowie optional eine KI-Sale-Price-Suggestion als Zielpreis-Kandidat. Zusätzlich (PROJ-1465) Wiederverwendung derselben Klick-/Impressions-Kennzahlen (product_performance_view) zur Berechnung eines Priority-Scores (Preisabweichung × Relevanz), gespeichert in hawego_price_monitoring_scores. Übermittelt werden ausschließlich die Merchant-Center-Account-ID und Abfrage-Parameter; zurückgeliefert werden aggregierte Produkt-Preis-/Performance-Kennzahlen ohne Personenbezug. Manuell (Batch) oder täglich (Cron) ausgelöst. Google Sheets Datenimport für IAAI Extranet (PROJ-1712): Service-Account-Schreibzugriff (spreadsheets-Scope, Wiederverwendung des bestehenden GOOGLE_SERVICE_ACCOUNT_KEY aus PROJ-1012) zum Zurückschreiben serverseitig extern abgerufener Quelldaten in ein vom Kunden für den Service-Account freigegebenes Google Sheet. Zwei Quellentypen sind möglich, beide mit admin-konfigurierter Quell-URL: (1) CSV-Dateien (z.B. IAAI-Extranet); (2) Contao-Dateiverwaltung (PROJ-1834, erweitert durch PROJ-1839) — abgerufen wird die `_tools/file-info`-Schnittstelle der Contao-Instanz des Kunden selbst, also keine weitere Auftragsverarbeiter-Beziehung von NEULAND. OS. Geschrieben wird je Eintrag ausschließlich das Wertepaar Pfad + Contao-UUID. **Dateiinhalte werden in keinem Fall übernommen.** Der Umfang ist pro Quelle einstellbar und hat zwei Betriebsarten: (2a) **Ausschnitt** — ist ein Basis-Pfad hinterlegt, werden nur die Ordner genau eine Ebene darunter übernommen, keine Dateien (Verhalten aus PROJ-1834). (2b) **Vollständig** — bleibt der Basis-Pfad leer, wird die komplette Dateiverwaltung übernommen: alle Ordner UND alle Dateien, in jeder Ebene, jeweils mit ihrem Pfad. In der real gemessenen Kundeninstanz sind das rund 131.000 Einträge, davon etwa 99 Prozent Dateipfade (Stand 30.07.2026). Sowohl Ordner- als auch **Dateinamen** können Personennamen oder andere personenbezogene Angaben enthalten, wenn der Kunde seine Ablage so benennt (z.B. `files/kunden/mueller` oder `files/gutachten/Gutachten_Mueller_2024.pdf`) — bei Dateinamen ist das erfahrungsgemäß häufiger der Fall als bei Ordnernamen. Diese Werte stammen ausschließlich aus der Ablagestruktur des Kunden, werden nicht in NEULAND. OS gespeichert und gelangen nur in das Google Sheet des Kunden selbst. Die Wahl der Betriebsart trifft der Kunde bzw. das betreuende Team bei der Einrichtung der Quelle; wer den Umfang begrenzen möchte, hinterlegt einen Basis-Pfad. Übermittelt werden ausschließlich serverseitige API-Aufrufe (Service-Account-Auth), keine Übermittlung aus NEULAND. OS in Gegenrichtung an Google außer den zu schreibenden Zellwerten. Keine dauerhafte Speicherung der abgerufenen Inhalte in NEULAND. OS — Verarbeitung ausschließlich im Arbeitsspeicher während des Laufs; im Lauf-Protokoll bleiben nur technische Metadaten (Quellen-ID, Ziel-Tab, Status, Versuchszähler, Fehlertext). Auslösung manuell oder — seit PROJ-1819 — nach einem pro Verbindung einstellbaren Zeitplan (stündlich oder täglich zu fester Uhrzeit) über einen alle 15 Minuten prüfenden Cron. Google Sheets API v4 Ausgabe von Contao-Formularanfragen (PROJ-2168, AP4): Service-Account-Schreibzugriff (spreadsheets-Scope, Wiederverwendung des bestehenden GOOGLE_SERVICE_ACCOUNT_KEY) zum Anhängen eingegangener Website-Formularanfragen aus der Contao-Datenquelle (contao_form_submissions) als neue Zeilen in ein vom Kunden für den Service-Account freigegebenes Google Sheet — ersetzt den bisherigen Zapier-Schreibschritt. ANDERS als die vorstehenden Sheets-Flows werden hier personenbezogene Daten übermittelt: pro Kunde über ein Feld-zu-Spalten-Mapping konfigurierbar ausschließlich die dort gewählten Felder der Anfrage — typischerweise Name, E-Mail-Adresse, Telefonnummer und freie Formularfelder des Website-Besuchers (Datenminimierung, nur gemappte Felder). Auftragsverarbeitung im Kundenauftrag; pro Ausgabe-Ziel per Schalter aktivierbar, danach alle 5 Minuten per Cron, Export jeder Anfrage genau einmal je Ziel. Keine zusätzliche dauerhafte Speicherung der Anfrage-Inhalte über contao_form_submissions hinaus; gespeichert werden nur die Ausgabe-Ziel-Konfiguration, Export-Markierungen (Submission-/Ziel-Referenz) und Lauf-Protokolle ohne Personenbezug. Google Sheets API v4 Einlese-Backfill von Contao-Formularanfragen (PROJ-2169, AP5, Gegenrichtung zu AP4): Service-Account-Lesezugriff (spreadsheets-Scope, Wiederverwendung des bestehenden GOOGLE_SERVICE_ACCOUNT_KEY) zum einmaligen Einlesen des historischen Anfrage-Bestands aus einem vom Kunden freigegebenen Google Sheet in die Contao-Datenquelle. Default-Quelle ist das konfigurierte AP4-Ausgabe-Ziel desselben Sheets; eine abweichende Quelle erfordert explizite Admin-Bestätigung und wird mit auslösendem Nutzer und exakter Spreadsheet-ID protokolliert (contao_sheet_backfill_runs), weil der agenturweite Service-Account grundsätzlich Lesezugriff auf viele Kunden-Sheets hat. Übertragen werden ausschließlich die per Mapping ausgewählten Spalten (Datenminimierung); die eingelesenen Zeilen werden über dieselbe Dedup-/Anreicherungslogik wie Webhook-/E-Mail-Anfragen in contao_form_submissions gespeichert — keine neue dauerhafte Speicherung über diese Tabelle hinaus, außer dem Lauf-Protokoll selbst (Snapshot der Konfiguration, Zeilenzähler, kein Rohwert der Anfragen). Google Ads API `AdService`/`CampaignService`/`AdGroupService.update()` (PROJ-2319): Setzt `final_url_suffix=nl_tid=<wert>` auf Kampagnen-/Anzeigengruppen-/Anzeigen-Ebene zur internen Kampagnen-Attribution — erster Schreibzugriff der Plattform auf ein lebendes Kunden-Google-Ads-Konto. Merge-statt-Überschreiben-Pflicht schützt bestehende Kundenparameter im final_url_suffix. Nur durch expliziten, authentifizierten Admin-Trigger je Verbindung (kein Cron, kein Auto-Rollout). Keine Endnutzer-Personendaten, ausschließlich Kampagnen-/Anzeigen-Metadaten. | E-Mail-Adresse, Name, Drive-Dateien, Drive-Datei-Metadaten (Name, URL, Typ), Kalender-Einträge, Gmail-Nachrichten-Metadaten und Nachrichtentext (Betreff, Absender, Empfänger, Textvorschau sowie seit PROJ-1772 der Textinhalt der E-Mail — body_text, gekürzt auf maximal 20.000 Zeichen — als Cache in der Datenbank gespeichert, maximal 1.000 Einträge pro Google-Konto; bei Überschreitung werden die ältesten Einträge automatisch gelöscht. Der Textinhalt wird zusätzlich in einen Suchindex (search_vector) übernommen, damit die Volltextsuche der Inbox Betreff und Nachrichtentext durchsuchen kann. Anhänge werden NICHT serverseitig gespeichert — sie werden bei Bedarf live über die Gmail API abgerufen), YouTube-Daten (Video-Titel, Beschreibung, Tags, Thumbnails, Kommentare inkl. Autorenname und Text), Google Business Profile-Daten (Bewertungen inkl. Sternebewertung 1–5, Autorenname, Bewertungstext, Antworten; Standortdaten wie Adresse, Telefon, Website), Online-Kennungen (Cookies, IP-Adresse nach Consent); Google Ads Änderungshistorie (PROJ-1876, Rückrichtung Google → NEULAND. OS): E-Mail-Adresse der Person, die eine Änderung im Werbekonto vorgenommen hat — transient, nur zur Einordnung Agentur/Kunde, keine Speicherung | USA (SCCs / Data Privacy Framework) | Link |
| Microsoft Corporation | OAuth-Login via Azure AD; Bing Webmaster Tools API (Import von aggregierten Keyword-Ranking-Daten — Klicks, Impressionen, Position pro Keyword und URL — für verknüpfte Kunden-Domains; Auslösung manuell oder, seit PROJ-1919, nach einem je Workspace einstellbaren Zeitplan (aus, stündlich, täglich oder wöchentlich zu fester Uhrzeit im Halbstunden-Raster, Berliner Zeit) über einen alle 15 Minuten prüfenden Cron. Keine personenbezogenen Endutzerdaten, ausschließlich aggregierte Such-Metriken). Microsoft Ads / Bing Ads API V13 Customer Management Service (PROJ-569): OAuth 2.0 zum Microsoft Agency Account; Discovery aller Ads-Customer-Konten unter dem Agentur-Account (CustomerManagementService.GetCustomersInfo / GetAccountsInfo) zur Befüllung des Werbekonten-Pickers im CRM-Kontakt-Tab. Keine Endnutzer-PII; ausschließlich Geschäftsdaten der Agentur-Kunden (Account-IDs, Account-Namen, Währung). Microsoft Advertising (Bing Ads) Campaign Management REST API v13 (PROJ-883, FR-10): POST /Campaigns mit OAuth 2.0 Bearer Token + DeveloperToken-Header + CustomerId-Header + CustomerAccountId-Header. Überträgt Kampagnenstruktur (Name, BudgetType=DailyBudgetStandard, DailyBudget in EUR, Status=Paused, CampaignType entsprechend Kampagnenziel, TimeZone=EuropeBerlin) an Microsoft Advertising zur werblichen Auslieferung im Status PAUSED. Token-Refresh bei 401 via OAuth 2.0 Refresh Token. Audit-Log in paid_campaign_pushes mit redacted Tokens (kein Access Token, kein DeveloperToken im Log). Keine End-User-PII — ausschließlich Kampagnen-Konfigurationsdaten (Geschäftsdaten der Werbekonto-Inhaber). Vorherige PROJ-790-Implementierung war ein Stub ohne echte API-Übertragung; ab PROJ-883 aktiv. Microsoft Advertising Reporting Service v13 (PROJ-1612): asynchroner SOAP-Report-Abruf (SubmitGenerateReport → Poll → ZIP-CSV-Download) für tagesgenaue Kampagnen-Performance-Kennzahlen (Spend, Impressionen, Klicks, Conversions) verbundener Werbekonten — On-Demand-Nachladen oder, seit PROJ-1919, nach einem je Workspace einstellbaren Zeitplan (aus, stündlich, täglich oder wöchentlich zu fester Uhrzeit im Halbstunden-Raster, Berliner Zeit) über einen alle 15 Minuten prüfenden Cron. Übermittelt werden ausschließlich Werbekonto-ID + Datumsbereich; zurückgeliefert werden aggregierte Kampagnen-Kennzahlen ohne Endnutzer-Personenbezug, gespeichert in campaign_snapshots. Microsoft Advertising Reporting Service v13 — Änderungshistorie verbundener Werbekonten via Bericht `SearchCampaignChangeHistoryReportRequest` (PROJ-1894; läuft im Werbekonten-Import mit und folgt seit PROJ-1919 dessen je Workspace einstellbarem Zeitplan — aus, stündlich, täglich oder wöchentlich zu fester Uhrzeit im Halbstunden-Raster, Berliner Zeit, über einen alle 15 Minuten prüfenden Cron; derselbe asynchrone SOAP-Weg): Abgefragt werden Zeitfenster, Werbekonto-Kennung und ein serverseitiger Objektart-Filter (`ItemChanged = Campaign AdGroup Ad Keyword`, schließt die Objektarten `User` und `Account` — E-Mail/Name bzw. Zahlungsdaten — bewusst aus, bevor sie überhaupt geliefert werden) — zurückgeliefert werden neben den Änderungsdaten AUCH DIE KLARTEXT-ADRESSE der Person, die die Änderung vorgenommen hat (`ChangedBy`, bei Systemänderungen der Wert `Administrator`). Diese Adresse wird ausschließlich zur Ableitung einer groben Einordnung — Agentur oder Kunde — verwendet (derselbe Baustein wie beim Google-Ads-Pendant, PROJ-1876) und danach verworfen; sie wird in NEULAND. OS nicht gespeichert und nicht protokolliert. Microsoft ist hier Quelle des Personenbezugs, nicht Empfänger: In Richtung Microsoft fließen bei dieser Abfrage keine personenbezogenen Daten. Microsoft Advertising Campaign Management Service v13 — Anzeigen-Assets (PROJ-2241): synchroner SOAP-Abruf CampaignManagementService.GetAdsByAdGroupId mit OAuth 2.0 Bearer Token + DeveloperToken- + CustomerId- + CustomerAccountId-Header. Übermittelt werden ausschließlich Werbekonto-Kennung + AdGroup-IDs; zurückgeliefert werden RSA-Anzeigenbausteine (Überschriften-/Beschreibungstexte, Pin-Position, Asset-Performance-Label, finale Ziel-URL), gespeichert in ad_creatives. Keine Endnutzer-PII — ausschließlich werbliche Anzeigeninhalte der Werbekonto-Inhaber. | E-Mail-Adresse, Name; Bing-Webmaster-Daten: Keyword-Text, URL-Pfad, aggregierte Klick-/Impressionszahlen, durchschnittliche Position (keine Endnutzer-PII). PROJ-569 Microsoft Ads: Agency-Account-OAuth-Tokens (AES-256-GCM verschlüsselt mit MICROSOFT_OAUTH_ENCRYPTION_KEY), Customer-Account-IDs, Account-Namen, Währung. Geschäftsdaten der Account-Inhaber, kein End-User-Personenbezug. Microsoft Ads Änderungshistorie (PROJ-1894, Rückrichtung Microsoft → NEULAND. OS): E-Mail-Adresse der Person, die eine Änderung im Werbekonto vorgenommen hat — transient, nur zur Einordnung Agentur/Kunde, keine Speicherung. | EU/USA (DPA) | Link |
| finAPI GmbH | PSD2 Open-Banking-Kontoanbindung: AIS (Account Information Service) für Kontoumsatzabruf und Zahlungsabgleich; PIS (Payment Initiation Service) für SEPA-Überweisungen und SEPA-Lastschriften. finAPI ist BaFin-lizensierter Kontoinformationsdienstleister (KID) und Zahlungsauslösedienstleister (ZAD) gem. §§33, 34 ZAG. | Pseudonymisierte Workspace-User-ID, Bankverbindungsdaten (IBAN, Kontoname, Kontotyp, Salden), Kontoumsätze (Buchungsdatum, Betrag, Verwendungszweck, Gegenseite Name/IBAN/BIC), Zahlungsauslösung (Empfänger-IBAN, Betrag, Verwendungszweck, Ausführungsdatum). Bank-Zugangsdaten werden ausschließlich im finAPI PSD2 Web Form verarbeitet und nie an NEULAND. OS übermittelt. | EU (München, Deutschland) | Link |
| Telnyx LLC | Browser-Telefonie und macOS-Companion-App-Telefonie (PROJ-552: WebRTC läuft in einer versteckten WKWebView innerhalb der nativen macOS-App, identische SIP-Registrierung wie im Browser-Kontext, gleicher Token-Mechanismus), SIP-Trunking, Webhook-Events für Anrufdokumentation | Rufnummern (Anrufer/Angerufener), Anrufrichtung, Anrufdauer, SIP-Signalisierungsdaten, WebRTC-Token (kurzlebig, 15 Minuten — sowohl im Browser als auch in der macOS-App). Bei Multi-Device-Nutzung (Browser + macOS-App parallel angemeldet) registriert Telnyx mehrere SIP-Endpoints derselben Telephony-Credentials und nutzt First-Answer-Wins, sodass der erste annehmende Endpoint das Klingeln auf den anderen serverseitig beendet. | USA (EU-Processing verfügbar, SCCs) | Link |
| Retell AI Inc. | Echtzeit-Sprachverarbeitung für den KI-Telefonassistenten: Speech-to-Text (Transkription eingehender Anrufe), LLM-Orchestrierung (Gesprächsführung via Claude Haiku), Text-to-Speech-Routing (an ElevenLabs). Retell AI empfängt Audio-Streams via SIP-Trunk von Telnyx und gibt synthetisierte Sprachantworten zurück. | Audio-Streams (ephemer, nur während des Anrufs verarbeitet), Transkripte (an NEULAND. OS zurückgeliefert und in call_logs gespeichert, Aufbewahrung max. 12 Monate), Gesprächskontext (anonymisiert, keine personenbezogenen Daten im LLM-Prompt dank sanitizePii()), Function-Call-Parameter (Kontakt-Lookup, Transfer-Ziel) | USA (SOC 2 Typ II zertifiziert, SCCs) | Link |
| ElevenLabs Inc. | Text-to-Speech (TTS) für (1) den KI-Telefonassistenten (via Retell AI), (2) die Angebots-Audio-Zusammenfassung (direkter API-Aufruf an ElevenLabs Multilingual v2) und (3) AI Talk Studio — PROJ-666: Sprachsynthese der KI-Persona NORA (NORA-Antworttexte, max. 2000 Zeichen pro Call, via POST /v1/text-to-speech/{voice_id}, Modell eleven_multilingual_v2; Audio-Stream transient, keine serverseitige Persistenz bei ElevenLabs). Generierung natürlicher deutscher Sprachausgabe. | KI-Telefonassistent: Synthetisierte Sprachantworten (Text-Input von Retell AI, Audio-Output zurück an Retell AI). Angebots-Audio: KI-generierte Angebots-Zusammenfassungen (Leistungen, Konditionen, Ablauf — optional Anrede und Nachname der Kontaktperson des Angebots für persönliche Ansprache, keine Preise). AI Talk Studio: NORA-Antworttexte (KI-generiert, ohne Endkunden-PII), Audio-Stream (audio/mpeg, transient). | USA (SOC 2 Typ II zertifiziert, SCCs) | Link |
| Higgsfield AI Inc. | KI-On-Brand-Bild-Generierung im CMS (PROJ-596 — higgsfield_image_generation) UND KI-Video-Generierung im Markenasset-Studio (PROJ-607 Phase 2 — higgsfield_video_generation): Wenn ein Plattform-Admin den DPA bestätigt UND adapter_mode='live' setzt, werden user-getriggerte Prompts (max 500 Zeichen, sanitisiert via sanitizePii) zusammen mit On-Brand-Constraints (CI-Hex-Farben aus ssot_items, Brand-Style-Beschreibung aus workspace_higgsfield_settings, Avoid-Liste) an Higgsfield übermittelt. Bild-Pfad: 3 Varianten je Aufruf. Video-Pfad: 1 Variante je Aufruf, Längen 5/10/15/30s, Kameraführung wählbar (static/pan/dolly_in/orbit), optional Image-to-Video mit signed URL eines bestehenden brand_assets als Referenz (Signed-URL-TTL 10 Min). Generierte Medien werden als brand_assets im Workspace-Storage gespeichert (is_ai_generated=true, ai_generated_by='higgsfield', EU AI Act Art. 50). Bis DPA-Abschluss läuft adapter_mode='mock' — alle Generierungen erfolgen lokal über einen Mock-Adapter, keine Daten verlassen die Plattform. Quota pro Workspace pro Monat (Default 50, konfigurierbar; Video kostet 4 Quota-Slots). Hardcoded Wordlist-Filter (AC-22) blockt Personen-Namen, NSFW-Begriffe, Markenrechte vor Übermittlung; PROJ-620 CRM-Referenzen — KI-Mockups für Portfolio-Visualisierung (Bild/Video-Generierung als Asset-Galerie-Material für CRM-Referenz-Einträge eines Kontakts; nutzt denselben Higgsfield-Adapter-Pfad wie PROJ-596/607, dieselbe Quota, derselbe Wordlist-Filter — kein zusätzlicher Datenfluss). KI-CD-Generator (PROJ-652): Logo-, Signet-, Moodboard- und Mockup-Bild-Generierung für 3 alternative Corporate-Design-Routen pro Kunden-Briefing — nutzt denselben Higgsfield-Adapter-Pfad und dieselbe Quota wie PROJ-596/607, mit dedizierten cd_logo_kind-Kategorien (wordmark/signet je color/negative/monochrome, moodboard, mockup_mug/polo/flag/business_card/phone). Brand Vision Studio (PROJ-654): Image-to-Image (Phase 2 — Transformation hochgeladener Kunden-Rohbilder mit referenceImageUrls[] + imageToImageStrength 0.3–0.9) und Text-to-Image (Phase 3 — Neue Bilder auf Basis freigegebener Master-Prompts pro Bildkategorie). Modell-Auswahl pro Kategorie via src/lib/brand-vision/model-mapping.ts (Portrait→Soul, Product→Flux, Lifestyle→Soul, Abstract→Seedream — User kann manuell überschreiben). Generierte Bilder als brand_assets mit source_kind='brand_vision_studio' + is_ai_generated=true (EU AI Act Art. 50). Nutzt denselben Higgsfield-Adapter-Pfad, dieselbe Quota und denselben Wordlist-Filter wie PROJ-596/607/652. + Face-Identity-Preservation für vom User markierte Referenzbilder (PROJ-674): Wenn der User in der KI-Studio-UI den Toggle 'Gesicht exakt übernehmen' für ein Referenzbild aktiviert, wird die UUID des Assets als face_lock_asset_id im Job persistiert. Der Adapter bevorzugt dann ein face-fähiges Higgsfield-Modell (SoulID/PuLID/IP-Adapter-Face-ID via Discovery-Heuristik) und erhöht den Image-Weight auf 1.0 (statt Default 0.5). Bei fehlendem face-fähigem Modell: Fallback auf Standard-Modell + Prompt-Marker '(preserving the exact facial identity from Reference Image N)'. Cap auf 1 Face-Lock pro Job. Bilder mit echten Personen unterliegen Art. 9 DSGVO (biometrische Daten) — User muss vor Upload die Einwilligung der abgebildeten Person eingeholt haben (User-Aufklärung via Help-Center + Erst-Nutzungs-Modal). Keine Speicherung biometrischer Embeddings im System (clientseitige Face-Detection rein zur UI-Anzeige, keine Server-Persistenz). | Aktuell (mock-Modus): Keine Datenübermittlung — alle Generierungen lokal über MockHiggsfieldAdapter. Bei live-Modus (nach DPA): Sanitisierter User-Prompt (max 500 Zeichen, kann theoretisch indirekt Personenbezug enthalten — wird durch Wordlist-Filter geblockt vor Übermittlung), CI-Hex-Farben (öffentliche Brand-Daten, keine PBD), Brand-Style-Beschreibung (öffentliche Marketing-Sprache, keine PBD), Avoid-Liste (Workspace-konfigurierte Begriffe). Generierte Bilder können theoretisch generische Personen-Darstellungen enthalten (KI-erzeugt, keine echten Personen) — Content-Rating-Pipeline (PROJ-421 AIH) klassifiziert NSFW automatisch und sperrt mit is_restricted=true | USA (DPA und SCC werden vor Produktivschaltung — d.h. vor adapter_mode='live'-Switch — abgeschlossen) | Link |
| Google LLC (Google Cloud Vision API) | Reverse-Image-Search / Web Detection für Plagiats-Prüfung generierter Logos im KI-CD-Generator (PROJ-652): Pro Auto-Gen-Logo (`wordmark_monochrome`, schwarz auf weiß — 3 Routen × 1 Logo = 3 Checks pro Briefing seit 2026-05-20) wird eine Signed-URL (15min TTL, aus dem privaten cd-generator-Storage-Bucket) an die Vision API gesendet. Vision liefert webDetection.fullMatchingImages + partialMatchingImages + visuallySimilarImages + webEntities zurück. Daraus wird ein normalisierter Similarity-Score (0-100%) berechnet. Schwellen: <50% clean, 50-80% review, >80% blocked. Kein persistentes Speichern bei Google — die Bilder werden ausschließlich im Request-Body referenziert (via Signed-URL-Download durch Google) und nach der Response verworfen. | Signed-URL einer generierten Logo-Bilddatei (15min TTL, transient — Google lädt das Bild herunter, analysiert es, gibt Match-URLs/Entities zurück). Keine PBD, da es sich um KI-generierte Logos ohne Personenbezug handelt. Keine Workspace-Metadaten, kein Briefing-Kontext. | USA / multi-region (Standardvertragsklauseln, Google Cloud DPA) | Link |
| Daily Inc. (Daily.co) | Video-Konferenzen (WebRTC) im Browser und in der macOS-Companion-App (PROJ-553: WebRTC läuft in einer sichtbaren WKWebView innerhalb der nativen macOS-App, identische Daily-Token-Mint-Logik wie im Browser-Kontext, gleiches @daily-co/daily-js-SDK), Cloud-Recording für Meeting-Aufzeichnungen | Anzeigename des Teilnehmers, Audio/Video-Streams (ephemer, nur während des Meetings — sowohl im Browser als auch in der macOS-App), Raum-Konfiguration (UUID, Ablaufzeit, Warteraum), Meeting-Aufzeichnungen (MP4, nach Meeting-Ende an NEULAND. OS übertragen und aus Daily.co gelöscht). Bei macOS-App-Teilnahme werden zusätzlich technische SIP-/WebRTC-Verbindungs-Metadaten ausgetauscht (Daily-Server-Side gehandhabt). | USA (EU-Processing verfügbar, DPA) | Link |
| Meta Platforms Inc. | Social-Media-Publishing über die Graph API: Veröffentlichung von Beiträgen auf Facebook Pages und Instagram Business-Accounts (Bilder, Videos, Carousel, Reels, Stories), Kommentar-Synchronisation und -Beantwortung, Account-Metriken. Serverseitige Conversion-Übermittlung (Meta Conversions API): SHA-256-gehashte Nutzerdaten zur Conversion-Attribution. Meta Marketing API v19+: Import von Kampagnen-Performance-Daten (Spend, Reichweite, CPM, CPC, Conversions) aus verbundenen Ad-Accounts — Auslösung manuell oder, seit PROJ-1919, nach einem je Workspace einstellbaren Zeitplan (aus, stündlich, täglich oder wöchentlich zu fester Uhrzeit im Halbstunden-Raster, Berliner Zeit) über einen alle 15 Minuten prüfenden Cron; keine Endnutzerdaten, ausschließlich aggregierte Kampagnen-Metadaten. Meta Business Manager / Graph API `/me/adaccounts` (PROJ-569): Discovery aller Ad-Accounts unter dem Business Manager der Agentur (Scope `business_management` + `ads_read`) zur Befüllung des Werbekonten-Pickers im CRM-Kontakt-Tab. Keine neuen Tokens — Wiederverwendung der bestehenden Social-OAuth-Verbindung. Geschäftsdaten der Account-Inhaber, kein End-User-Personenbezug. System-User-Token-Alternative (PROJ-1472): Statt der Human-OAuth-Verbindung kann pro Workspace ein im Meta Business Manager manuell erzeugter, langlebiger System-User-Access-Token hinterlegt werden (auth_method=system_user). Der Token wird beim Speichern serverseitig via `/me/adaccounts` validiert, AES-256-GCM-verschlüsselt (eigener META_SYSTEM_USER_ENCRYPTION_KEY) gespeichert und dient nicht nur der Werbekonten-Discovery, sondern wird seit PROJ-1476 zusätzlich für die Facebook-Page-/Instagram-Discovery via `/me/accounts` genutzt (Zugriff auf Seiten-/Instagram-Metadaten unter demselben System-User) — kein neuer Anbieter und keine neue Datenkategorie, lediglich ein erweiterter Verwendungszweck desselben Tokens innerhalb der bestehenden Meta-Datenverarbeitung. Meta Marketing API v23.0 `/act_<id>/campaigns` Campaign-Create (PROJ-790): Übertragung der Kampagnenstruktur (Name, Objective, Status=PAUSED, Special-Ad-Categories, Daily-/Lifetime-Budget in Cents, Bid-Strategy) an Meta zur werblichen Auslieferung. OAuth-Scope `ads_management` (Wiederverwendung der bestehenden Connection). Audience-IDs werden als opake Referenzen übertragen, keine direkten End-User-Personendaten im Request-Body. Audit-Log in `paid_campaign_pushes` mit redacted Tokens. Graph API Media-Insights (PROJ-1469, täglicher Cron): Abruf aggregierter Post-Kennzahlen (Reichweite, Impressions, Engagement, Video-Views/Watch-Time) für bereits veröffentlichte eigene Organic-Posts der Agentur/Kunden-Accounts zur internen Auswertungsschicht — keine Endnutzerdaten, ausschließlich aggregierte Post-Metriken. Erweiterung PROJ-1901 (derselbe tägliche Cron, dieselbe Verbindung): Der Abruf holt zusätzlich die Reaktionszahlen einzeln (Likes, Kommentare, Teilungen) sowie die Vorschaubild-URL und Medien-Details des eigenen Beitrags. Das Vorschaubild wird einmalig heruntergeladen und in den eigenen privaten Speicher kopiert, weil die von Meta gelieferte Adresse nach wenigen Tagen abläuft — es handelt sich um das bereits öffentlich veröffentlichte Bildmaterial des eigenen Beitrags, keine Endnutzerdaten. Keine neuen Tokens — Wiederverwendung der bestehenden Social-OAuth-Verbindung. Ad Account Activity Log (PROJ-1895; läuft im Werbekonten-Import mit und folgt seit PROJ-1919 dessen je Workspace einstellbarem Zeitplan — aus, stündlich, täglich oder wöchentlich zu fester Uhrzeit im Halbstunden-Raster, Berliner Zeit, über einen alle 15 Minuten prüfenden Cron; Graph API v25.0 `/act_<id>/activities`): Abruf der Änderungshistorie verbundener Werbekonten zur Nachvollziehbarkeit steuernder Eingriffe (analog PROJ-1876/PROJ-1894 bei Google/Microsoft) — Details zur Datenkategorie und zur Nicht-Speicherung des Klarnamens siehe DATA_PROCESSING-Eintrag „Werbekonten-Änderungshistorie als Ereignisquelle“. Keine neuen Tokens — Wiederverwendung der bestehenden Ads-Verbindung (OAuth oder System-User). | OAuth-Zugangstokens (AES-256-GCM verschlüsselt), Post-Inhalte (Text, Medien-URLs), Kommentardaten (Autorenname, Text, Zeitstempel), Account-Metadaten (Seitenname, Avatar, Follower-Anzahl), SHA-256-gehashte E-Mail-Adressen, Telefonnummern, Vor-/Nachnamen und Postleitzahlen (Conversion-Tracking). PROJ-790 Paid-Campaign-Push: Kampagnen-Konfigurationsdaten (Name, Budget, Bid-Strategy, Special-Ad-Categories, Custom-Audience-IDs als opake Strings), keine PBD. PROJ-1469: aggregierte Post-Performance-Kennzahlen (keine PBD). PROJ-1895 Activity Log: Klarname und numerische Kennung des Urhebers einer Werbekonto-Änderung (`actor_name`, `actor_id`) — werden mit jeder Zeile mitgeliefert, aber NICHT gespeichert; `actor_name` wird von keiner Funktion gelesen, `actor_id` nur laufzeit-intern zur Erkennung mehrerer Urheber je Lauf verwendet (Details siehe DATA_PROCESSING-Eintrag). | USA (SCCs / Data Privacy Framework) | Link |
| LinkedIn Corporation | Social-Media-Publishing über die Community Management API: Veröffentlichung von Organisations-Beiträgen (Text, Bilder, Dokumente/Carousel), Kommentar-Synchronisation und -Beantwortung. LinkedIn Marketing Developer Platform / `/rest/adAccounts` (PROJ-569): Discovery aller Ad-Accounts unter dem Campaign Manager der Agentur (Scope `r_ads`) zur Befüllung des Werbekonten-Pickers im CRM-Kontakt-Tab. Keine neuen Tokens — Wiederverwendung der bestehenden Social-OAuth-Verbindung. Geschäftsdaten der Account-Inhaber, kein End-User-Personenbezug. LinkedIn Marketing API Version 202605 `/rest/adCampaigns` Campaign-Create (PROJ-790, Version-Upgrade auf 202605 via PROJ-883): Übertragung der Kampagnenstruktur (Account-URN, Name, Type, Status=PAUSED, CostType, DailyBudget+CurrencyCode, ObjectiveType) für werbliche Auslieferung. Bei Lead-Gen-Kampagnen zusätzlich `leadgenCallToAction.privacyPolicyUrl` (Pflichtfeld der LinkedIn-API). Scopes `r_ads`+`rw_ads`. Header `LinkedIn-Version: 202605` + `X-Restli-Protocol-Version: 2.0.0`. Audit-Log in `paid_campaign_pushes` mit redacted Tokens. Community Management API Share-Statistics (PROJ-1469, täglicher Cron): Abruf aggregierter Post-Kennzahlen (Impressions, Klicks, Engagement) für bereits veröffentlichte eigene Organic-Posts der Organisations-Accounts zur internen Auswertungsschicht (Scope `r_organization_social`) — keine Endnutzerdaten, ausschließlich aggregierte Post-Metriken. Erweiterung PROJ-1901 (derselbe tägliche Cron, dieselbe Verbindung): Zusätzlich wird je Beitrag mit Medium über `/rest/posts` die Medien-Kennung und darauf über `/rest/images` bzw. `/rest/videos` die Vorschaubild-Adresse aufgelöst (Scope `w_organization_social`, bereits vorhanden). Das Vorschaubild wird einmalig heruntergeladen und in den eigenen privaten Speicher kopiert — es handelt sich um das bereits öffentlich veröffentlichte Bildmaterial des eigenen Beitrags, keine Endnutzerdaten. Keine neuen Tokens — Wiederverwendung der bestehenden Social-OAuth-Verbindung. LinkedIn Marketing API `/rest/adAnalytics` (PROJ-1612): Abruf tagesgenauer Kampagnen-Performance-Kennzahlen — on demand oder, seit PROJ-1919, nach einem je Workspace einstellbaren Zeitplan (aus, stündlich, täglich oder wöchentlich zu fester Uhrzeit im Halbstunden-Raster, Berliner Zeit) über einen alle 15 Minuten prüfenden Cron (Impressionen, Klicks, Kosten, Conversions je Kampagne und Tag, Pivot CAMPAIGN, timeGranularity DAILY) für verbundene Werbekonten, gespeichert in campaign_snapshots. Keine neuen Tokens — Wiederverwendung der bestehenden Social-OAuth-Verbindung (Scope `r_ads`). Keine Endnutzerdaten, ausschließlich aggregierte Kampagnen-Metriken. | OAuth-Zugangstokens (AES-256-GCM verschlüsselt), Post-Inhalte (Text, Medien-URLs), Kommentardaten (Autorenname, Text, Zeitstempel), Organisations-Metadaten. PROJ-569: zusätzlich LinkedIn-Ads-Account-IDs, Account-Namen, Währung — Geschäftsdaten ohne End-User-PII. PROJ-790 Paid-Campaign-Push: Kampagnen-Konfigurationsdaten (Account-URN, Name, Budget mit CurrencyCode, Lead-Gen-Datenschutz-URL als Pflichtfeld der LinkedIn-API), keine PBD. PROJ-1469: aggregierte Post-Performance-Kennzahlen (keine PBD). | USA (SCCs / Data Privacy Framework) | Link |
| X Corp. (Twitter) | Social-Media-Publishing über die X API v2: Veröffentlichung von Tweets (Text, Bilder, Videos, Threads, Polls, Quote-Tweets) | OAuth 2.0 PKCE-Zugangstokens (AES-256-GCM verschlüsselt), Tweet-Inhalte (Text, Medien-URLs), Account-Metadaten (Handle, Anzeigename) | USA (SCCs) | Link |
| Apple Inc. | Apple Push Notification Service (APNs): Zustellung nativer Push-Benachrichtigungen an die NEULAND. OS Companion-App auf iOS und macOS | APNs Device Token (geräte- und app-spezifischer Identifier), Benachrichtigungstitel und -text: für generische System-Notifications nur 'Neue Benachrichtigung', für Chat-Notifications (PROJ-257) Absender-Name und Nachrichtenvorschau (max. 100 Zeichen — kein vollständiger Nachrichteninhalt), für Wiedervorlagen-Fälligkeits-Pushes (PROJ-400) ein Kurz-Titel ('Wiedervorlage fällig') ohne Label-Inhalte im Klartext, Badge-Count, Routing-Metadaten (room_id, workspace_slug, follow_up_id als technische Deep-Link-Parameter) | USA (SCCs / Data Privacy Framework) | Link |
| ByteDance Ltd. (TikTok) | Social-Media-Publishing über die TikTok Content Posting API: Upload von Videos und Fotos, Kommentar-Leseabfrage (Read-Only) | OAuth-Zugangstokens (AES-256-GCM verschlüsselt), Video-/Foto-Inhalte, Kommentardaten (Autorenname, Text, Zeitstempel — Read-Only), Account-Metadaten | USA/Singapur (SCCs). Hinweis: ByteDance Ltd. hat seinen Hauptsitz in China (Peking). Es kann nicht ausgeschlossen werden, dass chinesische Behörden auf Grundlage des chinesischen Datensicherheitsgesetzes (DSL) Zugriff auf Daten verlangen. SCCs und ergänzende Maßnahmen (Transfer Impact Assessment) werden eingesetzt | Link |
| Flyeralarm GmbH | Drucksachen-Bestellabwicklung über die Flyeralarm eSolutions API: Produktkatalog-Sync, Preisberechnung, Druckdaten-Validierung, Bestellaufgabe und Bestellstatus-Tracking | Bestelldaten (Produktkonfiguration, Mengen, Preise), Lieferadressen (werden 30 Tage nach Lieferung gelöscht), Druckdateien (PDF), Bestellstatus und Tracking-Links | Deutschland (Würzburg). Datenverarbeitung in der EU | Link |
| IPinfo LLC | IP-Unternehmens-Erkennung (PROJ-290): Asynchrone Anreicherung von Tracking-Sessions mit Unternehmensinformationen anhand von IP-Adressen — ausschließlich auf Unternehmensebene (B2B). Verwendet für das ABM-Dashboard. IP-Adressen werden transient verarbeitet und nicht gespeichert — nur das Ergebnis (Unternehmensname, -domain, Branche, Größenklasse) wird der jeweiligen Tracking-Session zugeordnet. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse im B2B-Kontext). | IP-Adresse des Website-Besuchers (transient, wird nicht gespeichert — nur für den API-Aufruf verwendet), zurückgeliefert und gespeichert: Unternehmensname, Unternehmensdomain, Branche, Größenklasse (ausschließlich Unternehmens-Daten, keine personenbezogenen Daten natürlicher Personen) | USA (Delaware). DPA verfügbar, SCCs für Drittlandstransfer | Link |
| Open Exchange Rates Ltd. | Täglicher Abruf von Devisenkursen für die Währungsumrechnung im KI-Kampagnen-Analyse-Modul (PROJ-294). Konvertierung von Ads-Spend-Daten aus Fremdwährungen (z.B. USD) in die Workspace-Standardwährung. Keine personenbezogenen Daten werden übermittelt. | Keine personenbezogenen Daten — ausschließlich öffentliche Wechselkursdaten (Währungspaare und Tageswechselkurse) | USA (SCCs) | Link |
| GitHub, Inc. | (1) Bundle-Repository-Hosting für agentur-eigene Composer-Pakete (Contao Hub Bundle Bootstrap, PROJ-586). Auf admin-getriggerten Klick erstellt der Hub via REST-API ein Repository in der Organisation `neulandagentur` (POST /orgs/neulandagentur/repos), pusht ein lauffähiges Composer-Bundle-Skelett (Tree + Commit + Ref auf main-Branch) und erstellt parallel den Bundle-Eintrag in `contao_bundles`. Bei Push-Failures wird das Repository per DELETE wieder aufgeräumt (atomarer Rollback). Authentifizierung via dediziertem Fine-Grained-PAT (GITHUB_BUNDLE_BOOTSTRAP_TOKEN) mit Permissions Administration:RW + Contents:RW + Metadata:R. (2) PROJ-662 KI-Requirements-Assistent: Workspace-konfigurierter Fine-Grained-PAT (verschlüsselt gespeichert via AES-256-GCM in workspaces.github_token_encrypted) pusht generierte Feature-Spezifikationen (features/PROJ-X-name.md + INDEX.md-Update) atomar via Tree+Commit+Ref-API in das Workspace-konfigurierte Ziel-Repository (workspaces.github_repo_owner/github_repo_name) auf den Workspace-konfigurierten Target-Branch (Default 'main', Preview-Env: 'preview/requirements'). PROJ-ID-Race-Condition wird via GitHub-SHA-Lock (409 Conflict bei stalem Ref) mit max. 3 Retries gelöst. Commit-Message-Format: 'feat(PROJ-X): Add feature specification for [feature name] (via KI-Assistent, submitted by [display_name])'. (3) PROJ-1418 PR-Merge-Benachrichtigung + Dev-Inbox: `GITHUB_PR_MERGE_TOKEN` (bis PROJ-1658: Fine-Grained-PAT mit Pull-requests + Contents Read/Write auf `neulandagentur/neuland-os`; seit PROJ-1658 auf ein Classic Personal Access Token mit Scope `repo` umgestellt, weil GitHubs Check-Runs-Lese-Endpunkt für Fine-Grained-PATs keine passende Permission-Kategorie anbietet — live verifiziert, siehe `docs/production/monitoring-status-PROJ-1658.md`) für mehrere Zwecke — Empfang von CI-Check-Status-Events per HMAC-signiertem Webhook (`POST /api/webhooks/github-pr-status`), serverseitige Squash-Merge- und Branch-Lösch-Aufrufe an `api.github.com`, sowie seit PROJ-1658 aktives Auflisten offener PRs + Lesen von Check-Runs/Compare/Tree-Daten und automatisches Erstellen neuer Commits/Branches/PRs bei ausgebliebenem CI-Check-Trigger (siehe Punkt unten). Bis PROJ-1478 ausschließlich ausgelöst durch Marcels manuelle Merge-Aktion in der Dev-Inbox; seit PROJ-1478 löst der grün gewordene Pflicht-Check den Merge automatisch im selben Webhook-Handler aus (kein manueller Klick mehr nötig) — der manuelle Button bleibt als Fallback bestehen, falls der automatische Merge technisch nicht möglich ist (z.B. Draft-PR, Token-Ausfall). (4) PROJ-1658 CI-Pflicht-Check-Trigger-Ausfall-Erkennung: automatischer Cron (`ci-trigger-check`, alle 2 Min) listet offene PRs, prüft Check-Run-Existenz, und eskaliert bei ausbleibendem Trigger über Leer-Commit-Retrigger bis hin zu automatischem Branch-Neustart (neuer Commit + neuer Branch + neuer PR + Schließen/Kommentieren des alten PR) auf demselben Repository (seit PROJ-1823 commit-frei: nur noch Schließen+Wiederöffnen des PR-Objekts). (5) PROJ-1832 Persönliche GitHub-Kontoanbindung für den manuellen Branch-Neustart: Entwickler verbinden ihr eigenes GitHub-Konto per OAuth (bestehende OAuth-App der Workspace-Integration, Scope `repo`); der Zugriffstoken wird AES-256-GCM-verschlüsselt in user_github_tokens gespeichert (nutzer-gebunden, eine Verbindung pro Person). Der 'Branch neu abzweigen'-Button in der Benachrichtigung 'Pflicht-Check startet nicht' führt den Branch-Neustart (Compare/Tree/Commit/Branch/PR-Erstellung + Schließen des alten PR) mit diesem persönlichen Token aus — Commits/PRs entstehen unter der echten Identität des auslösenden Entwicklers (Attributions-Ehrlichkeit, Vercel-Deployment-Zuordnung). Übermittelt werden ausschließlich PR-Nummern, Commit-SHAs, Dateiinhalte des eigenen Code-Repositories und Merge-Parameter — keine Endkunden-Personendaten. | (PROJ-586) Repository-Metadaten (Name, Description, Visibility=private/public), Composer-Bundle-Skelett-Dateien als Initial-Commit (composer.json mit Vendor/Name/Namespace + Author-E-Mail aus auth.users.email, Bundle-Class, Contao-Manager-Plugin, DI-Extension, services.yaml, .gitignore, README.md). Initial-Commit-Author: Service-Account 'NEULAND. OS Bundle Bootstrap <bundle-bootstrap@neuland-agentur.com>' mit Co-Authored-By-Trailer der eingeloggten Admin-E-Mail. GitHub-API-Antworten werden serverseitig redaktiert (Bearer/token/Authorization-Strings → [REDACTED]) bevor sie ins Audit-Log (contao_bundle_operations.output) geschrieben werden — harte Begrenzung auf ca. 10.000 Zeichen pro Eintrag. (PROJ-662) Generierte Markdown-Spezifikationen mit User-formulierten Feature-Beschreibungen (können implizite Kunden- oder Mitarbeiter-Bezüge enthalten — Workspace-Admin ist verantwortlich für Inhalts-Prüfung vor Commit), Commit-Message-Metadaten (Anzeige-Name des Submitters, kein Klartext-Token), INDEX.md-Update-Diff. Token-Redaktion (Regex github_pat_*, ghp_*, ghs_*, gho_*) in allen Logs. | USA (DPA — GitHub Customer Agreement + Data Protection Agreement) | Link |
| Matelso GmbH | Call-Tracking & Attribution: Zuordnung von Inbound-Telefonanrufen zu Web-Sessions und Werbekampagnen (PROJ-418). Matelso übermittelt nach Beendigung eines Anrufs via Webhook: Anrufernummer (wird serverseitig sofort SHA-256-gehasht), Zielrufnummer, Gesprächsdauer, Klingeldauer, Anrufstatus, Click-IDs (GCLID, FBCLID) und UTM-Parameter. Matelso empfängt als Custom-Data die Neuland-Session-ID für Session-Stitching. Zusätzlich (PROJ-568): Cron-Sync alle 6h zum show_subscribers-Endpoint der Matelso-XML-API zur Anreicherung der Pool-Mappings um Subscriber-Namen + Subscriber-Domain (Geschäftsdaten von Matelso-Account-Inhabern, kein End-User-Personenbezug). Routing-Regeln werden ausschließlich lokal verwaltet und nicht an Matelso übermittelt. | Anrufernummer (transient, SHA-256-gehasht vor Persistierung — kein Klartext in DB), Zielrufnummer, Gesprächsdauer und -status, Werbe-Click-IDs (GCLID, FBCLID, WBRAID, MSCLKID), UTM-Kampagnenparameter, Landing-Page-URL, Referrer, Neuland-Session-ID (aus sessionStorage — nur bei aktiviertem Matelso-Stitching und Consent), Subscriber-Name + Subscriber-Domain (Geschäftsdaten der Matelso-Account-Inhaber, gecacht für UI-Anzeige im Pool-Picker — PROJ-568) | Deutschland (DSGVO-konform) | Link |
4. Cookies
Wir setzen technisch notwendige Cookies (Rechtsgrundlage: §25 Abs. 2 Nr. 2 TDDDG — unbedingt erforderlich für die Bereitstellung des Dienstes) sowie funktionale Cookies (Rechtsgrundlage: §25 Abs. 1 TDDDG i.V.m. Art. 6 Abs. 1 lit. a DSGVO — Einwilligung) ein. Es werden keine Tracking- oder Marketing-Cookies verwendet.
| Cookie | Zweck | Lebensdauer | Typ |
|---|---|---|---|
| sb-*-auth-token | Supabase-Authentifizierungs-Session (enthält sb-*-auth-token.0 und ggf. sb-*-auth-token.1 als chunked Cookies für Access Token + Refresh Token) | Session-Dauer (bis Logout); Access Token 1 Stunde, Refresh Token 7 Tage | notwendig |
| wm_cache | Workspace-Memberships-Cache (HMAC-signiert) | 5 Minuten | notwendig |
| active_workspace | Aktiver Workspace (httpOnly) | 30 Tage | notwendig |
| yt_consent | YouTube-Consent-Merker für CMS-Video-Galerie (speichert Einwilligung zur YouTube-Einbettung über die datenschutzfreundliche Domain youtube-nocookie.com — erst nach Zustimmung werden YouTube-Player geladen) | 30 Tage | funktional |
| cms_consent | Cookie-Einwilligung auf öffentlichen CMS-Kundenwebsites (PROJ-1121, veraltet seit PROJ-1287): speichert die Kategorien-Auswahl (Statistik/Marketing), die Banner-Version und den Zeitstempel. Abgelöst durch nlcs-Cookie. | 12 Monate (läuft natürlich aus) | notwendig |
| nlcs | Cookie-Einwilligung auf öffentlichen CMS-Kundenwebsites (PROJ-1287) und den eigenen Landing Pages (PROJ-1904, gemeinsamer Consent-Kern): speichert die Kategorien-Auswahl (notwendig/statistik/marketing/externe-medien, seit PROJ-2296 vier feste Kategorien statt frei benennbarer — vormals notwendig/funktional/Statistik/Marketing), die Banner-Version und den Zeitstempel. URL-kodiertes JSON, kein personenbezogener Inhalt. Tracking-/Marketing-Skripte werden erst nach Zustimmung geladen. Gesetzt pro Domain (Kunden-Website bzw. eigene Landing Pages). | 12 Monate | notwendig |
| nlcs_vid | Anonyme Besucher-UUID (PROJ-1287), getrennt vom Entscheidungs-Cookie nlcs gesetzt — verknüpft eine Einwilligungsentscheidung mit dem serverseitigen Nachweis (consent_records), ohne Klarnamen oder sonstigen personenbezogenen Inhalt. Gesetzt auf öffentlichen CMS-Kundenwebsites und den eigenen Landing Pages (PROJ-1904). | 12 Monate | notwendig |
| nl_uid | Besucher-Wiedererkennung im Website-Tracking (PROJ-1503, Tier-2-Opt-in): speichert die pseudonyme Identity-UUID (user_identity.pseudonymous_id), damit wiederkehrende Besucher über mehrere Sessions im selben Browser als eine Person gezählt werden (Unique Visitors). Wird AUSSCHLIESSLICH nach explizitem Opt-in in der Consent-Kategorie 'Besucher-Wiedererkennung' serverseitig gesetzt (HttpOnly, Secure, SameSite=None, pfadbeschränkt auf /api/tracking) — der serverseitige Consent-Nachweis (consent_records, Kategorie identity) wird bei jeder Wiederanknüpfung geprüft. Ohne Opt-in wird das Cookie nie gesetzt; nach Widerruf wird es gelöscht und keine weitere Session mehr der bestehenden Identität zugeordnet. Kein Fingerprinting, keine Klartext-Login-Daten (Login-IDs werden nur als HMAC-SHA256-Hash verarbeitet). | 395 Tage (rolling — wird bei jedem Besuch mit gültigem Consent-Nachweis verlängert) | statistik |
| nland_ref | Affiliate-Referral-Zuordnung (speichert den Referral-Code eines Affiliate-Partners zur Conversion-Zuordnung, kein personenbezogener Inhalt) | 90 Tage | funktional |
| google_oauth_nonce | CSRF-Schutz bei der persönlichen Google-Kontoanbindung (einmaliger Sicherheitstoken, httpOnly, pfadbeschränkt auf Callback-Endpunkt) | 10 Minuten (nach Verwendung sofort gelöscht) | notwendig |
| meta_oauth_token | Temporärer verschlüsselter Meta-OAuth-Token für die Facebook/Instagram Page-Auswahl nach OAuth-Autorisierung (httpOnly, AES-256-GCM verschlüsselt) | 15 Minuten (nach Verwendung sofort gelöscht) | notwendig |
| meta_oauth_state | CSRF-Schutz beim Start der Meta/Facebook-OAuth-Anbindung (einmaliger Sicherheitstoken, httpOnly) | 10 Minuten (nach Verwendung sofort gelöscht) | notwendig |
| linkedin_oauth_state | CSRF-Schutz beim Start der LinkedIn-OAuth-Anbindung (einmaliger Sicherheitstoken, httpOnly) | 10 Minuten (nach Verwendung sofort gelöscht) | notwendig |
| google_ads_oauth_nonce | CSRF-Schutz bei der Google-Ads-Konto-Anbindung (einmaliger Sicherheitstoken, httpOnly, pfadbeschränkt auf Callback-Endpunkt) | 10 Minuten (nach Verwendung sofort gelöscht) | notwendig |
5. Lokale Speicherung (localStorage)
Neben Cookies nutzen wir die localStorage-Funktion Ihres Browsers, um funktionale Einstellungen lokal zu speichern. Diese Daten werden nicht an unsere Server übertragen.
| Schlüssel | Zweck | Lebensdauer | Typ |
|---|---|---|---|
| theme | Darstellungseinstellung (Hell/Dunkel/System) — FOUC-Prävention | Bis manuell gelöscht | funktional |
| dms_viewMode | Ansicht-Einstellung im Dokumentenmanagementsystem (Grid- oder Listenansicht) | Bis manuell gelöscht | funktional |
| sidebar_perspective_{slug} | Gewählter Navigations-Fokus-Modus der Sidebar (Alle Module / Umsetzung / Vertrieb / Verwaltung) — workspace-spezifisch, keine personenbezogenen Daten | Bis manuell gelöscht | funktional |
| neuland_voice_consent | Einwilligung zur Spracheingabe-Funktion (speichert ob der Nutzer der Audio-Übertragung an OpenAI zugestimmt hat) | Bis manuell widerrufen oder gelöscht | funktional |
| presence_invisible | Unsichtbar-Modus der Team-Präsenzanzeige (sessionStorage — speichert ob der Nutzer für andere als offline erscheinen möchte) | Browser-Session (gelöscht bei Tab-Schließen) | funktional |
| gmail_last_account | Zuletzt ausgewähltes Absender-Konto beim E-Mail-Verfassen (speichert die Google-E-Mail-Adresse des zuletzt genutzten Kontos für Komfort-Vorauswahl) | Bis manuell gelöscht | funktional |
| inbox-view-mode | PROJ-1551: Ansichtsmodus der Inbox (Spalte oder Leiste) — reine UI-Präferenz, keine personenbezogenen Daten | Bis manuell gelöscht | funktional |
| inbox-importance-filter | PROJ-1636: Wichtigkeits-Filter der Inbox (Wichtig = nur Handlungsbedarf / Alle = ungefiltert) — als Standard-Ansicht beim Öffnen. Reine UI-Präferenz, keine personenbezogenen Daten | Bis manuell gelöscht | funktional |
| inbox-email-folder | PROJ-2108: zuletzt gewählter E-Mail-Ordner im Inbox-Ordner-Umschalter (Eingang/Gesendet/Spam/Papierkorb) — als Standard-Ansicht beim erneuten Besuch der Inbox. Reine UI-Präferenz, keine personenbezogenen Daten | Bis manuell gelöscht | funktional |
| table_cols_{tableId} | PROJ-434/1464: Tabellen-Konfiguration der Tracking-Dashboard-Tabellen (Spalten-Sichtbarkeit, -Reihenfolge, Sortierung, Seitengröße) — geräte-/browsergebunden, pro Tabellen-ID (z.B. Picker-Widgets, Top-Seiten, Kampagnen-Qualitätsmatrix, Friction-Leaderboard). Keine personenbezogenen Daten, rein UI-Präferenz | Bis manuell gelöscht | funktional |
| daterange_default_{tableId} | PROJ-2211: Individuell gewählter Standard-Zeitraum je Tabelle des zentralen Zeitraum-Bausteins (DateRange), pro Tabellen-ID (z.B. tracking_global). Speichert ausschließlich einen Preset-Bezeichner (z.B. last_7d) — geräte-/browsergebunden, kein Geräte-Sync, keine serverseitige Übertragung, keine personenbezogenen Daten, rein UI-Präferenz | Bis manuell gelöscht | funktional |
| timerange_bar_{tableId} | PROJ-2211: Leisten-Konfiguration der neu designten Zeitraumsteuerung (TimeRangeControl) je Diagramm/Tabelle (z.B. tracking_global) — welche Schnell-Buttons sichtbar sind (available) und die vom Nutzer selbst gespeicherten dynamischen Presets (customPresets, z.B. 'Letzte 23 Tage'). Speichert ausschließlich Preset-IDs und relative Zeitraum-Definitionen (Anzahl/Einheit/Anker-Offset) — geräte-/browsergebunden, kein Geräte-Sync, keine serverseitige Übertragung, keine personenbezogenen Daten, rein UI-Präferenz | Bis manuell gelöscht | funktional |
| timerange_active_{tableId} | PROJ-2211: Zuletzt angewandte aktive Zeitraum-Auswahl und Vergleichseinstellung der neu designten Zeitraumsteuerung (TimeRangeControl) je Diagramm/Tabelle (z.B. tracking_global) — dient als gespeicherter Standard (Präzedenz: URL > gespeicherter Standard > Default). Speichert ausschließlich Preset-IDs, relative Definitionen und ggf. gewählte Datums-Strings — geräte-/browsergebunden, kein Geräte-Sync, keine serverseitige Übertragung, keine personenbezogenen Daten, rein UI-Präferenz | Bis manuell gelöscht | funktional |
| cms_sidebar_collapsed | Persistierter Aufgeklappt/Eingeklappt-Status der CMS-Sidebar (workspace-übergreifend) — keine personenbezogenen Daten | Bis manuell gelöscht | funktional |
| cms_seiten_compact | Persistierter Kompakt-/Detail-Modus der Seitenstruktur-Tabelle im CMS — keine personenbezogenen Daten | Bis manuell gelöscht | funktional |
| neuland:projects:visible-columns | Persistierte Sichtbarkeit der Kennzahlen-Spalten (Aufgaben-Fortschritt/Verantwortlicher/Priorität) in der Projekte-Liste — pro Nutzer, keine personenbezogenen Daten (nur drei Boolean-Flags) | Bis manuell gelöscht | funktional |
| neuland:tasks:assignee-filter:{board-list|project-tab|redaktionsplan}:{userId} | Gemerkte Abweichung vom Assignee-Filter-Default "Meine Aufgaben" (Kanban-Board+Listen-Ansicht, Projekt-Tab "Aufgaben", Redaktionsplan). Wert ist ein JSON-Array aus "all", "unassigned" und/oder user_ids (PROJ-1532 Mehrfachauswahl im Board/Liste; Projekt-Tab und Redaktionsplan bleiben einwertig). Ältere, als Plain-String gespeicherte Werte werden weiterhin gelesen. Pro Ort UND pro eingeloggter Person getrennt (User-ID Teil des Schlüssels), keine personenbezogenen Daten außerhalb des eigenen Browsers | Bis manuell gelöscht | funktional |
| cms_theme_preview_device | Zuletzt gewähltes Gerät im Theme-Editor Live-Preview (mobile/tablet/desktop) — reine UI-Präferenz, keine personenbezogenen Daten | Bis manuell gelöscht | funktional |
| pagebuilder_draft_<pageId>_<locale> | Lokaler Notfall-Entwurf des Page-Builder-Seiteninhalts (Block-Baum als JSON) zum Schutz vor Datenverlust bei versehentlicher Navigation oder Tab-Absturz. Enthält nur redaktionelle CMS-Seiteninhalte, keine personenbezogenen Daten. Wird nach erfolgreichem Speichern automatisch gelöscht. | Bis zum nächsten erfolgreichen Speichern oder manuellem Verwerfen | funktional |
| configurator_mode | Gewählter Modus im Kampagnen-Konfigurator (Expert Mode / Guided Mode) — reine UI-Präferenz, keine personenbezogenen Daten | Bis manuell gelöscht | funktional |
| campaign_configurator_campaigns | Lokal gespeicherte Kampagnen-Planungsdaten im Konfigurator (Kampagnenname, Netzwerk, Typ, Budget, Status) — keine personenbezogene Identifikation, keine serverseitige Übertragung, reine Planungsdaten für die Agentur | Bis manuell gelöscht oder Browser-Storage geleert | funktional |
| neuland_tracking_picker_recent_<domainId>_<userId> | Zuletzt verwendete Dimensionen/Metriken im Widget-Auswahl-Picker (max. 10 Katalog-Keys + Grain, pro Tracking-Domain und pro eingeloggtem User) — reine UI-Komfortfunktion, keine personenbezogenen Daten | Bis manuell gelöscht oder Browser-Storage geleert | funktional |
6. Datenverarbeitungen nach Funktionsbereichen
Im Folgenden erläutern wir, welche personenbezogenen Daten in den einzelnen Funktionsbereichen unserer Plattform verarbeitet werden:
HAWEGO Preisübernahme-Historie — Auslöser-Protokoll manueller Live-Preisänderungen (PROJ-2334)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an Nachvollziehbarkeit und Revidierbarkeit eines direkten Schreibeingriffs in reale Verkaufspreise — Rechenschaft/Vier-Augen-Fähigkeit bei manuell ausgelösten Preisübernahmen).
- Preisübernahme-Historie (hawego_repricing_price_history, Shop-DB): Produkt-Referenz, Preis vorher/nachher (Cents), Referenzquelle, Auslöser-Art (manuell/nachtlauf), Mindestpreis-Klemmung, Revert-Kennzeichnung/verwiesener Vorgänger-Eintrag, Zeitpunkt — Geschäftsdaten ohne Personenbezug; PLUS triggered_by_user_id (UUID des auslösenden Agentur-Mitarbeitenden, nur beim manuellen Bulk-Weg gesetzt, beim Nachtlauf NULL).
KI-Antwortvorschlag für Kommentare & @Mentions (PROJ-2349)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an effizienter, schneller interner/kundenbezogener Kommunikation).
- Antwortvorschläge (comment_reply_suggestions): Verweis auf den Kommentar und den Ziel-Nutzer, vorgeschlagener Antworttext, numerische Confidence + Kurzbegründung, verwendeter Ton, Aktualitäts-Anker, Zeitstempel — strikt empfänger-gebunden (RLS: nur target_user_id = auth.uid()).
- Persönliche Einstellungen (user_comment_reply_settings): Standard-Ton, Opt-out-Schalter für die proaktive Generierung.
- Transient an Anthropic übermittelt: PII-sanierter Kommentar-Thread-Text + PII-sanierte Aufgaben-/Projekt-Stammdaten (kein Roh-Personenbezug, sanitizePii() vor jedem Prompt-Aufbau, D-74-01/R-1825).
Schreibstil-Kalibrierung für Kommentar-Antwortvorschläge (PROJ-2357)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an einer passenden, korrekturarmen Vorbelegung der KI-Antwortvorschläge; Analyse ausschließlich eigener Texte des Nutzers, Wirksamkeit nur nach aktiver Bestätigung).
- Kalibrierungs-Ergebnis (user_comment_reply_settings.style_analysis_*): Status (none/suggested/accepted/dismissed), vorgeschlagener Ton, kurze KI-Begründung (max. 1000 Zeichen, DB-CHECK), Analyse-Zeitstempel — nutzergebunden (FK auf auth.users, ON DELETE CASCADE).
- Transient an Anthropic übermittelt: PII-sanierte Stichprobe der eigenen Kommentar-Texte des Nutzers (jüngste max. 200 Kommentare, gekappt; kein Roh-Personenbezug, sanitizePii() vor dem Prompt-Aufbau).
USP-Generik-Klassifikation — Content-Intelligence-Qualitätsgate (PROJ-2114)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an einer qualitätsgesicherten, seitenspezifischen Content-Generierung für Kundenprojekte).
- USP-Bewertungen (ci_usp_generik_bewertung): Verweis auf die USP-Zeile (ssot_item_id), Einstufung (spezifisch/generisch/nicht_ermittelbar), kurze Begründung, verwendetes Modell, Text-Hash und optionaler menschlicher Override — abgeleitete Qualitäts-Metadaten zu Unternehmens-USP-Aussagen, kein Personenbezug (Live-Prüfung 10.08.2026: 0/204 USP-Texte mit E-Mail-Mustern).
Mitarbeitergespräche — Buchung, Vorbereitung, Dokumentation, Historie (PROJ-2102/PROJ-2103)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Durchführung des Beschäftigungsverhältnisses) i.V.m. § 26 BDSG (Personalführung/Personalentwicklung, inkl. Gehaltsverhandlung); für die Organisations-Metadaten (Buchungsfenster, Round-Robin-Zuweisung) zusätzlich Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an strukturierter Personalführung).
- Gesprächs-Datensätze (employee_conversations): betroffene Person (profile_id), ein oder zwei Gesprächsführer (conducted_by, conducted_by_2 — seit PROJ-2214 werden neue Gespräche mit beiden aktiven Geschäftsleitungs-Mitgliedern geführt), Gesprächstyp (regulär/Jahresgespräch), Status, Termin-/Durchführungs-/Dokumentations-Zeitpunkte, vereinbarte Maßnahmen (Freitext), Follow-up-Fälligkeitsdatum, Verknüpfung zur Buchung.
- Gesprächsnotizen (employee_conversation_notes): Vorbereitungs- und Ergebnis-Notizen je Kompetenzbereich (Fach-, Methoden-, Sozial-, Persönliche Kompetenz) als Freitext — Personalakte-relevante Einschätzungen zur beruflichen Entwicklung.
- Buchungsfenster-Zuordnung (booking_pages.employee_profile_id): Verknüpfung der wiederkehrenden Buchungsseite (quartalsweise UND/ODER jährlich, beide unabhängig aktiv möglich) zur betroffenen Person.
- PROJ-2103 Gehaltsabschnitt: interner Verhandlungs-Zielkorridor in eigener Tabelle employee_conversation_salary_prep (RLS ohne Zugriffsrecht für die betroffene Person — nur Geschäftsführung), dokumentiertes Verhandlungsergebnis in employee_conversations.salary_result_monthly_gross/salary_result_weekly_hours (der betroffenen Person in der eigenen Historie sichtbar). Löst bei Dokumentation automatisch eine neue payroll_employee_data-Zeile aus.
Werbekosten-Zuordnung — Google-Ads-Suchbegriff-Layer (PROJ-2037)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an einer korrekten, produktgruppenscharfen Werbekosten-Zuordnung für das Kunden-Reporting).
- Roh-Suchbegriffe aus Google Ads (campaign_search_terms): nutzergenerierter Freitext, den Endnutzer in die Google-Suche eingegeben haben — KANN in Einzelfällen personenbezogene Daten enthalten (z.B. Namen/Orte in der Suchanfrage). Gespeichert je Suchbegriff mit Keyword, Anzeigengruppe, Kampagne, Datum, Kosten (Micros), Klicks, Conversions — kein Nutzer-Identifier, keine IP, kein Cookie.
- Zuordnungs-Vorschläge (campaign_search_term_suggestions): normalisierter Begriff, Ebene, vorgeschlagene Produktgruppe, betroffener Spend, Konfidenz, Status — abgeleitete Auswertungsdaten.
Organic Social — Aggregations-Cube & Normalisierung (PROJ-1824)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an datenbasierten Content-Empfehlungen fuer Kundenprojekte).
- Bewertungsfelder am Post (social_post_performance, neue Spalten): Primaer-KPI, Baseline-Wert/-Anzahl/-Fenster, relativer Index (gedeckelt + Rohwert), Bewertungsstatus, Wochentag/Tageszeit-Slot in Account-Zeitzone, Posting-Abstand-Klasse, Zeitzonen-Fallback-Kennzeichen, Bewertungszeitpunkt — abgeleitete Kennzahlen ohne Personenbezug.
- Cube-Zellen (organic_learning_cube_cells): Dimensionskombination, Post-Anzahl, Kundenanzahl, Median-Index, Status, zugrundeliegende Post-IDs, Berechnungszeitstempel — aggregierte Kennzahlen zu Unternehmensbeitraegen, kein Personenbezug. Kein Client-Direktzugriff (RLS ohne Policies + REVOKE), Lesen nur ueber serverseitig gescopte Endpunkte: Kunden-Zellen nur im eigenen Workspace, Branchen-/Portfolio-Zellen nur fuer Agentur-Workspaces (Admin/Manager).
- Schwellen-Konfiguration (organic_normalization_config): Mindest-Posts je Zelle, Mindest-Kunden je aggregierter Zelle, Index-Deckel, Baseline-Fenster (Start/Obergrenze) — je global (workspace_id NULL) oder als Workspace-Override. Reine Konfigurationsdaten.
- Account-Zeitzone (social_accounts.timezone): IANA-Bezeichner des Unternehmens-Accounts (z.B. Europe/Berlin) — technisches Metadatum, kein Personenbezug.
Organic Social — Beitrags-Vorschau auf der Post-Detailseite (PROJ-1901)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an einer verständlichen, im eigenen Produkt nachvollziehbaren Content-Auswertung für Kundenprojekte).
- Einzelne Reaktionszahlen am Post (social_post_performance, neue Spalten likes_count/comments_count/shares_count/slides_count): abgeleitete Anzeigewerte ohne Personenbezug — ein `null`-Wert bedeutet 'Plattform liefert diesen Wert nicht', kein fehlender Datenpunkt.
- Vorschaubild-Kopie (social_post_performance.thumbnail_storage_path, privater Storage-Bucket `social-media`, Pfad {workspace_id}/organic-thumbnails/{social_post_id}.{ext}): 1:1-Kopie des bereits öffentlich auf der Plattform sichtbaren Beitragsbilds. Kein Client-Direktzugriff (privater Bucket, RLS scoped auf Workspace-Mitgliedschaft); Auslieferung an das Frontend ausschließlich über eine kurzlebige signierte URL (5 Minuten), erzeugt serverseitig in der Detail-Route — die dauerhaft gespeicherte Plattform-URL wird nie persistiert oder ausgeliefert.
Organic Social — KI-Insight-Generierung (PROJ-1855)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an verständlichen, datenbasierten Content-Empfehlungen für Kundenprojekte).
- Insight-Texte (organic_social_insights): Insight-Typ, Scope-Ebene (Kunde/Branche/Portfolio), betroffene Dimensionskombination (lesbar + Roh-Schlüssel), referenzierte Cube-Zell-IDs, Datenpunkt-Anzahl, gerundeter relativer Wert, generierter Text, verwendetes Modell, Rangwert, Identitäts-/Inhaltsabdruck-Schlüssel, Status (published/superseded) — aggregierte Kennzahlen zu Unternehmensbeiträgen, kein Personenbezug. Kein Client-Direktzugriff (RLS ohne Policies), Lesen nur über serverseitig gescopte Endpunkte (Kunden-Scope nur eigener Workspace, Branchen-/Portfolio-Scope nur Agentur-Workspaces, Admin/Manager).
- Lauf-Protokoll (organic_social_insight_runs): Start-/Endzeitpunkt, Status, Anzahl geprüft/erzeugt/übersprungen/verworfen je Lauf, Verwurfsgründe — technisches Betriebsprotokoll ohne Personenbezug.
- Erweiterung der Schwellen-Konfiguration (organic_normalization_config): Insight-Schwellenwerte je Typ, Kappungswerte, Modellwahl, Aufbewahrungsfrist für überholte Insights — reine Konfigurationsdaten.
CRM-Ansprechpartner (Grunddaten)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an einer funktionierenden Geschaeftskommunikation mit dem richtigen Ansprechpartner beim Kundenunternehmen).
- Name (Vor-/Nachname, optional Anrede)
- E-Mail-Adresse und Telefonnummern (Festnetz/Mobil)
- Position und Abteilung beim Kundenunternehmen
- Kategorie (z.B. Ansprechpartner, Lead) und Archiv-Status (aktiv/archiviert)
- Erstellungsdatum
Custom-Datenquellen-Framework (PROJ-1600, Push-Adapter PROJ-1563)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an einer eigenen, DSGVO-konformen Reporting-Infrastruktur anstelle von Drittanbieter-Tools) bzw. Art. 6 Abs. 1 lit. b DSGVO im Auftragsverhaeltnis mit dem jeweiligen Kunden fuer konkrete Connectoren.
- Verbindungskonfiguration (custom_data_sources): Name, Adapter-Typ (sql/push), bei SQL Host/Port/Datenbank-Name/Nutzername der externen Quelle, bei Push nur Zieltabellen + erwartetes Sende-Intervall (kein Host/Port/Nutzername, da die Gegenstelle selbst initiiert), Schema-Definition, Sync-Status (inkl. neuem Push-spezifischem Zustand 'stale' = laenger kein Ingest empfangen) — technische Konfigurationsdaten der Agentur/des Kunden-Systems, i.d.R. kein direkter Personenbezug zu Endkunden. Ausnahme fuer Contao-Formular-Quellen (PROJ-2218): dort wird custom_data_sources.name automatisch aus dem CRM-Kundennamen abgeleitet und ist damit eine materialisierte Namens-Kopie (Details im Connector-Eintrag 'Contao-Formularanfragen als Datenquelle').
- Zugangsdaten SQL-Adapter (custom_data_sources.encrypted_credentials): Passwort der externen DB-Verbindung, AES-256-GCM verschluesselt mit eigenem, feature-spezifischem Schluessel; wird ausschliesslich serverseitig fuer den Sync-Vorgang entschluesselt, nie im Klartext an den Client ausgeliefert. Bei Umstellung auf Push wird dieses Feld serverseitig geleert.
- Ingest-Token Push-Adapter (custom_data_source_ingest_tokens, PROJ-1563): SHA-256-Hash eines Zugriffs-Tokens (Klartext wird nie gespeichert, nur einmalig beim Erzeugen/Rotieren im Browser angezeigt), Widerrufs-Zeitpunkt, Zeitpunkt + IP-Adresse + Versionskennung des letzten eingehenden Push. Die IP-Adresse ist die des agentur-/kundeneigenen Reporting-Servers (Server-zu-Server-Kommunikation), nicht die eines Endnutzers.
- Ersteller-/Widerrufer-Referenz (custom_data_sources.created_by; custom_data_source_ingest_tokens.created_by/revoked_by): Verweis auf den anlegenden bzw. widerrufenden Agentur-Mitarbeiter (auth.users, ON DELETE SET NULL bei Mitarbeiter-Loeschung).
- Sync-Protokoll (custom_data_source_sync_logs): Zeitpunkt, Status, Ausloeser (manuell/Cron/Push), Anzahl verarbeiteter Zeilen, sanitisierte Fehlermeldung (Credentials werden vor dem Speichern aus Fehlermeldungen entfernt) — rein technische Protokolldaten, keine Fachdaten-Inhalte.
- Zeitplan-Konfiguration (automation_schedules, PROJ-1919): pro Datenquelle eine Zeile mit Frequenz (aus/stuendlich/taeglich/woechentlich), Uhrzeit im Halbstunden-Raster (Europe/Berlin), Wochentag, Zeitstempel des letzten automatischen Laufs sowie updated_by (auth.users-Referenz des zuletzt aendernden Mitglieds, ON DELETE SET NULL) — Konfigurations- und Betriebsdaten ohne eigenen Verarbeitungszweck. Die Lauf-Historie dieses Moduls bleibt in custom_data_source_sync_logs (keine Doppelbuchung). Workspace-scoped (ON DELETE CASCADE bei Workspace-Loeschung), im DSGVO-Datenexport (Art. 15/20) enthalten.
Contao-Formularanfragen als Datenquelle (PROJ-2165, Connector des Custom-Datenquellen-Frameworks)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO im Auftragsverarbeitungsverhaeltnis mit dem jeweiligen Kunden (Art. 28 DSGVO); die Rechtsgrundlage fuer die urspruengliche Erhebung der Formulardaten verantwortet der Kunde als Website-Betreiber (i.d.R. Art. 6 Abs. 1 lit. a/b DSGVO gegenueber dem Website-Besucher).
- Kontaktdaten der Website-Besucher aus der Formularanfrage (contao_form_submissions): E-Mail-Adresse, Name, Telefonnummer (soweit vom Formular erhoben) — denormalisiert fuer Reporting, gezielte Loeschung und Deduplizierung.
- Vollstaendige Formularfelder (contao_form_submissions.fields, JSONB): alle uebermittelten Formularinhalte verlustfrei (z.B. Nachricht, Betreff, weitere kundenspezifische Felder) — koennen je nach Formular weitere personenbezogene Angaben enthalten.
- Verarbeitungs-Metadaten: Zulieferweg (Webhook/E-Mail/Sheet-Backfill), Formulartyp, Contao-Submission-ID (falls geliefert), Dedup-Schluessel (deterministischer Hash aus Datenquelle/E-Mail bzw. Telefon/Inhalt), Zeitpunkt der Anfrage und der Aufnahme.
- Reject-Protokoll (contao_form_submission_rejects): abgelehnte Eingaenge (kein aufloesbarer Schluessel/leere Felder/Spam) werden mit Ablehnungsgrund protokolliert. Der gespeicherte Auszug (payload_excerpt) enthaelt bewusst NUR Feldnamen und Werttypen, KEINE Rohwerte/Klartext-PII.
- Google-Sheets-Ausgabe-Konfiguration (PROJ-2168): Ausgabe-Ziele (contao_sheet_output_targets: Spreadsheet-/Blatt-Referenz, Feld-zu-Spalten-Mapping, Aktiv-Schalter), Export-Gedaechtnis (contao_sheet_output_exports: nur Submission-/Ziel-ID-Referenzen zur Doppel-Vermeidung) und Lauf-Historie (contao_sheet_output_runs: Status, Zeilenzahlen, Google-API-Fehlertext) — selbst ohne Personenbezug, steuern aber, welche der personenbezogenen Anfragefelder in welches Kunden-Sheet uebermittelt werden.
- Sheet-Backfill-Lauf-Historie (PROJ-2169, contao_sheet_backfill_runs): je ausgefuehrtem Einlese-Lauf ein Datensatz mit auslösendem Agentur-Mitarbeiter (actor_id, ON DELETE SET NULL bei Mitarbeiter-Loeschung — der Lauf-Datensatz bleibt als Audit-Nachweis erhalten), Quell-Snapshot (Spreadsheet-ID/Blatt/Range/tatsaechlich verwendetes Mapping, KEINE Rohwerte der Anfragen selbst), Zeilenzaehlern (gelesen/importiert/angereichert/Duplikat/abgelehnt je Grund) und generischem Fehlertext ohne PII. Selbst ohne Anfrage-Personenbezug, dokumentiert aber wer wann mit welcher Konfiguration den historischen Bestand eingelesen hat (PII-Import-Nachvollziehbarkeit).
- Zwischengespeicherte geparste Formularfelder pro E-Mail-Eingang (PROJ-2217, email_intake_events.parsed_fields, JSONB): fuer den E-Mail-Parser-Zulieferweg werden die vom Parser aus der eingehenden Mail extrahierten Formular-Feld-Keys+Werte (z.B. Name, E-Mail, Nachricht des Anfragenden) an der Log-Zeile der Mail zwischengespeichert — AUSSCHLIESSLICH die geparste Key/Value-Struktur, KEIN Roh-Text/HTML/voller Mail-Body. Zweck: ein Agentur-Admin/Manager kann eine bereits eingegangene Mail zur Kontrolle des Feld-Mappings erneut in den Parser-Editor laden, ohne dass die Roh-Mail vorgehalten wird (bewusste Datenminimierung gegenueber Roh-Mail-Speicherung). Gehaertet beim Schreiben (max. 60 Felder, Key <=128 / Wert <=2000 Zeichen, Gesamt <=64 KB, gefaehrliche Objekt-Keys verworfen). Zugriff strikt agentur-intern (nur aktive admin/manager der Agentur-Seite, nicht Kunden-Workspace-Nutzer); die Listen-Antwort enthaelt nur ein Verfuegbarkeits-Flag, die Werte werden erst on-demand ueber einen separaten autorisierten Detail-Abruf (Cache-Control: no-store) geladen. Fuer Rejects/Fehler (kein Parser-Erfolg) werden KEINE Felder gespeichert.
- Auto-abgeleiteter Datenquellen-Name fuer Contao-Integrationen (PROJ-2218, custom_data_sources.name): fuer Contao-Formular-Quellen wird der Anzeigename automatisch aus dem zugewiesenen CRM-Kunden abgeleitet (Template 'Contao Anfragen | <contact.name>', workspace-gescopt) und bei Umzuordnung/Umbenennung des Kontakts nachgezogen, solange der Name nicht bewusst manuell gesetzt wurde (Flag name_auto_generated). Damit wird custom_data_sources.name zu einer materialisierten Kopie von contacts.name (in diesem CRM strukturell der Firmen-/Kundenname); ein direkter Personenbezug entsteht nur, wenn der Kundenname selbst eine natuerliche Person benennt.
- Konditionale Zuordnungsregeln (PROJ-2266, AP7, contao_form_field_rules): ein Agentur-Admin/Manager kann je Contao-Integration Regeln definieren ('wenn Formularfeld X [enthaelt/ist gleich/passt auf Muster] Y, dann setze Segment/Label Z'), die eingehende Anfragen fachlich kategorisieren. Die Regeln selbst (Quellfeld, Operator, Vergleichswert, Zielwert, Reihenfolge) sind reine Admin-Konfiguration ohne Personenbezug. Das Ergebnis der Auswertung wird an der einzelnen Anfrage als contao_form_submissions.segment_label gespeichert — strukturell IMMER ein vom Admin frei definierter, fester String, NIEMALS eine Kopie/Passthrough des rohen (potenziell PII-tragenden) Quellfeldwerts (eigene Spalte, kein Uebernahme-Mechanismus). Analog dazu email_intake_rules.segment_fallback_label (integrationsweiter Vorbelegungswert, falls keine Regel greift). Das Segment erscheint zusaetzlich automatisch als Dimension im Report-Widget-Picker (Unified Dimensions, PROJ-2170). Seit PROJ-2330 koennen Agentur-Admins/Manager neben der eingebauten, nicht loeschbaren Dimension 'Anfrage-Typ' (segment_label, unveraendert Single-Value) beliebig viele weitere, frei benannte Klassifikations-Dimensionen anlegen (contao_form_dimensions), jede mit eigenem Regel-Satz (contao_form_field_rules.dimension_id) und optional mehrfachwertigem Ergebnis. Die ausgewerteten Werte ALLER Dimensionen einer Anfrage werden zusaetzlich strukturiert in contao_form_submissions.dimension_values (JSONB, Schluessel=Dimensions-Bezeichner, Wert=Liste admin-definierter Zielwerte) gespeichert — dieselbe Personenbezugsfreiheit wie beim bestehenden segment_label (fester, vom Admin definierter String je Treffer, kein Passthrough des rohen Quellfeldwerts), keine zusaetzliche Datenkategorie, nur eine strukturierte Ablage derselben Art von Klassifikations-Entscheidung. Eine rueckwirkende Neuberechnung bestehender Anfragen ist moeglich (Recompute-Funktion); Ausloeser und Zeitpunkt eines manuellen Laufs werden in custom_data_source_sync_logs.triggered_by protokolliert (interne User-Referenz mit ON DELETE SET NULL). Jede Dimension erscheint automatisch als eigene Spalte im Report-Widget-Picker.
- Manuelle Feld-Kalibrierung (PROJ-2272, custom_data_source_field_overrides): ein Agentur-Admin/Manager kann pro Contao-Quelle und Rohfeldname entscheiden, ob das Feld eine Katalog-Dimension ist ('Formularfeld') oder dauerhaft von der Katalog-Erzeugung ausgeschlossen wird ('Kein Formularfeld') — als Override-Schicht ueber der automatischen Impressum-/Signatur-Filterung (PROJ-2271). Die Tabelle enthaelt keine Endnutzer-PII (nur Feldname, Entscheidung, entscheidender Mitarbeiter als interne User-Referenz mit ON DELETE SET NULL, Zeitstempel). Die zugehoerige Kalibrierungs-Ansicht (GET /api/custom-data-sources/:id/field-samples) zeigt die letzten 10 Einsendungen mit ihren Rohfeldern — dieselben Daten, die derselbe Personenkreis (aktive Admin/Manager des Workspace) bereits ueber den Auskunfts-Export der Quelle einsehen kann; keine neue Datenkategorie, kein neuer Empfaengerkreis. Ein manuelles 'Formularfeld'-Override kann den PII-Filter (PROJ-2170, E-Mail/Name/Telefon/Nachricht) NICHT aushebeln — der Endpunkt lehnt solche Aufnahmen ab, der Katalog-Generator erzwingt es zusaetzlich.
- Redigierte Rohmail-Zwischenspeicherung (PROJ-2286, contao_form_submissions.raw_body_redacted): ausschliesslich fuer den E-Mail-Zulieferweg wird zusaetzlich zu den bereits geparsten Formularfeldern eine PII-redigierte Kopie des vollstaendigen Mail-Rohtexts gespeichert (Text bevorzugt, sonst HTML-zu-Klartext) — E-Mail-Adressen, Telefonnummern und offensichtliche Namens-Muster werden VOR dem Speichern automatisch maskiert (redactPii(), Muster-Ersetzung, kein KI-Einsatz). Zweck: ein Agentur-Admin/Manager kann in der Feld-Kalibrierungs-Ansicht nachvollziehen, wie der Parser vom Rohtext zu den extrahierten Feldern kommt, und einen Textabschnitt markieren, um ihn einem eigenen Zielfeld zuzuweisen, wenn der Parser zwei fachlich getrennte Werte faelschlich zu einem Rohfeld zusammengefasst hat (behebt ein anderes Problem als die Feld-Kalibrierung oben). Eine bewusste, ausschliesslich fuer diesen Zweck temporaere Teil-Umkehr der PROJ-2167-Datenminimierungs-Entscheidung ('Roh-Mail wird nicht gespeichert') — begrenzt auf maximal 200.000 Zeichen (dieselbe Kappungsgrenze wie die Formularfeld-Extraktion), eigene 30-Tage-Frist (siehe Aufbewahrung), Zugriff strikt auf aktive Admin/Manager der Agentur-Seite beschraenkt, on-demand geladen (nicht Teil der Listen-Antwort). Split-Regeln (contao_form_field_splits): pro Contao-Quelle definierte Text-Marker-Regeln ('wenn Rohfeld X den Marker Y enthaelt, spalte ab Y in ein neues Feld Z'), wirken quellenweit ab der naechsten eingehenden Mail (nicht rueckwirkend). Die Regeln selbst enthalten keine PII (nur Feldnamen, ein literales Trennzeichen-Textstueck und den entscheidenden Mitarbeiter als interne User-Referenz mit ON DELETE SET NULL) — der eigentliche (redigierte) Anfrage-Inhalt bleibt ausschliesslich in raw_body_redacted.
- UNREDIGIERTE Rohmail-Zwischenspeicherung fuer den Sheet-Export (PROJ-2322, contao_form_submissions.raw_body_unredacted): Geschwisterfeld zu raw_body_redacted (PROJ-2286), ausschliesslich fuer den E-Mail-Zulieferweg befuellt, aber OHNE PII-Maskierung — derselbe bereits extrahierte Rohtext (Text bevorzugt, sonst HTML-zu-Klartext), nur vor statt nach redactPii(). Zweck ist ein STRIKT ANDERER als bei raw_body_redacted: die Google-Sheets-Ausgabe (AP4, PROJ-2168) kann dieses Feld in eine beliebige Ziel-Spalte schreiben, damit die bestehenden, beim Kunden verbleibenden Array-Formeln des abgeloesten Zapier-Workflows (die u.a. Name/E-Mail/Telefon per REGEXEXTRACT aus dem vollen Rohtext extrahieren) unveraendert weiterlaufen — eine redigierte Kopie wuerde hier Platzhalter statt echter Kontaktdaten liefern und die Formeln unbrauchbar machen. Kein eigener Lese-Endpunkt, keine Kalibrierungs-Ansicht, keine UI-Anzeige — striktere Zugriffsbeschraenkung als raw_body_redacted (das noch ueber die Feld-Kalibrierungs-Ansicht einsehbar ist). Der bisherige Zapier-Workflow hat denselben unredigierten Rohtext bereits unbefristet in das kundeneigene Google-Sheet geschrieben; PROJ-2322 verschiebt diesen Schreibschritt lediglich von Zapier nach NeulandOS und verkuerzt die Vorhaltedauer auf der Neuland-Seite auf 30 Tage befristet (der Zapier-Vorgaenger hatte gar keine Loeschfrist). Begrenzt auf maximal 200.000 Zeichen (dieselbe Kappungsgrenze wie raw_body_redacted), eigene 30-Tage-Frist (siehe Aufbewahrung), Zugriff strikt auf aktive Admin/Manager der Agentur-Seite beschraenkt (identische RLS-Policy wie die uebrige Tabelle).
KI-Nutzungs-Kosten-Zuordnung zu CRM-Kontakten (PROJ-1152)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfuellung / Abrechnung — projektgenaue Zuordnung und Weiterberechnung der KI-Nutzungskosten an den beauftragenden Kunden)
- KI-Nutzungsmetriken je Aufruf (ai_token_logs): genutztes Feature/Modell, Token-Verbrauch (prompt/completion/total, Cache-Token), berechnete Kosten, Zeitstempel, Workspace-Bezug
- Zuordnung billable_contact_id: Referenz auf einen CRM-Kontakt (contacts, ON DELETE SET NULL — bei Kontakt-Loeschung bleibt das Kosten-Log erhalten, nur die Zuordnung entfaellt). Indirekter Personenbezug ueber den verknuepften Kontakt; der Kontakt selbst unterliegt dem CRM-Datenschutz-Regime (contacts).
Voice-Diktat-Verlauf (PROJ-379, erweitert PROJ-1871)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Bereitstellung eines Diktier-Verlaufs zur Nachvollziehbarkeit/Wiederverwendung eigener Diktate) i.V.m. Einwilligung/Opt-out-Moeglichkeit ueber profiles.voice_history_enabled
- Diktat-Rohtext (raw_text): woertliche Whisper-Transkription der Spracheingabe des Mitarbeiters — kann betriebsinterne Inhalte, Namen und sonstige personenbezogene Angaben enthalten, je nachdem was diktiert wurde
- Bearbeiteter Diktat-Text (cleaned_text): entweder serverseitig grammatisch bereinigte Version des Rohtexts, oder (seit PROJ-1871, sofern von der App mitgeschickt) der tatsaechlich vom gewaehlten Diktier-Kuerzel erzeugte und eingefuegte Text
- Metadaten: Szenario-/Kuerzel-Name, Aufnahmedauer, Zeitstempel — workspace- und user-gebunden
Cookie-Einwilligung auf CMS-Kundenwebsites und den eigenen Landing Pages (Cookiebar / Consent Operating System)
Rechtsgrundlage: Art. 6 Abs. 1 lit. a DSGVO / § 25 Abs. 1 TDDDG (Einwilligung für nicht-notwendige Cookies/Skripte). IP-Speicherung in consent_records: Art. 6 Abs. 1 lit. c DSGVO (Nachweispflicht Art. 7 Abs. 1 DSGVO). Für die durch die Cookiebar eingebundenen Dritt-Skripte ist der jeweilige Workspace-Betreiber Verantwortlicher; für die eigenen Landing Pages ist NEULAND selbst Verantwortlicher. NEULAND OS stellt das Einwilligungs-Werkzeug für Kunden-Sites als Auftragsverarbeiter bereit (Art. 28 DSGVO).
- Consent-Tool-Konfiguration (cms_cookie_config): aktiviert ja/nein, Geltungsbereich (scope: cms_site/landing_pages/ssot), Banner-Texte, Kategorien, Kanal-Schalter, Sektions-Overrides für das Banner-Design (design_overrides) und die vom Workspace hinterlegten Dritt-Skript-Snippets — Workspace-Konfiguration ohne Besucher-Personenbezug. Seit PROJ-2295 existiert je Workspace zusätzlich eine workspace-weite Standardvorgabe-Zeile (scope='ssot', kein Site-Bezug), von der einzelne Projekte Texte/Design feld- bzw. sektionsweise erben können, solange sie nichts überschreiben — rein technisches Vererbungs-Konzept ohne eigenen Besucher-Personenbezug, ändert nichts an den bereits dokumentierten Datenkategorien. Seit PROJ-2296 zusätzlich die Dienste-Liste (services): pro aktiviertem Dienst Name, Anbieter, Kategorie, Kürzel und die vom Workspace eingetragene Tracking-Kennung (z.B. GA4-Mess-ID, Meta-Pixel-ID) — reine Workspace-Konfigurationsdaten des jeweiligen Drittanbieter-Kontos, kein Personenbezug zu Website-Besuchern. `categories[].scripts[]` wird ab PROJ-2296 serverseitig aus dieser Dienste-Liste über feste Skript-Templates berechnet statt frei eingegeben (bei eigenen, nicht im Katalog geführten Diensten stehen seit PROJ-2341 zwei unabhängige Freitext-Skriptfelder zur Verfügung — eines für den <head>-Bereich und eines vor dem schließenden </body>-Tag —, beide mit demselben admin/manager-Vertrauensmodell wie zuvor).
- Vendor-Katalog (vendor_catalog, PROJ-1287): 10 vorgepflegte Dienste mit Regex-URL und Env-IDs — Workspace-Konfiguration ohne Besucher-Personenbezug
- Bundle-Konfiguration (consent_bundle_config, PROJ-1287): Dual-Bundle-Wechsel (cm-test/ vs. cm/) — Workspace-Konfiguration ohne Besucher-Personenbezug
- Besucher-Einwilligung: clientseitiger Cookie nlcs (Kategorien-Auswahl, seit PROJ-2320 zusätzlich optionale Einzeldienst-Auswahl im Feld svcs, Banner-Version, Zeitstempel) + getrennter Cookie nlcs_vid (anonyme Besucher-UUID)
- Consent-Nachweis (consent_records, PROJ-1287, erweitert PROJ-1904): server-seitiger Nachweis je Einwilligungs-Aktion — anonyme Besucher-UUID, Kategorien, Banner-Version, GPC-Signal, IP-Adresse (90-Tage-Retention), Zeitstempel, Herkunfts-Referenz (config_id, optional), seit PROJ-2320 zusätzlich optionale Pro-Dienst-Zustimmung (services-Feld, Dienst-ID → Boolean)
- Consent-Log (cms_cookie_consent_log, PROJ-1136): älterer server-seitiger Nachweis — Aktion, Kategorien, Banner-Version, Sprache, Zeitstempel. KEIN Besucher-Bezug (keine IP), daher anonym
- Von den eingebundenen Dritt-Skripten ggf. verarbeitete Besucherdaten unterliegen der Verantwortung des Workspace-Betreibers und dessen eigener Datenschutzerklärung
- Banner-Design-Presets (cms_cookie_design_presets, PROJ-2347): workspace-eigene, speicherbare Vorlagen für das Consent-Banner-Design (Layout/Branding/Typografie/Buttons/Chip als vollständiger Design-Satz) — reine Editor-Konfiguration ohne Besucher-Personenbezug, wird vom öffentlichen Banner nie gelesen. Zusätzlich enthält jede Zeile eine interne Ersteller-Referenz (created_by → auth.users) des Agentur-Mitarbeiters, der das Preset angelegt hat. Mitgelieferte, kuratierte Vorlagen liegen dagegen als Code-Konstante (kein DB-Bezug, keine personenbezogenen Daten).
Vorlagenprojekte in Standardvorgaben (PROJ-1718, konsolidiert PROJ-1738)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter Projekt-Bereitstellung durch wiederverwendbare Vorlagen). Keine neue Datenkategorie — alle vier Flags (is_system_contact, is_template, core_override, is_core_template_page) steuern nur Sichtbarkeit/Klassifizierung/Kopierverhalten bestehender, bereits dokumentierter Tabellen (contacts, cms_sites, cms_modules, cms_pages).
- is_system_contact (contacts, boolean): markiert genau einen bestehenden Platzhalter-Kontakt ohne echte Personendaten — kein neues personenbezogenes Datum
- is_template + template_category (cms_sites, boolean/enum): markiert Vorlagenprojekte, kein Personenbezug
- core_override (cms_modules, boolean|NULL): Agentur-Klassifizierung eines Basis-Moduls als Kern/Optional, kein Personenbezug
- is_core_template_page (cms_pages, boolean): markiert Kern-Seiten einer Vorlage für die automatische Übernahme in neue Kundenprojekte, kein Personenbezug
Kundenbewertungen (Bewertungs-Center)
Rechtsgrundlage: Art. 6 Abs. 1 lit. a DSGVO (Einwilligung bei öffentlich abgegebenen Bewertungen über das Formular) bzw. Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse bei manuell erfassten/gespiegelten/öffentlich verfügbaren Bewertungen aus Google Business Profile, Google Places und kununu)
- Name des Bewertenden (optional)
- E-Mail-Adresse des Bewertenden (optional)
- Bewertungstext, Titel, Pro/Contra
- Sternebewertung (1–5)
- Pseudonymisierter IP-Hash (SHA-256) bei Formular-Abgabe zur Spam-Abwehr
- Aus externen Quellen übernommene Bewertungen (Google Business Profile gespiegelt, Google Places, kununu): Name des Bewertenden, Bewertungstext, Sterne, ggf. Inhaber-Antwort
- Cross-Workspace-Lesezugriff (PROJ-1044): Bei bestehender Workspace-Verbindung (workspace_connections, status='active') können berechtigte Agentur-Mitarbeiter die veröffentlichten Bewertungen verbundener Kunden-Workspaces ausschließlich read-only einsehen (Liste + Aggregat/Portfolio, nur Status veröffentlicht — Moderations- und interne Status bleiben dem Kunden-Workspace vorbehalten). Es erfolgt keine eigene Datenspeicherung und keine Kopie im Agentur-Workspace: Der Zugriff ist ein Live-Lesezugriff auf den Eigentümer-Workspace. Export und Löschung der Bewertungen liegen ausschließlich beim Eigentümer-Workspace (siehe Löschkonzept).
- Öffentliche Website-Ausspielung (PROJ-1045): Veröffentlichte Bewertungen (Sterne, Text, Name des Bewertenden, Datum) können über einen CMS-Block auf öffentlichen Websites angezeigt werden — auf der NEULAND-OS-Domain (Vercel) und auf Kunden-Domains (separater Renderer neuland-cms-renderer, Hetzner/EU). Es werden ausschließlich Bewertungen mit Status 'veröffentlicht' und ohne interne Felder (keine E-Mail-Adresse, keine Spam-/Widerrufs-Token) ausgespielt; zusätzlich wird Schema.org-Markup (Bewertungs-Sterne) für Suchmaschinen erzeugt. Rechtsgrundlage: die im öffentlichen Erfassungsformular erteilte Einwilligung deckt die Veröffentlichung inkl. Name ausdrücklich ab (Art. 6 Abs. 1 lit. a); externe Bewertungen sind bereits öffentlich (lit. f). Widerruf entfernt die Bewertung sofort aus der öffentlichen Anzeige.
Google Sheets Datenabgleich & Synchronisation (PROJ-1005, Multi-Verbindung PROJ-1010): manueller Abgleich von Kunden-Tabellenblättern in interne Haupttabellen
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — interne Datenpflege im Rahmen der Agentur-Kunden-Zusammenarbeit)
- Verbindungs-Konfiguration (google_sheets_sync_connections, PROJ-1010/PROJ-1011): Pflicht-Zuordnung zu einem CRM-Kunden (contact_id → contacts, Unternehmen; ON DELETE CASCADE — Kundenlöschung entfernt zugehörige Verbindungen), optionaler Zweck-Freitext (label), Google-Sheets-URL der Kundentabelle, Referenz auf das verwendete Google-OAuth-Token (google_token_id), Zeitstempel des letzten Sync-Laufs (last_sync_at). Bugfix PROJ-1005 (2026-07-06): zwei rein technische Mutex-Lock-Felder (sync_in_progress, sync_lock_at — verhindern parallele Sync-Läufe auf derselben Verbindung, automatische Freigabe nach 10 Minuten) — kein Personenbezug, analog zum bestehenden sync_in_progress/sync_lock_acquired_at-Muster bei shop_drive_sheets (PROJ-743). created_by referenziert den anlegenden Nutzer (auth.users) — indirekter Personenbezug, dient nur der Anzeige (angelegt von), keine Zugriffsbedeutung. Der CRM-Kunde selbst unterliegt dem CRM-Datenschutz-Regime (contacts). Workspace-scoped. Pro Workspace und Kunde mehrere Verbindungen möglich.
- Mapping-Konfiguration (google_sheets_sync_mappings): gehört via connection_id zu einer Verbindung. Name des Kunden-Tabellenblatts, Name des internen Haupt-Tabellenblatts, Name der Join-Key-Spalte, Aktiv-Status, Löschabgleich-Schalter (delete_orphaned_rows, PROJ-1928 — pro Mapping einschaltbar, Standard aus) sowie die zugehörige Notbremsen-Schwelle in Prozent (deletion_guard_percent, 5–100, Standard 20) — reine Konfigurationswerte ohne Personenbezug. Workspace-scoped. Enthält keine Kunden-Tabelleninhalte selbst.
- Sync-Lauf-Protokoll (google_sheets_sync_runs, PROJ-1014): Pro Sync-Lauf werden Metadaten gespeichert — Zeitpunkt, Auslöser-Typ (manuell/automatisch), triggered_by (auth.users-Referenz des auslösenden Mitglieds, indirekter Personenbezug), Status und Ergebnis-Zähler (verarbeitet/aktualisiert/eingefügt/übersprungen/gelöscht — Zähler „gelöscht“ seit PROJ-1928), Warnungen/Fehler als Text. Der Lauf-Eintrag selbst enthält KEINE Kunden-Tabelleninhalte; seit PROJ-1928 werden Inhalte GELÖSCHTER Ziel-Tab-Zeilen jedoch in der separaten Tabelle google_sheets_sync_deleted_rows gesichert (siehe eigener Eintrag unten — Aufbewahrung 90 Tage). Workspace-scoped. Zweck: Nachvollziehbarkeit der Abgleiche.
- Zeitplan-Konfiguration (automation_schedules, PROJ-1919): pro Verbindung eine Zeile mit Frequenz (aus/stündlich/täglich/wöchentlich), Uhrzeit im Halbstunden-Raster (Europe/Berlin), Wochentag, Zeitstempel des letzten automatischen Laufs sowie updated_by (auth.users-Referenz des zuletzt ändernden Mitglieds, SET NULL bei Nutzerlöschung) — Konfigurations- und Betriebsdaten ohne eigenen Verarbeitungszweck. Die Lauf-Historie dieses Moduls bleibt in google_sheets_sync_runs (keine Doppelbuchung). Seit PROJ-1941 führt automation_schedules mit identischen Datenkategorien auch die Zeitpläne des Google-Sheets-Datenimports (je Import-Verbindung eine Zeile; dessen Lauf-Historie bleibt google_sheets_import_runs, die bisherigen Takt-Spalten der Import-Verbindung werden übergangsweise nur noch als Rückfallebene mitgeschrieben und nicht mehr gelesen). Workspace-scoped (CASCADE bei Workspace-Löschung), im DSGVO-Datenexport (Art. 15/20) enthalten.
- Gesicherte gelöschte Zeilen (google_sheets_sync_deleted_rows, PROJ-1928): Ist der Löschabgleich für ein Mapping eingeschaltet, entfernt der Sync Ziel-Tab-Zeilen, deren Vergleichswert im Kunden-Tab nicht mehr vorkommt. Pro gelöschter Zeile wird zur Wiederherstellbarkeit der VOLLSTÄNDIGE Zeileninhalt gesichert (alle Zellwerte der Zeile, Kopfzeile des Ziel-Tabs zum Löschzeitpunkt, Vergleichswert, ursprüngliche Zeilennummer, Bezug zu Lauf/Mapping/Verbindung) — höchstens 500 Zeilen pro Lauf und Mapping, eine Kürzung wird im Report ausgewiesen. Damit werden — anders als beim übrigen Sync-Protokoll — Kunden-Tabelleninhalte gespeichert; Personenbezug nur, falls der Kunde personenbezogene Daten in seinen Tabellen pflegt (z.B. Ansprechpartner-Angaben). Aufbewahrung: 90 Tage ab Löschung, danach automatische Entfernung durch den täglichen Cron google-sheets-deleted-rows-cleanup (fester Systemtakt 04:50 UTC, in der Oberfläche rein lesend sichtbar). Dieser Aufräum-Vorgang protokolliert seit PROJ-1941 jeden Lauf je Workspace mit aktivem Löschabgleich in der gemeinsamen Lauf-Historie (automation_schedule_runs): Status, Zahl der entfernten Einträge, Dauer, ggf. technische Fehlermeldung des Datenbankvorgangs — keine Zeileninhalte und keine Endnutzerdaten. Diese Lauf-Historie wird nach 90 Tagen automatisch gelöscht. Workspace-scoped, Lesen nur für Workspace-Mitglieder (RLS), im DSGVO-Datenexport (Art. 15/20) enthalten.
- Kundendaten aus Google Sheets (transient): Beim Sync werden Tabellenblatt-Inhalte des Kunden gelesen (typischerweise Produkt-/Stammdaten) und in interne Haupttabellenblätter zurückgeschrieben — entweder als Aktualisierung bestehender Zeilen (nur geänderte Zellen, PROJ-1014) oder, falls die Kunden-ID im Haupttabellenblatt noch nicht existiert, als neu angehängte Zeile (Bugfix PROJ-1005, 2026-07-06). Zellwerte werden seit dem Bugfix vom 2026-06-11 1:1 inkl. enthaltenem HTML übernommen (kein Strippen mehr — die Zieltabelle unterstützt HTML-Formatierung). Seit PROJ-1928 kann pro Mapping zusätzlich ein Löschabgleich aktiviert werden: Zeilen des internen Ziel-Tabs, deren Vergleichswert im Kunden-Tab nicht mehr vorkommt, werden physisch gelöscht (mit Notbremse bei ungewöhnlich großem Umfang). Diese Rohdaten werden mit EINER Ausnahme NICHT in NEULAND. OS gespeichert — die Verarbeitung erfolgt im Arbeitsspeicher während des Sync-Laufs; die Ausnahme sind die Inhalte GELÖSCHTER Ziel-Tab-Zeilen, die für 90 Tage in google_sheets_sync_deleted_rows gesichert werden (siehe eigener Eintrag oben). Personenbezug nur, falls der Kunde personenbezogene Daten in seinen Tabellen pflegt (das interne Team trägt Verantwortung für PII-freie bzw. rechtmäßige Inhalte).
- Externer Auftragsverarbeiter: Google LLC (Google Sheets API v4, Lese-/Schreibzugriff via User-OAuth-Token — siehe Auftragsverarbeiter-Eintrag Google LLC). Keine Übermittlung an weitere Dritte.
Potenzialanalyse (PROJ-995): KI-gestützte digitale Potenzialanalyse im Sales-Modul
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur — Erstellung einer digitalen Potenzialanalyse zur Anbahnung und Bewertung einer Kundenzusammenarbeit im Vertriebsprozess)
- Analyse-Stammdaten (potential_analyses): analysierte Domain, Unternehmensname, Hauptthema/Leistung, Branche, Zielregion, B2B/B2C, Zielgruppe, Hauptleistung, Kundenziel. Überwiegend öffentliche Geschäftsdaten; ein Unternehmensname kann bei Einzelunternehmen einen Personenbezug haben
- Wirtschaftsdaten der Analyse: Ø Auftragswert, Anfragequote, Abschlussquote, mögliches Monatsbudget für Ads (kalkulatorische Geschäftskennzahlen, kein direkter Personenbezug)
- Erhobene Analyse-Daten (JSONB): Website-Bewertung (technisch + redaktionell), Keyword-/SERP-/Sichtbarkeitsdaten, gefundene Social-Media-Profil-URLs (inkl. manueller Bestätigung durch den Vertrieb), Local-Daten, 9 Ampeln mit Begründung, KI-Empfehlungen, Gesprächsfragen, Datenquellen-Status
- Externe Auftragsverarbeiter: DataForSEO Ltd. (Keyword-/SERP-/OnPage-Daten + Social-Media-Profilsuche, EU) und Anthropic PBC (KI-Dashboard- und Bewertungsgenerierung, USA — EU-Standardvertragsklauseln). Übermittelt werden ausschließlich öffentliche Domain-/Keyword-/Website-Inhalte, keine Endnutzer-PII
- Interne Notizen (internal_notes): freie Vertriebsnotizen — werden im DSGVO-Datenexport mit ausgegeben, aber NIEMALS in der öffentlichen Kundenansicht (Kundenlink /analyse/:token) ausgeliefert
- Kundenlink-Freigabe: pseudonymer Zugriffstoken (UUID v4), Ablaufdatum (Standard 21 Tage), Freigabe-Status (draft/released/sent). Der token-gated öffentliche Kundenlink ist ohne Login aufrufbar und gibt die Analyse OHNE internal_notes zurück; abgelaufene oder nicht freigegebene Links liefern keine Analysedaten
- Kundenlink-Versand: bei Mail-Versand wird die vom Vertrieb angegebene Empfänger-E-Mail-Adresse via Resend (Auftragsverarbeiter, EU) verarbeitet
Marketing-Landingpage Lead-Formulare (PROJ-976): Potenzialanalyse, Kennenlerngespräch, Fallstudien-Download & Tracking-Integration
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (vorvertragliche Maßnahmen auf Anfrage der betroffenen Person — Anbahnung einer Agentur-Zusammenarbeit) bzw. Art. 6 Abs. 1 lit. a DSGVO (Einwilligung — Fallstudien-Download als Lead-Magnet)
- Lead-Magnet Fallstudien-Download (/fallstudie-anfordern): Name, E-Mail-Adresse, optional Unternehmensname + Einwilligung. Nach Absenden Weiterleitung zur digitalen Fallstudie; Versand einer Bestätigungs-E-Mail mit Fallstudien-Link. Verarbeitung identisch (Deal in Neukunden-Pipeline, leadquelle 'Fallstudie-Download')
- Tracking-Integration-Anfrage (PROJ-1884, /tracking-kostenlos-testen): Name, E-Mail-Adresse und Website-URL des Unternehmens + Einwilligung. Die Website-URL dient ausschließlich als Zielort der angefragten kostenlosen technischen Tracking-Integration (transparent im Formular ausgewiesen); es erfolgt beim Absenden KEIN automatischer Abruf oder eine Prüfung der angegebenen Website — nur eine Format-Validierung der Eingabe. Verarbeitung identisch (Deal in Neukunden-Pipeline, leadquelle 'Tracking-Integration')
- Kontaktdaten der anfragenden Person: Anrede, Name, E-Mail-Adresse, Telefonnummer, bevorzugter Kontaktweg (Online-/Telefontermin)
- Freiwillige Angaben zur Anfrage: ausgewählter Unterstützungs-/Themenbereich, Art der gewünschten Zusammenarbeit, Freitext zur aktuellen Herausforderung (max. 5000 Zeichen)
- Optionaler Datei-Upload (nur Potenzialanalyse): vom Interessenten hochgeladene Dateien (PDF, Bilder, Office-Dokumente, max. 10 MB) im privaten Storage-Bucket lead-attachments, Pfad workspace-präfixiert, Lesezugriff nur für aktive Mitglieder des Agentur-Workspaces (Storage-RLS)
- Verarbeitung: Die Anfrage wird als Deal in der Neukunden-Pipeline (Stage 'Neu') des NEULAND-Agentur-Workspaces angelegt (sales_deals.webhook_payload mit den Formularangaben als Lead-Snapshot) und dem Vertriebsteam zur Validierung angezeigt. Ein CRM-Kontakt wird erst bei manueller Validierung durch den Vertrieb erstellt. Bei technischem Fehlschlag Fallback als staged-Lead (leads-Tabelle)
- Quell-Landingpage (PROJ-1854): der Seitenpfad der Marketing-Seite, von der aus das Formular abgesendet wurde (z.B. /roi-rechner), wird als Quellenangabe mit dem Lead-Datensatz gespeichert (sales_deals.webhook_payload.landing_source) — dient der korrekten CRM-Quellenangabe und der aggregierten Auswertung pro Landingpage (keine personenbezogene Auswertung, Aggregation nur auf Seiten-Ebene)
- Spam-Schutz: IP-Adresse (kurzlebig, als Rate-Limit-Schlüssel, TTL 60 Min.) und verstecktes Honeypot-Feld — keine dauerhafte Speicherung der IP
- Bestätigungs-E-Mail an die anfragende Person via Resend (Auftragsverarbeiter, EU)
Präsentationen-Modul (PROJ-942): KI-Slide-Builder im CRM-Kundenkontext
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Erstellung von Kundenpräsentationen im Rahmen der Agenturleistung)
- Präsentations-Metadaten (presentations): Titel, Vorlagentyp, Marken-Modus, zugeordneter CRM-Kontakt (contact_id), Ersteller, Zeitstempel. Workspace-scoped. Löschung bei Präsentations-/Kontakt-/Workspace-Löschung (CASCADE). Im Datenexport (Art. 15/20 DSGVO) enthalten
- Slide-Inhalte (presentation_slides): KI-generierte und manuell bearbeitete Texte, Layout-Typ, Bild- und Video-Referenzen (content_json). Können Kundenbezug enthalten, wenn der Nutzer Kundendaten ins Briefing oder in Slides einträgt. CASCADE-DELETE bei Präsentations-Löschung
- Video-Referenzen in Slides (PROJ-993): Slides können Videos aus den Markenassets des Kunden einbetten. Gespeichert wird in content_json eine stabile Markenasset-Referenz (brand_asset_id) sowie eine zeitlich befristete signierte URL (24h-TTL). Das Video wird NICHT kopiert, sondern beim Abspielen referenziert: Bei im eigenen brand-assets-Storage abgelegten Videos erfolgt das Streaming aus dem workspace-isolierten Supabase-Storage (EU-Region) — kein Drittanbieter-Kontakt. Verweist die hinterlegte Markenasset-Quelle ausnahmsweise auf eine externe HTTPS-URL (z. B. extern gehostetes Asset), lädt der Browser des Betrachters das Video direkt vom Drittanbieter-Server (IP-Adresse und User-Agent werden dabei übertragen) — analog zum bestehenden Verhalten bei extern gehosteten Bild-Assets. Im PDF-Export wird das Video NICHT eingebettet, sondern durch einen Platzhalter-Hinweis ersetzt (kein Datenfluss). Die Video-Quelldatei selbst ist im Eintrag 'Digitale Medienverwaltung — Markenassets-Bibliothek' dokumentiert. CASCADE-DELETE der Referenz bei Präsentations-Löschung; im Datenexport (Art. 15/20 DSGVO) als Teil von content_json enthalten
- Freitext-Briefing: transient an Anthropic (Claude Sonnet 4.6) zur Slide-Generierung übermittelt (siehe Auftragsverarbeiter Anthropic PBC) — kein Training, keine Persistenz bei Anthropic
- Hochgeladene Slide-Bilder: Storage-Bucket presentations, Pfad {workspace_id}/{presentation_id}/. Workspace-isoliert via Storage-RLS
- Share-Links: optionaler PIN-Schutz (PBKDF2-Hash + Salt, kein Klartext), Ablaufdatum, Aufruf-Zähler. Öffentlich geteilte Decks sind ohne Login abrufbar (bewusste Freigabe durch den Nutzer)
- Element-Standardwerte (presentation_element_defaults, PROJ-971): workspace-weite Typografie-Voreinstellungen pro Element-Typ (Schriftgröße, Schriftfarbe, Zeilenhöhe, Schriftgewicht) sowie pro-Element-Instanzwerte in content_json.extra_blocks[]. Enthält KEINE personenbezogenen Daten — reine Styling-Konfiguration; lediglich updated_by als interner Bearbeiter-Verweis (auth.users). Workspace-scoped, CASCADE-DELETE bei Workspace-Löschung. Die Instanz-Styling-Werte sind als Teil von content_json im Datenexport enthalten
10%-Hebel-Vertriebs-Präsentation (PROJ-1071): Interaktive Hebel-Rechner-Präsentation pro Deal
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Erstellung einer verständlichen Vertriebs-Präsentation zur Anbahnung/Bewertung einer Kundenzusammenarbeit)
- Präsentations-Daten (sales_hebel_presentations): Titel, optionale persönliche Begrüßung (greeting_text — Freitext bis 2.000 Zeichen, kann PII wie Empfängername/Anrede enthalten), an den Deal (sales_deals) und optional an einen CRM-Kontakt (contacts) gebunden, Ersteller, Zeitstempel, Status (draft/shared/archived). Workspace-scoped via RLS. Der feste Inhalt der 5 Hebel steht im Code (hebel-content.ts), nicht in der Datenbank
- Kundenzahlen (visitors_per_month, inquiry_rate_percent, close_rate_percent, avg_order_value_eur): greifbare Geschäftskennzahlen des Kunden für den Rechner — in der Regel keine personenbezogenen Daten (Unternehmenskennzahlen). Alle optional; bei leeren Werten greifen generische Beispielzahlen
- Share-Links: optionaler PIN-Schutz (PBKDF2-Hash + Salt, kein Klartext), optionales Ablaufdatum, Link aktivierbar/sperrbar (share_is_active), anonymer Aufruf-Zähler (view_count — keine IP-Speicherung). Öffentlich geteilte Präsentationen sind ohne Login über einen nicht erratbaren UUID-Token (/hebel/[token]) abrufbar — bewusste Freigabe durch den Vertrieb, der den Link aktiv an den Kunden übermittelt. Ohne gültige PIN-Sitzung liefert der öffentliche Endpunkt nur Titel und needs_pin (Datensparsamkeit); keine Kundenzahlen/Begrüßung
- IP-Adresse (Rate Limiting): Beim öffentlichen Abruf und bei PIN-Versuchen wird die IP-Adresse temporär für Rate Limiting genutzt (nicht in der Datenbank gespeichert). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (Missbrauchsschutz)
- Aufruf-Benachrichtigung (hebel_presentation_viewed): Öffnet der Kunde den geteilten Link, wird der Deal-Owner intern benachrichtigt (max. 1×/Stunde gedrosselt). Die Benachrichtigung enthält Präsentations-Titel und Deal-Bezug, keine Besucher-IP. Aufbewahrung: Standard-Notification-Retention
- Kein externer Auftragsverarbeiter und kein KI-Einsatz: Rechner-Berechnung erfolgt rein clientseitig; es werden keine Daten an Drittanbieter oder außerhalb der EU übermittelt (keine DSFA nach Art. 35 erforderlich — nur einfacher Aufruf-Zähler, keine systematische Überwachung oder besondere Datenkategorien)
Authentifizierung & Login
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
- E-Mail-Adresse
- Name
- Passwort (gehashter Wert)
- OAuth-Token (verschlüsselt)
Workspace- & Teamverwaltung
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
- Workspace-Name
- Mitglieder-Zuordnung
- Rollen und Berechtigungen
- Avatar-Bild
- Einstellungsdatum (für Dienstjubiläum-Berechnung und Lohnvorbereitung)
- Jubiläumsbenachrichtigungen (Name des Jubilars, Jubiläumsstufe, Datum — automatische Inbox-Benachrichtigungen an Admins, den Jubilar und das Team bei Meilenstein-Jubiläen)
- Wochenkapazität (weekly_capacity): Wöchentliche Arbeitszeitkapazität eines Mitglieds in Stunden (Standard: 20 Stunden). Wird für abteilungsbasierte Angebotsplanung verwendet — Abteilungskapazität = Summe aller aktiven Mitglieder der Abteilung. Kein sensitives PII. Löschung bei Workspace-Mitglied-Löschung (CASCADE)
- Verantwortungsebene (responsibility_level): HR-Klassifikation der Verantwortungs-Dimension eines Mitglieds (4 Stufen: Umsetzung, Fachverantwortung, Teamverantwortung, Unternehmensverantwortung). Optional (nullable). Wird nur in Agentur-Workspaces verwendet als einheitliche Klassifizierungsbasis für VSOP-Beteiligungs-Zuteilung, Reports und Kapazitätsplanung. Sichtbar ausschließlich für Workspace-Admins sowie für den Mitarbeiter selbst (read-only auf dem eigenen Profil). Setzung ausschließlich durch Admins. Löschung bei Workspace-Mitglied-Löschung (CASCADE). Im Datenexport (Art. 15/20 DSGVO) enthalten
- Unternehmerische Haltung (entrepreneurial_attitude): Engagement-/Mindset-Klassifikation eines Mitglieds (4 Stufen: Erfüller, Engagiert, Mitdenker, Mitunternehmer). Optional (nullable). Subjektive Einstufung durch die Geschäftsführung — wird in Agentur-Workspaces als zusätzlicher Faktor für VSOP-Beteiligungs-Zuteilung verwendet (belohnt unternehmerisches Denken und Engagement über die Vertragspflicht hinaus). Sichtbar ausschließlich für Workspace-Admins sowie für den Mitarbeiter selbst (read-only). Setzung ausschließlich durch Admins. Löschung bei Workspace-Mitglied-Löschung (CASCADE). Im Datenexport (Art. 15/20 DSGVO) enthalten
- Jährlicher Urlaubsanspruch (annual_leave_quota): Anzahl der jährlich verfügbaren Urlaubstage pro Mitglied (Standard: 30). Wird im Mitarbeiter-Cockpit zur Berechnung von genommenen, geplanten und verfügbaren Urlaubstagen verwendet. Setzung ausschließlich durch Admins im Mitglied-Bearbeiten-Sheet. Löschung bei Workspace-Mitglied-Löschung (CASCADE). Im Datenexport (Art. 15/20 DSGVO) enthalten
- Probezeit in Monaten (probationary_period_months): Vertragliche Probezeit des Mitglieds in Monaten (0 = keine Probezeit). Optional (nullable). Rechtsgrundlage: §26 BDSG (Beschäftigtendatenschutz, Vertragsabwicklung). Sichtbar und bearbeitbar ausschließlich für Workspace-Admins. Löschung bei Workspace-Mitglied-Löschung (CASCADE). Im Datenexport (Art. 15/20 DSGVO) enthalten
- Kündigungsfrist (notice_period): Vertragliche oder gesetzliche Kündigungsfrist als Freitext (max. 100 Zeichen). Optional (nullable). Rechtsgrundlage: §26 BDSG. Sichtbar und bearbeitbar ausschließlich für Workspace-Admins. Löschung bei Workspace-Mitglied-Löschung (CASCADE). Im Datenexport (Art. 15/20 DSGVO) enthalten
- Arbeitsort (work_location): Vertraglich vereinbarter oder tatsächlicher Arbeitsort des Mitglieds (Freitext, z.B. 'Köln', 'Remote', 'Hybrid'). Optional (nullable). Rechtsgrundlage: §26 BDSG. Sichtbar für alle Workspace-Mitglieder (read), bearbeitbar ausschließlich durch Admins. Löschung bei Workspace-Mitglied-Löschung (CASCADE). Im Datenexport (Art. 15/20 DSGVO) enthalten
- Heute-wichtig E-Mail-Schwellenwert (workspaces.heute_wichtig_email_threshold_hours, PROJ-733/PROJ-1142): Workspace-weite Schwellenwert-Konfiguration in Stunden (Integer, Default 24 seit PROJ-1142, vorher 4, Bereich 1..168), ab dem eine unbeantwortete Kunden-Mail im Bereich 'Heute wichtig' als priorisierte Maßnahme erscheint. Konfigurierbar in den Einstellungen unter Heute wichtig → Signale (Admins/Manager). Reines Konfigurations-Setting ohne Personenbezug. Wirkt rückwirkend auf alle bestehenden Mails des Workspaces. Setzung ausschließlich durch Admins/Manager. Löschung bei Workspace-Löschung (CASCADE). Im Datenexport (Art. 15/20 DSGVO) als Teil der Workspace-Settings enthalten
Mitarbeiter-Cockpit (PROJ-372): Urlaubsanträge, Krankmeldungen, Lohndokumente
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsdurchführung Arbeitsverhältnis), Art. 6 Abs. 1 lit. c DSGVO i.V.m. §147 AO (gesetzliche Aufbewahrungspflicht für Lohndokumente), §26 BDSG (Beschäftigtendatenschutz)
- Urlaubsanträge (leave_requests, type='urlaub'): Antragsteller (user_id), Zeitraum (start_date, end_date), Vertreter (deputy_user_id), Status (eingereicht/in_pruefung/genehmigt/abgelehnt/zurueckgezogen), Genehmiger (approved_by), Genehmigungs-/Ablehnungsdatum, Ablehnungsgrund (Freitext, falls vorhanden). Sichtbarkeit: Antragsteller selbst sowie Mitglieder von Abteilungen mit Genehmigungs-Berechtigung (departments.can_approve_leave=true) — Bugfix 25.08.2026: Workspace-Rolle Admin/Manager gewährt seit PROJ-2318-Nachtrag KEINE automatische Sichtbarkeit mehr, ausschließlich das Abteilungs-Flag entscheidet. Aufbewahrung: bis zu 3 Jahre nach Antragsstellung gemäß Aufbewahrungspflichten für Arbeitszeit-Nachweise (§16 Abs. 2 ArbZG). Löschung bei Workspace-Mitglied-Löschung (CASCADE). Im Datenexport (Art. 15/20 DSGVO) enthalten
- Workation-Anträge (leave_requests, type='workation'): Zusätzlich zu Urlaubsdaten: Zielort (Land + Stadt als Freitext), Erreichbarkeits-Modus (standard/zeitverschiebung), bei Zeitverschiebung Erreichbarkeits-Zeitfenster (Von/Bis-Uhrzeit), Bestätigung über Technik-Voraussetzungen (Boolean). Workation-Tage werden NICHT vom Urlaubskonto abgezogen — gelten arbeitsrechtlich als Arbeitszeit von einem anderen Ort. Aufbewahrung und Löschung wie Urlaubsanträge
- Abwesenheiten-Kalender Self-Service (absences, 8 Typen seit PROJ-2248: Urlaub, Sonderurlaub, Elternzeit, Krankheit, Pflegeurlaub, Feiertag, Sonstiges, Fortbildung): Werden über das Cockpit als Self-Service eingetragen (kein Genehmigungs-Workflow). Antragsteller (user_id), Abwesenheitstyp, Zeitraum (start_date, end_date), optionale diskrete Notiz (Freitext, sichtbar nur für Genehmiger/Lohnbuchhaltung). Bei type='krankheit' werden KEINE Diagnosen, Krankheitsbilder oder ärztliche Bescheinigungen gespeichert — nur die Kategorie selbst. Sichtbarkeit des Typs + Zeitraums (ohne Notiz): alle Workspace-Mitglieder im Team-Kalender (Team → Abwesenheiten), analog dem bestehenden Avatar-Status 'Im Urlaub' — berechtigtes Interesse an Team-Koordination (Art. 6 Abs. 1 lit. f DSGVO). Seit PROJ-2248 sind die Typen Elternzeit und Pflegeurlaub granularer benannt als zuvor (früher unter der Sammelkategorie 'Sonstiges' erfasst) — der Sichtbarkeits-Umfang selbst ist unverändert, nur die Aussagekraft der Kategorie-Bezeichnung ist gestiegen. Aufbewahrung: 3 Jahre für die Lohnabrechnung. Löschung bei Workspace-Mitglied-Löschung (CASCADE)
- Browser-localStorage (Zeitraum-Umschalter Abwesenheiten-Kalender, PROJ-2243, kein Server-Speicher): Schlüssel neuland_absence_calendar_view_mode speichert rein clientseitig, ob der Team → Abwesenheiten-Kalender zuletzt in Monats-, Quartals- oder Jahresansicht angezeigt wurde (nicht der navigierte Zeitpunkt selbst). Kein Personenbezug (reiner Anzeige-Modus-String), nach §25 Abs. 2 Nr. 2 TDDDG technisch unbedingt erforderlich (keine Einwilligung nötig, analog Theme-/Ansichts-Präferenzen anderer Module)
- Avatar-Status 'Im Urlaub' (profiles.availability_status='on_vacation' + profiles.vacation_end_date): Wird automatisch durch Cron-Jobs (06:00 + 23:00 Uhr Europa-Zeit) gesetzt sobald ein genehmigter Urlaubsantrag aktiv ist. Sichtbarkeit: Alle Workspace-Mitglieder (zur Team-Koordination), zusätzlich für verbundene Kunden im Kunden-Portal (zeigt Verfügbarkeit des Ansprechpartners). Wird nach Urlaubsende automatisch zurückgesetzt auf 'verfügbar'. Berechtigtes Interesse (Art. 6 Abs. 1 lit. f DSGVO) — Widerspruchsrecht über profiles.presence_visible-Toggle (PROJ-115)
- Lohnabrechnungen, Lohnsteuerbescheinigungen, SV-Nachweise (payroll_documents): Hochgeladene PDF-Dateien mit Metadaten (Jahr, Monat, Dokumenttyp). Sichtbarkeit ausschließlich für: (1) den jeweiligen Mitarbeiter (RLS auf user_id=auth.uid()), (2) Workspace-Admins, (3) Mitglieder von Abteilungen mit Lohnbuchhaltungs-Berechtigung (departments.can_approve_leave=true), (4) den hochladenden Steuerberater im Steuerberater-Workspace (über workspace_connections-Verknüpfung). Speicherung: Privater Supabase Storage Bucket 'payroll-documents' mit Verschlüsselung at-rest, RLS-Folder-Scoping ({workspace_id}/{user_id}/), Zugriff ausschließlich über zeitbegrenzte signierte URLs (1 Stunde Gültigkeit). Aufbewahrung: 10 Jahre gemäß §147 AO (steuerliche Aufbewahrungspflicht für Lohndokumente). Löschung: Mitarbeiter selbst kann nicht löschen (gesetzliche Aufbewahrung), Admin/Uploader kann manuell löschen. DB-Eintrag wird bei Workspace-Mitglied-Löschung via CASCADE entfernt; Storage-Datei wird durch separaten Cleanup-Cron entfernt (in Vorbereitung). Metadaten (ohne Datei-Inhalt) im Datenexport (Art. 15/20 DSGVO) enthalten
- Vertretungs-Beziehungen (leave_requests.deputy_user_id): Verweis auf den vom Antragsteller gewählten Vertreter während des Urlaubs. Optional. Sichtbar für Genehmiger und Workspace-Mitglieder mit Antragszugriff. Löschung bei Workspace-Mitglied-Löschung (SET NULL)
- Genehmigungs-Berechtigung pro Abteilung (departments.can_approve_leave): Konfigurations-Flag (Boolean, Standard: false). Setzung ausschließlich durch Admins im Abteilung-Bearbeiten-Dialog. Mitglieder einer Abteilung mit aktivem Flag erhalten Lese-/Schreibrechte auf alle Urlaubsanträge des Workspaces (typischerweise für Lohnbuchhaltung). Im Datenexport (Art. 15/20 DSGVO) enthalten
- Steuerberater Cross-Workspace-Upload: Wenn ein Steuerberater-Workspace mit dem Agentur-Workspace verbunden ist (workspace_connections), kann der Steuerberater Lohnabrechnungen direkt für Mitarbeiter der Agentur hochladen. Voraussetzung: Beide Workspaces sind in workspace_connections mit status='connected' verknüpft. Der hochladende Workspace wird in payroll_documents.uploaded_via_workspace_id gespeichert. Hinweis: Zwischen Agentur und Steuerberater MUSS ein Auftragsverarbeitungsvertrag (AVV) gemäß Art. 28 DSGVO bestehen — diese Verknüpfung ist arbeitsrechtlich als Auftragsverarbeitung zu werten
Gesellschafterkonto (PROJ-438): Internes Bewegungs-Logbuch für Privatentnahmen/-einlagen
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an sauberer Gesellschafterbuchführung) i.V.m. Gesellschaftsvertrag bzw. Satzung. §26 BDSG (Beschäftigtendatenschutz, soweit einzelne Gesellschafter zugleich Mitarbeitende sind)
- Gesellschafter-Kennzeichnung (workspace_members.is_shareholder): Boolean-Flag auf dem Workspace-Mitglied. Ausschließlich durch Platform-Admins setzbar (nicht durch Workspace-Admins). Steuert die Sichtbarkeit des Gesellschafterkonto-Tabs und den Zugriff (SELECT/INSERT/UPDATE/DELETE via RLS) auf die shareholder_transactions-Tabelle. Nur in Agency-Workspaces wirksam — andere Workspace-Typen sehen das Feature nicht. Im Datenexport (Art. 15/20 DSGVO) für den betroffenen User enthalten
- Bewegungs-Einträge (shareholder_transactions): Pro Eintrag werden gespeichert: der zugeordnete Gesellschafter (user_id, verweist auf auth.users), das Datum der Bewegung (transaction_date), der Betrag in Cent (amount_cents, immer positiv), die Richtung (direction: 'einlage' oder 'entnahme'), eine optionale Freitext-Kategorie/Bezeichnung (category, max. 100 Zeichen) und eine optionale Freitext-Notiz (notes, max. 500 Zeichen). Zusätzlich werden Zeitstempel (created_at, updated_at) sowie der anlegende (created_by) und zuletzt bearbeitende User (updated_by) gespeichert
- Sichtbarkeit: Die Einträge sind ausschließlich für aktive Workspace-Mitglieder sichtbar, die als Gesellschafter gekennzeichnet sind (is_shareholder = true). Alle gekennzeichneten Gesellschafter sehen alle Einträge des Workspace (Transparenzmodell). Workspace-Admins ohne Gesellschafter-Flag haben keinen Zugriff, ebenso wenig Platform-Admins ohne eigenes Gesellschafter-Flag (keine privilegierte Einsicht aus Datenschutzgründen)
- Bearbeitung/Löschung: Jeder Gesellschafter kann ausschließlich seine eigenen Einträge erstellen, bearbeiten oder löschen (RLS-Guard auf created_by = auth.uid()). Kein Genehmigungs-Workflow, keine Unveränderbarkeit (keine GoBD-Konformität angestrebt) — dieses Register ist ein internes Logbuch, kein ordnungsgemäßes Buchhaltungswerk im Sinne des HGB. Der primäre Beleg (z. B. Bankauszug) bleibt die Wahrheit; dieses Logbuch ist Dokumentations-Hilfe
- Aufbewahrung: Einträge werden unbefristet aufbewahrt, solange der Workspace besteht. Beim Löschen des Workspace werden alle Einträge über CASCADE gelöscht. Bei Account-Löschung des erfassenden Gesellschafters (Art. 17 DSGVO) werden die Einträge NICHT automatisch gelöscht (geschäftliche Eigendokumentation), die Personen-Referenzen user_id, created_by und updated_by werden jedoch über ON DELETE SET NULL auf NULL gesetzt. Der Eintrag erscheint in der UI dann als ‚Ehemaliger/Gelöschter Gesellschafter'
- Datenexport (Art. 15/20 DSGVO): Der anfragende User erhält ausschließlich seine eigenen Bewegungen im Export (Datenminimierung gegenüber Mit-Gesellschaftern). Einträge anderer Gesellschafter werden nicht mit exportiert, selbst wenn sie im Feature für den User sichtbar sind
- Empfänger: Ausschließlich gekennzeichnete Gesellschafter desselben Agency-Workspaces. Keine Übermittlung an Steuerberater-Workspaces, keine DATEV-Exports, keine externen Drittanbieter. Kein Zugriff für verbundene Kunden-, Partner- oder Affiliate-Workspaces
Gesellschaftsverwaltung (PROJ-739): Stammdaten-Registry der eigenen Unternehmensgruppe
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Unternehmensgruppe an zentraler Stammdatenverwaltung der eigenen Gesellschaften) i.V.m. Art. 6 Abs. 1 lit. c DSGVO (§14 UStG für USt-ID/Steuernummer-Speicherung, §147 AO für 10-Jahres-Aufbewahrung steuerlicher Stammdaten)
- Stammdaten (companies): Pro Gesellschaft werden gespeichert: Name (Pflicht), Rechtsform (GmbH/UG/GbR/AG/Einzelunternehmen/Sonstige), Branche (Agentur/E-Commerce/Holding/Immobilien/Dienstleistung/Sonstige), optional Gründungsdatum, HRB-Nummer, Steuernummer, USt-ID (Format DE + 9 Ziffern), IBAN, EBITDA-Multiple-Faktor (für interne Bewertungs-Schätzungen), SKR-Kontenplan (SKR03/SKR04). Zusätzlich Zeitstempel (created_at, updated_at) und Soft-Delete-Flag (is_archived). Workspace-scoped (workspace_id FK → workspaces, ON DELETE CASCADE).
- Einzelunternehmen-Sonderfall (rechtsform = Einzelunternehmen): Bei diesem Rechtsform-Wert sind die gespeicherten Daten personenbezogen im Sinne des Art. 4 Nr. 1 DSGVO, da Einzelunternehmer als natürliche Personen auftreten. Der Firmenname enthält dann den Klarnamen des Inhabers, die Steuernummer ist die persönliche Steuernummer, die IBAN potenziell ein Privatkonto. Bei GmbH/UG/AG/GbR sind die Daten reine Unternehmensdaten juristischer Personen — DSGVO greift hier nicht.
- Steuerberater-Zuordnung (tax_advisor_workspace_id): Optionale FK auf einen verknüpften Steuerberater-Workspace (workspace.type = ‚tax_advisor', siehe PROJ-56). Dient der Zuordnung zur fachlich zuständigen Steuerkanzlei. Bei Löschung des Steuerberater-Workspace: ON DELETE SET NULL (Gesellschaft bleibt erhalten, Zuordnung wird entfernt).
- Workspace-Verknüpfungen (company_workspace_links): Junction-Tabelle für die N:M-Zuordnung von Workspaces zu Gesellschaften. Pro Verknüpfung werden gespeichert: company_id (FK → companies, CASCADE), workspace_id (FK → workspaces, CASCADE), created_at. UNIQUE-Constraint auf workspace_id stellt sicher, dass jeder Workspace maximal einer Gesellschaft zugeordnet ist. Diese Verknüpfung steuert ausschließlich die Sichtbarkeit von Gesellschaftsdaten — keine Berechtigungs- oder Workflow-Wirkung.
- Sichtbarkeit & Bearbeitung: Alle aktiven Workspace-Mitglieder können Gesellschaften lesen (RLS-SELECT). Nur Workspace-Admins können anlegen, bearbeiten oder archivieren (RLS-INSERT/UPDATE auf role = ‚admin'). Kein Hard-Delete via UI — Archivierung über is_archived = true (Soft-Delete). Hard-Delete via SQL ist möglich, ist aber explizit nicht als UI-Funktion vorgesehen.
- Aufbewahrung: Solange Gesellschaft aktiv (is_archived = false). Nach Archivierung 10 Jahre Aufbewahrung gemäß §147 AO (Steuerunterlagen-Aufbewahrungspflicht). Bei Löschung des Workspace werden alle zugehörigen companies + company_workspace_links über CASCADE-DELETE entfernt.
- Datenexport (Art. 15/20 DSGVO): Workspace-Admins können alle eigenen Gesellschaftsdaten + Workspace-Verknüpfungen über `GET /api/workspaces/data-export` im JSON-Format abrufen.
- Empfänger: Ausschließlich Mitglieder des owning Workspaces und ggf. der zugeordneten Steuerberater-Workspaces (über die etablierte Steuerberater-Connection, PROJ-56). Keine externen Drittanbieter, keine Übermittlung außerhalb der EU.
Finanzdaten-Import (PROJ-740): BWA, Summen-Saldenliste, GuV und Bilanz als CSV/Excel/XBRL hochladen und konto-granular speichern
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Unternehmensgruppe an zentraler Finanzdaten-Verwaltung und Management-Reporting) i.V.m. Art. 6 Abs. 1 lit. c DSGVO (§147 AO — Aufbewahrungspflicht handels- und steuerrechtlich relevanter Unterlagen 10 Jahre)
- Import-Metadaten (financial_imports): Pro Upload werden gespeichert: Gesellschafts-ID (FK company_id → companies, CASCADE), Import-Typ (bwa/summen_saldenliste/guv/bilanz), Perioden-Jahr und optionaler Perioden-Monat (1-12), Datei-Format (csv/xlsx/xls/xbrl), Storage-Pfad der Originaldatei im Bucket financial-imports, Upload-User-ID (FK uploaded_by_user_id → auth.users, FK uploaded_by_workspace_id → workspaces), Status (imported/replaced/failed) mit optionaler Fehlermeldung, FK auf ersetzten Vorgänger-Import (replaced_import_id, Self-Reference), JSONB-Summary mit Plausibilitäts-KPIs (Gesamtumsatz, Gesamtkosten, Positionsanzahl, etc.). UNIQUE-Constraint auf (company_id, import_type, period_year, period_month) WHERE status = imported — verhindert Duplikate für aktive Imports. Workspace-scoped indirekt über company_id (Gesellschaft gehört zu Workspace). CASCADE-DELETE bei Gesellschafts-Löschung.
- Konto-Einträge (financial_data_entries): Pro Konto und Periode eine Zeile. Gespeicherte Felder: import_id (FK → financial_imports, CASCADE), company_id (FK → companies, CASCADE, denormalisiert für Query-Performance), period_year, period_month (NULL bei guv/bilanz), account_number (z.B. 8400 SKR04 Erlöse), account_name, account_category (revenue/material_cost/personnel_cost/depreciation/other_cost/equity/assets/liabilities/other — auto-klassifiziert aus SKR-Kontonummer-Bereich), amount_cents (Betrag in Cent, signed), skr_variant (skr03/skr04). Keine personenbezogenen Daten im Regelfall — reiner Unternehmens-Finanzdatensatz. Sonderfall Einzelunternehmen: siehe PROJ-739 Einzelunternehmen-Hinweis — Umsätze und Aufwände können bei Einzelunternehmen transitiv auf die natürliche Person bezogen werden. CASCADE-DELETE bei Import-Löschung oder Gesellschafts-Löschung.
- Spalten-Mapping-Profile (financial_import_mappings): Gespeicherte Konfiguration für die Zuordnung von Datei-Spalten zu internen Feldern (z.B. Konto-Nr. → account_number). Felder: company_id (FK → companies, CASCADE), import_type, file_format, mapping_rules (JSONB {Spaltenname: internes_Feld}), decimal_separator (comma/dot). UNIQUE auf (company_id, import_type, file_format) — ein Profil pro Gesellschaft + Typ + Format. Enthält keine personenbezogenen Daten — nur technische Spalten-Konfiguration. CASCADE-DELETE bei Gesellschafts-Löschung.
- Originaldateien im Storage-Bucket financial-imports: Originale CSV/Excel/XBRL-Dateien werden im privaten Supabase-Storage-Bucket abgelegt. Pfad-Konvention: {workspace_id}/{company_id}/{import_id}/{filename}. Signed URLs für Direktdownload. Dateigröße max. 10 MB. Erlaubte MIME-Types: text/csv, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/xml, text/xml. Aufbewahrung analog financial_imports (§147 AO 10 Jahre). Löschung bei Import-Löschung (manuell oder via Workspace-CASCADE).
- Steuerberater-Zugriff: Steuerberater-Workspaces (workspace.type = tax_advisor, PROJ-56) mit aktiver Zuordnung (companies.tax_advisor_workspace_id = steuerberater_workspace_id) können Finanzdaten für ihre zugeordneten Gesellschaften hochladen (POST /preview + /confirm). Beim Upload durch den Steuerberater wird uploaded_by_workspace_id auf die Steuerberater-Workspace-ID gesetzt. Ein erfolgreicher Steuerberater-Upload löst eine financial_data_uploaded-Inbox-Notification für alle Admins des Haupt-Workspaces der Gesellschaft aus. Rechtsgrundlage für den Datenaustausch zwischen Agentur und Steuerberater: Art. 6 Abs. 1 lit. f DSGVO in Verbindung mit dem bestehenden Steuerberatungsauftrag.
- Sichtbarkeit & Bearbeitung: Alle aktiven Workspace-Mitglieder können Import-Liste und Konto-Details lesen (Member-Lese-RLS). Import-Erstellen und -Bestätigen: Admins des Haupt-Workspaces oder Steuerberater-Workspace-Member mit aktiver Zuordnung. Import-Löschen: ausschließlich Admins des Haupt-Workspaces. Mapping-Profile schreiben: ausschließlich Admins. Konto-Einträge-Insert ausschließlich via Backend-Service-Role beim Confirm-Schritt — kein direkter Client-Insert.
- Aufbewahrung: §147 AO — handels- und steuerrechtliche Unterlagen 10 Jahre. Nach Workspace-Löschung werden alle financial_imports + financial_data_entries + financial_import_mappings über CASCADE-DELETE entfernt.
- Datenexport (Art. 15/20 DSGVO): Workspace-Admins können alle Finanzdaten ihrer Gesellschaften über GET /api/workspaces/data-export im JSON-Format abrufen (financial_imports, financial_data_entries, financial_import_mappings). Originaldateien im Storage-Bucket sind separater Bestandteil und über signierte Download-URLs zugänglich.
- Empfänger: Ausschließlich Mitglieder des owning Workspace und ggf. des zugeordneten Steuerberater-Workspace (PROJ-56 Verbindung). Keine Übermittlung an externe Drittanbieter — kein KI-Einsatz, keine externen API-Aufrufe bei der Dateiverarbeitung (DATEV/Addison-API wird nicht aufgerufen; Daten werden lokal geparst).
Abrechnungs-Empfänger-Verwaltung & Kostenstellen (PROJ-492 + PROJ-543 + PROJ-545): Multi-Empfänger für Rechnungen und Mahnungen mit N Kostenstellen-Anschriften pro Empfänger
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — korrekte Zustellung von Rechnungen und Mahnungen an die vom Kunden benannten Abrechnungs-Adressen sowie korrekte Rechnungslegung an die jeweilige Kostenstelle/Tochtergesellschaft)
- Abrechnungs-Empfänger (billing_recipients, PROJ-492): Pro Firmenkontakt beliebig viele E-Mail-Empfänger hinterlegbar, getrennt nach Zweck (is_invoice_recipient und is_reminder_recipient). Gespeicherte Felder: E-Mail-Adresse (max. 320 Zeichen, RFC-5321), optionales Freitext-Label (max. 100 Zeichen), Zweck-Flags, Sortier-Reihenfolge, Zeitstempel und anlegender User. Sichtbarkeit: alle aktiven Workspace-Mitglieder (read), Bearbeitung/Löschung ausschließlich durch Admins und Manager. Löschung: CASCADE bei Löschung des Firmenkontakts oder Workspace. Im Datenexport (Art. 15/20 DSGVO) enthalten. Kein externer Empfänger — E-Mails werden beim konkreten Rechnungsversand genutzt (siehe Resend-Eintrag).
- Kostenstellen-Anschriften (billing_addresses, PROJ-543 + PROJ-545): Pro Versand-Empfänger (billing_recipient_id FK) beliebig viele Rechnungsanschriften (1:N). Gespeicherte Felder: recipient_name (max. 200 Zeichen), street (max. 200 Zeichen, Pflicht), zip (max. 20 Zeichen), city (max. 100 Zeichen), country (max. 2 Zeichen ISO-Code, Default DE), vat_id (max. 50 Zeichen, USt-IdNr), is_default (Boolean, bevorzugte Kostenstelle pro Empfänger), sort_order, Zeitstempel. PROJ-545 (2026-05-04): Anschriftsfelder aus billing_recipients in eigenständige Tabelle billing_addresses verschoben um N Anschriften pro E-Mail-Empfänger zu ermöglichen. Sichtbarkeit + Bearbeitungsrechte analog billing_recipients. Löschung: CASCADE bei Löschung des Versand-Empfängers oder Firmenkontakts oder Workspace. Im Datenexport (Art. 15/20 DSGVO) enthalten.
- Aufgaben-Kostenstellen-Zuordnung (tasks.cost_center_id, PROJ-543 + PROJ-545): Optionale FK-Spalte auf tasks (PROJ-545: FK zeigt auf billing_addresses.id, vorher billing_recipients.id). Erlaubt die Zuordnung einer Aufgabe zu einer Rechnungsanschrift. NULL = Aufgabe fällt bei Rechnungserstellung in die CRM-Standard-Gruppe. Bei Löschung der Anschrift: ON DELETE SET NULL (Aufgabe bleibt erhalten, Sammel-Default-Verhalten). Steuert Splitting bei Rechnungserstellung (pro Anschrifts-Gruppe eine eigene Rechnung). Im Datenexport als Teil des tasks-Exports enthalten.
- Backfill aus Altsystem (Kju/Cobra, PROJ-491): 260 Abrechnungs-Empfänger aus importierten Platzhalter-Ansprechpartnern migriert (2026-04-24). 5 verbleiben zur manuellen Prüfung (Marker PROJ-491-REVIEW). PROJ-545: 0-Daten-Migrationsfenster — zum Zeitpunkt des Refactors (2026-05-04) waren noch keine Anschriften in billing_recipients eingetragen, daher war keine Datenkonvertierung erforderlich.
- Projektübergreifende Bündelungs-Einstellung (contacts.cross_project_billing_enabled, PROJ-1813, Boolean, Default false): Steuert ob die monatliche Sammelrechnung diesen Firmenkontakt projektübergreifend nach Abrechnungsempfänger bündelt (eine Rechnung je billing_recipient über alle aktiven Projekte hinweg) statt wie im Standardfall eine Rechnung je Projekt × Abrechnungsempfänger. Kein Personenbezug (reine Steuerungsgröße für die Rechnungserzeugung). Bearbeitung ausschließlich durch Admins und Manager (Field-Level-Access-Control, analog den anderen Feldern dieser Karte). Wirkt nur auf zukünftige Sammelrechnungs-Läufe — bereits erstellte Rechnungen werden beim Umschalten nicht rückwirkend verändert. Im Datenexport (Art. 15/20 DSGVO) enthalten.
Team-Präsenz & Aktivitätsanzeige
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter Teamkollaboration). Widerspruchsrecht gemäß Art. 21 DSGVO wird durch Opt-out-Schalter im Profil gewährleistet
- Anzeigename und Avatar-URL: Werden über Supabase Realtime Presence ephemerisch an andere Workspace-Mitglieder übermittelt, um den Online-Status anzuzeigen. Keine dauerhafte Speicherung in der Datenbank — Daten werden beim Verlassen der Seite oder Schließen des Tabs automatisch entfernt
- Aktuelles Modul (z. B. 'Projekte', 'Aufgaben'): Wird ephemerisch übermittelt, damit Teammitglieder sehen können, in welchem Bereich ein Kollege arbeitet
- Idle-Status (aktiv/inaktiv): Wird nach 5 Minuten Inaktivität automatisch gesetzt. Ephemerisch, keine DB-Speicherung
- Präsenz-Sichtbarkeit (presence_visible): Dauerhaft in der profiles-Tabelle gespeichert (boolean, Standard: sichtbar). Der Nutzer kann die Sichtbarkeit jederzeit über das Profil deaktivieren — bei Deaktivierung tritt der Nutzer dem Präsenz-Kanal nicht bei und ist für andere nicht sichtbar. Löschung bei Account-Löschung (CASCADE)
- Temporärer Unsichtbar-Modus (sessionStorage): Wird im Browser-Speicher abgelegt und beim Schließen des Tabs automatisch gelöscht. Ermöglicht kurzfristiges Verbergen ohne dauerhafte Einstellungsänderung
- Verfügbarkeitsstatus (availability_status + availability_status_changed_at): Dauerhaft in der profiles-Tabelle gespeichert. Erlaubt sind 5 Werte: 'available' (online), 'away' (abwesend), 'busy' (beschäftigt), 'do_not_disturb' (bitte nicht stören), 'offline' (Standard nach Account-Erstellung: 'available'). Zusätzlich wird der Zeitpunkt des letzten Status-Wechsels (availability_status_changed_at) gespeichert, um anderen Workspace-Mitgliedern anzuzeigen, seit wann jemand beschäftigt oder abwesend ist. Der Wert wird auf NULL zurückgesetzt, wenn der Status auf 'verfügbar' gewechselt wird. Der Nutzer kann seinen Status jederzeit manuell über das Profil-Menü oder die native macOS Companion App ändern. Bei Status 'Beschäftigt' oder 'Abwesend' wird der Chat-Input in Direktnachrichten an diese Person deaktiviert (kein Blocking in Gruppenräumen). Der Status bleibt nach Logout erhalten und wird zusätzlich ephemerisch über den Presence-Kanal an andere Workspace-Mitglieder übermittelt. Löschung bei Account-Löschung (CASCADE). Im Datenexport (Art. 15/20 DSGVO) enthalten
- Zuletzt online (last_seen_at): Dauerhaft in der profiles-Tabelle gespeichert (Zeitstempel, Standard: NULL). Wird bei Navigation innerhalb der App und beim Schließen des Tabs aktualisiert (maximal alle 5 Minuten). Wird für andere Workspace-Mitglieder als relative Zeitangabe angezeigt ('vor X Minuten'). Bei Deaktivierung der Präsenz-Sichtbarkeit (presence_visible = false) wird der Wert auf NULL gesetzt und nicht mehr geschrieben. Löschung bei Account-Löschung (CASCADE). Im Datenexport (Art. 15/20 DSGVO) enthalten
- Verfügbar nur in Agentur-Workspaces. Client- und Partner-Workspaces haben keinen Zugriff auf die Präsenzanzeige
- Native macOS Companion App (PROJ-550): Der Verfügbarkeitsstatus und der Arbeitsort (workspace_members.work_location) sind zusätzlich zur Web-App in der NEULAND. OS Companion App lesbar und der eigene Status setzbar. Die App ruft die Daten über dedizierte Companion-Endpunkte (GET /api/companion/presence + PATCH /api/companion/presence) ab — Bearer-Token-Authentifizierung über den Supabase-JWT, identische Sichtbarkeitsregeln wie im Web (presence_visible=false → Status für andere als 'offline' maskiert; location_visible=false ODER work_location=NULL → kein Aufenthaltsort sichtbar). Auf dem Gerät werden die Status-Daten ausschließlich im Arbeitsspeicher der App gehalten (kein lokales Storage). Live-Updates erfolgen über Supabase Realtime (postgres-changes auf profiles-Tabelle). Es entsteht kein neuer Auftragsverarbeiter — die Verarbeitung erfolgt weiterhin in NEULAND. OS (Supabase + Vercel)
- Automatisierte Status-Verwaltung (Auto-Status, optional, PROJ-550): Die native macOS App kann den eigenen Status automatisch verwalten — bei App-Start auf 'verfügbar', beim Mac-Schlaf (NSWorkspace.willSleepNotification) auf 'abwesend', beim App-Beenden auf 'offline'. Manuell gewählte Status (insbesondere 'beschäftigt' und 'bitte nicht stören') werden bis zum nächsten App-Neustart respektiert und nicht durch Auto-Logik überschrieben. Der Auto-Modus ist standardmäßig aktiv und kann jederzeit über einen Einstellungs-Toggle (UserDefaults 'presenceAutoManage') deaktiviert werden — der Hinweis dazu ist im Einstellungs-Dialog der App sichtbar. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an akkurater Team-Verfügbarkeitsanzeige). Widerspruchsrecht: Toggle deaktivieren ODER Status-Sichtbarkeit (presence_visible) im Profil ausschalten
Kontakt- & Kundenverwaltung (CRM)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
- Firmenname
- Ansprechpartner (Name, E-Mail, Telefon)
- PROJ-601 Phase 2: Alternative E-Mail-Adressen pro Kontakt/Ansprechpartner (contacts.additional_emails + contact_persons.additional_emails — JSONB-Array {email, label?}, max 5 Einträge): Z.B. business + privat. Primary-E-Mail bleibt in der jeweiligen email-Spalte. Beim Versand von Angeboten kann der Mitarbeiter die alternative Adresse explizit wählen. Rechtsgrundlage Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung mit ausdrücklich angegebenen Kontaktdaten). CASCADE-DELETE bei Kontakt-Löschung.
- Branche
- Notizen
- Cross-Workspace-Aggregation: Bei bestehender Workspace-Verbindung können berechtigte Agentur-Mitarbeiter die Lead-Pipeline (Name, Lead-Quelle, Pipeline-Stage) verbundener Kunden-Workspaces einsehen. Die Daten verbleiben im Quell-Workspace und werden nicht kopiert. Durch Trennung der Workspace-Verbindung wird der Zugriff sofort entzogen.
- Pipeline-Automatisierung: Regelbasierte automatische Zuordnung von Kontakten zu Pipeline-Stages anhand konfigurierbarer Eintrittsbedingungen (z. B. ausgefüllte Felder, erstellte Angebote, stattgefundene Meetings). Die Auswertung erfolgt workspace-lokal ohne Übermittlung an Dritte. Transitionen werden in der Stage-History protokolliert (Quell-Stage, Ziel-Stage, Zeitstempel, Systemkennung). Konfigurationsdaten (Regeltyp, Feldschlüssel, Feldwert) sind keine personenbezogenen Daten. Löschung bei Kontakt-Löschung via CASCADE
- Duplikat-Erkennung & Merge (contact_duplicate_pairs): Täglicher Cron-Job erkennt potenzielle Duplikate unter Ansprechpartnern und Unternehmen mittels Trigram-Ähnlichkeit (Name, E-Mail, Telefon). Gespeichert werden: Workspace-ID, Entity-Typ (contact/company), zwei Kontakt-IDs, Ähnlichkeits-Score, Status (pending/ignored/merged), resolved_by (User-ID des Bearbeiters), resolved_at. Bei Merge werden alle FK-Referenzen (Projekte, Aufgaben, Angebote, Zeiteinträge, E-Mails, Provisionen, SSOT-Einträge, Aktivitätslog) auf den Primärkontakt migriert und das Duplikat gelöscht. resolved_by referenziert auth.users mit ON DELETE SET NULL (Art. 17 DSGVO). Löschung der Duplikat-Paare bei Workspace-Löschung (CASCADE)
- Umsetzungsteam pro Kontakt (contact_team_members): Zuordnung von Workspace-Mitgliedern (User-ID) zum Umsetzungsteam eines Kontakts mit optionaler Rolle (Freitext, max. 200 Zeichen) und optionaler Buchungsseiten-Verknüpfung. Personenbezug über user_id (identifiziert Mitarbeiter). Löschung bei Kontakt-Löschung (CASCADE DELETE) oder manueller Entfernung
- Wiederkehrende Meetings pro Kontakt (contact_recurring_meetings): Konfiguration regelmäßiger Meeting-Typen mit Name, Frequenz und optionaler Buchungsseiten-Verknüpfung. Keine direkten personenbezogenen Daten. Löschung bei Kontakt-Löschung (CASCADE DELETE)
- PROJ-620 CRM-Referenzen-Tab (crm_references, crm_reference_assets): Pro Kunden-Kontakt speichert Titel, Beschreibung, Kategorie, Story-Felder (Ausgangssituation/Lösung/Projektstatus max. je 5.000 Zeichen, PROJ-651; PROJ-673: Projektstatus ist seit 2026-05-16 ein 4-Werte-Enum aktiv/on_hold/abgeschlossen/abgebrochen statt Freitext), KPIs (numeric/text), Bilder/Galerie-Verlinkungen zu brand_assets, Video-URLs, Testimonial-Texte mit Klarnamen + Funktion. Story-Felder sind Marketing-Texte des Agentur-Teams und können indirekte PII enthalten (z. B. Mitarbeiter-Namen). KI-Mockup-Generierung ueber Higgsfield-MCP (siehe PROCESSORS). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (Marketing-Nachweis durch Auftragsverarbeiter), bei Public-Share-Link auch Art. 6 Abs. 1 lit. a (Einwilligung Manager) UND Art. 6 Abs. 1 lit. f. RLS: SELECT alle workspace_members, INSERT/UPDATE/DELETE nur Admin+Manager. Workspace+Contact-scoped, CASCADE-DELETE bei Kontakt- oder Workspace-Loeschung. Public-Share-Token (crm_references.public_share_token + .public_share_enabled): 144-Bit Random-Token (crypto.randomBytes), als Plaintext in der Datenbank gespeichert (analog zu Angebots-Share-Links PROJ-9 — Token funktioniert wie ein langes Passwort im Link selbst, kein Server-seitiges Secret). Aktivierung/Deaktivierung jederzeit durch Manager via public_share_enabled-Toggle; deaktivierter Link liefert 404. Audit-Cron: taegliche Stale-Detection und Inbox-Notification an Admins bei nicht-rotierten Tokens. Loeschung bei Workspace-Loeschung via CASCADE, signing_references und cms_collection_items behalten Bezug via FK ON DELETE SET NULL. Im Datenexport (Art. 15/20 DSGVO) enthalten (inkl. solution-Feld PROJ-651).
- PROJ-673 Projektstatus-Migration Backup (crm_references_project_status_backup_proj673): Einmaliges Audit-Backup der Original-Freitext-Werte aus crm_references.project_status, BEVOR die Spalte am 2026-05-16 auf das 4-Werte-Enum (aktiv/on_hold/abgeschlossen/abgebrochen) umgestellt wurde. Pro Referenz mit nicht-leerem project_status wird gespeichert: reference_id, workspace_id, original_value (Freitext), migrated_to (Ziel-Enum-Wert oder NULL bei nicht eindeutig zuordenbarem Text), migrated_at, created_at. Zweck: Workspace-Admins können nicht automatisch gemappte Texte innerhalb von 365 Tagen manuell nachpflegen. Enthält indirekte PII (Story-Texte mit Mitarbeiter-/Kundennamen). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Migrations-Audit, Wiederherstellbarkeit). RLS: SELECT nur Admin+Manager des Workspaces; keine User-Schreibrechte (Insert ausschließlich in der Migration, Cleanup ausschließlich via Cron). Retention: 365 Tage (Verhältnismäßigkeit nach Art. 5 Abs. 1 lit. e DSGVO — gibt Admins einen Geschäftsjahres-Zyklus zur Nachpflege; danach automatische Löschung via tracking-cleanup-Cron). CASCADE-DELETE bei Referenz- oder Workspace-Löschung. Im Datenexport (Art. 15/20 DSGVO) enthalten.
- PROJ-672 CRM-Favoriten (contact_favorites): Pro Agentur-Mitarbeiter werden favorisierte Unternehmens-Kontakte gespeichert (user_id, contact_id, workspace_id, created_at). Zweck: Schnellzugriff auf häufig genutzte Kunden ohne erneute Suche (Komfortfunktion zur Listen-Personalisierung). Nur in Agentur-Workspaces (workspaces.type = agency); Client-Portale erhalten 403. Keine Inhalts-Kopie der Kontakte selbst — ausschließlich Referenzen via FK. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Effizienz im Account-Management ohne Mehrverarbeitung). Personenbezug entsteht indirekt über user_id (Nutzungsverhalten des Agentur-Mitarbeiters: welche Kunden werden bevorzugt aufgerufen?). RLS: SELECT/INSERT/DELETE strikt auf user_id = auth.uid() begrenzt; andere Workspace-Mitglieder sehen die Favoriten NICHT. INSERT-Policy enthält zusätzlich Cross-Workspace-Smuggle-Schutz (contact.workspace_id muss mit favorite.workspace_id übereinstimmen). UNIQUE(user_id, contact_id) für Idempotenz. CASCADE-DELETE bei Nutzer-Löschung (auth.users), Kontakt-Löschung (contacts) und Workspace-Löschung (workspaces) — keine verwaisten Referenzen. Im Workspace-Datenexport (Art. 15/20 DSGVO) enthalten (gefiltert auf den anfragenden Nutzer + aktiven Workspace).
- PROJ-1737 Sidebar-Modul-Favoriten (module_favorites): Pro Nutzer und Workspace werden favorisierte Sidebar-Module gespeichert (user_id, workspace_id, module_key, sort_order, created_at). Zweck: persönlicher Schnellzugriffs-Bereich ganz oben in der Sidebar (Komfortfunktion zur Navigations-Personalisierung, inkl. frei wählbarer Reihenfolge per Drag & Drop). Keine Inhaltsdaten — ausschließlich Referenzen auf Modul-Schlüssel via FK auf module_definitions. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — effiziente Navigation ohne Mehrverarbeitung). Personenbezug entsteht indirekt über user_id (Nutzungsverhalten: welche Module nutzt der Mitarbeiter bevorzugt?). RLS: SELECT/INSERT/UPDATE/DELETE strikt auf user_id = auth.uid() begrenzt, SELECT/INSERT zusätzlich an aktive Workspace-Membership gebunden; andere Workspace-Mitglieder sehen die Favoriten NICHT. UNIQUE(user_id, workspace_id, module_key) für Idempotenz. Speicherdauer: bis der Nutzer die Markierung entfernt; CASCADE-DELETE bei Nutzer-Löschung (auth.users), Modul-Löschung (module_definitions) und Workspace-Löschung (workspaces). Im Workspace-Datenexport (Art. 15/20 DSGVO) enthalten (gefiltert auf den anfragenden Nutzer + aktiven Workspace).
- PROJ-935 Kreditoren-/Debitoren-Buchhaltungsfelder (contacts): Erweiterung bestehender Kontakte um buchhalterische Stammdaten. Neue Datenkategorien: Buchhaltungsrolle (kreditor/debitor/beides/none — klassifiziert ob wir an den Kontakt zahlen oder er an uns), Kreditorennummer und Debitorennummer (externe Buchhalter-IDs z. B. aus Addison — kein Personenbezug im eigentlichen Sinne, jedoch Geschäftsdatum), Zahlungsziel in Tagen (Vertragskondition), Standard-IBAN des Lieferanten (AES-256-GCM verschlüsselt via FINAPI_ENCRYPTION_KEY — Bankverbindungsdaten des Geschäftspartners, nicht des Endnutzers), Standard-BIC. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Zahlungsabwicklung gegenüber Lieferanten) UND Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — ordnungsgemäße Buchführung nach HGB § 238). RLS: SELECT/PATCH Buchhaltungsfelder nur Admin+Manager. Standard-IBAN wird ausschließlich masked (letzte 4 Stellen) an die UI geliefert; Klartext nur server-seitig für SEPA-Zahlungsaufträge. CASCADE-DELETE bei Workspace-/Kontakt-Löschung. Im Workspace-Datenexport (Art. 15/20 DSGVO) enthalten (IBAN als letzte 4 Stellen, nicht Klartext).
- PROJ-1533 Kontakt-Monitoring — Einschlaf-Erkennung (contacts): Vier neue Felder am Kontakt. last_contact_at (Zeitstempel des letzten Kontaktereignisses — automatisch per DB-Trigger abgeleitet aus direkter Kommunikation (sales_communication_log, ohne interne Notizen/ignorierte Auto-Zuordnungen) und aus erledigten Aufgaben verknüpfter Projekte; einmaliger Backfill aus Bestandsdaten bei Einführung), inactivity_threshold_days (individuelle Einschlaf-Frist in Tagen, 1–365, Default 30 — nur durch Admin/Manager setzbar), zustaendiger_redakteur_id (Referenz auf den betreuenden Agentur-Mitarbeiter, auth.users, ON DELETE SET NULL — Personenbezug: identifiziert den zuständigen Mitarbeiter pro Kunde), last_contact_notified_at (technisches Idempotenz-Flag der Einschlaf-Benachrichtigung, wird bei neuem Kontaktereignis zurückgesetzt). Täglicher Cron (contact-inactivity-check) prüft Fristüberschreitung und erstellt eine reine Inbox-System-Benachrichtigung an den zuständigen Redakteur (Fallback: Workspace-Admins/-Manager) — keine automatisierte Entscheidung über Personen, nur Sichtbarmachung. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — aktive Kundenbetreuung, Verhinderung unbeabsichtigter Betreuungslücken). Löschung bei Kontakt-Löschung (Felder Teil der contacts-Zeile), zustaendiger_redakteur_id bei Nutzer-Löschung ON DELETE SET NULL. Im Kontakt-Datenexport (Art. 15/20 DSGVO) enthalten.
- PROJ-1571 Rollenbasierte Ansprechpartner für Website-Insert-Tags (contact_role_contacts): Pro Marke (Contact) oder als Workspace-weiter Standard können bis zu 7 Rollen-Kontakte gepflegt werden (Redaktion, Datenschutz, Bewerbung, Vertrieb, Support, Inhaber, Komplementär) — je nach Rolle Anrede/Name/E-Mail/Telefon/Position bzw. Adresse bzw. Titel. Zweck: automatisches Einsetzen als Website-Platzhalter (z. B. {{privacy.email}} im Impressum/Datenschutzerklärung), damit Ansprechpartner nicht manuell im Seiteninhalt gepflegt werden müssen. Zusätzlich 11 weitere Firmendaten-Felder (Adresszusatz, Postanschrift, Fax, Bundesland, Firmenname-Varianten, Handelsregister-Komplementär) direkt auf contacts/workspaces, gleiche Zweckbindung. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Website-Pflichtangaben wie Impressum/Datenschutzerklärung). RLS: SELECT/INSERT/UPDATE alle Workspace-Mitglieder, DELETE nur Admin. CASCADE-DELETE bei Kontakt- oder Workspace-Löschung. Kein bestehender Contact-Datenexport-Endpunkt im Repo vorhanden — daher aktuell auch keine Aufnahme dort nötig.
Client-CRM — Lead- & Recruiting-Pipeline (Kunden-Workspaces)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung), Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Bewerberverwaltung)
- Lead-Pipeline: Name, E-Mail, Telefon, Firmenname, Position, Lead-Quelle, Notizen, Aktivitätsverlauf (erstellt/aktualisiert/Stage-Wechsel)
- Recruiting-Pipeline: Bewerbername, E-Mail, Telefon, Position, Notizen, Lebenslauf (PDF/DOC/DOCX, max. 10 MB, privater Storage-Bucket mit signierten URLs), Aktivitätsverlauf
- DSGVO-Aufbewahrungsfrist Bewerber: 6 Monate nach Ablehnung — automatische Anonymisierung durch täglichen Cron (Name → 'Anonymisiert', E-Mail/Telefon/Position/Notizen/CV gelöscht). Lebenslauf-Dateien werden aus dem Storage entfernt
- Pipeline-Stages: Konfigurierbare Phasen pro Pipeline (Name, Farbe, Reihenfolge) — keine personenbezogenen Daten
- Datenexport (Art. 15/20): Leads, Bewerber und Aktivitätsdaten sind im Workspace-Datenexport enthalten
- Agentur-Leseansicht: Bei bestehender Workspace-Verbindung können berechtigte Agentur-Mitarbeiter die Lead- und Recruiting-Pipeline im Read-Only-Modus einsehen. Die Daten verbleiben im Kunden-Workspace
Projektverwaltung & Aufgaben
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
- Projektnamen und -beschreibungen
- Aufgaben mit Zuweisungen
- Kommentare und @Mentions. PROJ-1898 Mention-basierte Sichtbarkeit: @-Erwähnungen werden zusätzlich zum Freitext strukturiert erfasst (Tabelle comment_mentions — pro Kommentar wer/was erwähnt wurde: Agentur-Mitarbeiter, Abteilung, KI-Mitarbeiter, Kunden-Firma oder einzelner Kunden-Login-Nutzer, jeweils nur als ID-Referenz auf bereits bestehende Datensätze, keine neuen Datenkategorien). Ein daraus vorberechnetes Sichtbarkeits-Flag (comments.client_visible) steuert, ob ein Agentur-Kommentar für die Login-Nutzer des freigegebenen Kunden-Workspace sichtbar ist — Agentur-Kommentare sind standardmäßig intern und werden nur bei ausdrücklicher Erwähnung der Kunden-Firma oder einer Kunden-Person kundensichtbar; Kommentare von Kunden-Nutzern bleiben unverändert für die Agentur sichtbar. Lebenszyklus: Erwähnungs-Zeilen werden bei Kommentar-Löschung CASCADE-gelöscht (Rechtsgrundlage wie Kommentare selbst, Art. 6 Abs. 1 lit. b DSGVO). PROJ-1899 Projektübergreifender Kommunikationsbereich: Kunden-Login-Nutzer können Kommentare zusätzlich auf oberster Ebene ihres Kunden-Workspace verfassen — wahlweise ohne Bezug („Allgemein“, neuer Speicherort-Typ client_workspace, gespeichert im Workspace der verbundenen Agentur) oder einem freigegebenen Projekt/einer Aufgabe zugeordnet. Es entstehen keine neuen Datenkategorien — dieselbe Kommentar-Art (Freitext, Autor, Zeitstempel, optionale Anhänge/@-Erwähnungen) an einem zusätzlichen Ort; Allgemein-Kommentare sind wechselseitig für Kunde und Agentur sichtbar (das ist der Zweck des gemeinsamen Kanals). Ein Herkunfts-Kennzeichen (comments.client_top_level) markiert im Projekt-Kontext, dass ein Kommentar auf oberster Ebene entstanden ist (kein Personenbezug). Neue Kommentare ohne Projektbezug lösen eine Inbox-Benachrichtigung an aktive Admin-/Manager-Mitglieder der verbundenen Agentur aus (Inhalt: Autor-Anzeigename, Kunden-Workspace-Name, Text-Vorschau). PROJ-1900 Agentur-weiter Kommunikationsbereich: Agentur-Mitarbeiter mit CRM-Modulzugriff sehen zusätzlich einen kunden- und projektübergreifenden Feed derselben Kommentare (reine Aggregation, kein neuer Datenbestand) und können Kommentare ohne jeden Bezug verfassen (neuer Speicherort-Typ agency_workspace, rein agenturintern). CRM-Kontakt-Kommentare (ohne Projektbezug) können seither bei ausdrücklicher Erwähnung der Kunden-Firma oder einer Kunden-Person kundensichtbar werden (gleiche Mention-Regel wie bei Projekt-Kommentaren, aufgelöst über die aktive Workspace-Verbindung des Kontakts); ohne Erwähnung bleiben sie unverändert intern. PROJ-2110 Kommunikations-Gruppen: Agentur-Mitarbeiter können Kommentare zusätzlich in selbst erstellten, abgeschotteten Gruppen verfassen (neuer Speicherort-Typ communication_group — dieselbe Kommentar-Art, keine neue Datenkategorie). Sichtbarkeit strikt auf aktuelle Gruppenmitglieder beschränkt (Positivliste über die neue Mitgliedschaftstabelle communication_group_members: Gruppen-ID, Nutzer-ID, wer das Mitglied wann hinzugefügt hat — mildes personenbezogenes Datum über interne Team-Zugehörigkeiten); Workspace-Admins/Manager sehen zur Verwaltung Gruppennamen und Mitgliederlisten (Tabelle communication_groups: Name, optionale Beschreibung, Ersteller-Referenz, Archivierungszeitpunkt), aber niemals Kommentar-Inhalte ohne eigene Mitgliedschaft. @-Erwähnungen in Gruppen benachrichtigen ausschließlich Gruppenmitglieder. Beim Verlassen/Entfernen eines Mitglieds erlischt der Zugriff sofort und vollständig; Gruppen werden nur archiviert (Historie bleibt für verbleibende Mitglieder erhalten), nie gelöscht. Lebenszyklus: Mitgliedschafts-Zeilen werden bei Gruppen-Löschung über die Workspace-Löschkaskade CASCADE-gelöscht (Rechtsgrundlage wie Kommentare selbst, Art. 6 Abs. 1 lit. b DSGVO).
- Datei-Anhänge
- PROJ-539 Projekt-Abrechnungsmodell-Historie (project_billing_model_history): Audit-Trail für jede Änderung am Projekt-Abrechnungsmodell (Sprint-Kontingent, monatliche Pauschale, Modus). Pro Eintrag werden gespeichert: User-ID des Änderers, Zeitstempel, Quelle der Änderung (auto_from_quote / manual / quote_amendment), Snapshot der alten + neuen Werte als JSONB. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Audit-Nachvollziehbarkeit). Workspace-scoped, CASCADE-DELETE bei Projekt- oder Workspace-Löschung. Zugriff nur für admin/manager des Workspaces.
- PROJ-699 Aufgaben-Erledigt-Metadaten (tasks.completed_at + tasks.completed_by): Zeitstempel und Mitarbeiter-Referenz bei Aufgaben-Abschluss. Pro erledigter Aufgabe: completed_at (TIMESTAMPTZ, Zeitpunkt der Erledigung — kann vom schliessenden Mitarbeiter rueckwirkend gesetzt werden), completed_by (UUID-Referenz auf auth.users(id), der Mitarbeiter der die Aufgabe geschlossen hat). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Audit-Nachvollziehbarkeit und Projekt-Velocity-Reporting). RLS: workspace-scoped, identisch zu tasks. Bei Mitarbeiter-Account-Loeschung: completed_by ON DELETE SET NULL — das Erledigungs-Datum bleibt fuer Audit-Trail erhalten (anonymisierte Aktivitaet). Kein Cleanup-Cron (Aufgaben-Daten folgen dem Workspace-Lebenszyklus).
- PROJ-1462 Projekt-Verantwortlicher (PM) + Priorität (projects.project_manager_id, projects.priority): project_manager_id ist eine UUID-Referenz auf den verantwortlichen Mitarbeiter (auth.users) — frei durch jeden aktiven Workspace-Mitarbeiter setzbar, kein Rollen-Gate. priority ist ein Freitext-Wert aus den workspace-konfigurierbaren Dropdown-Optionen (workspace_dropdown_options, category='project_priority', analog zu projects.status) — kein Personenbezug. Beide Felder sind nullable ohne Default (Bestandsprojekte, u. a. alle 591 D&P-Importe, bleiben ohne PM/Priorität). Änderung der Zuweisung löst eine Inbox-Notification (project_manager_assigned) an die neu zugewiesene Person aus (Metadaten: Projektname + zuweisende User-ID, beide nur workspace-intern sichtbar). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an interner Projektsteuerung). Ausschließlich im Agentur-Workspace sichtbar — das Kunden-Portal (`GET /api/client/projects`) liefert project_manager_id/priority nicht mit.
- PROJ-1503 Aufgaben-Startdatum + Kalenderansicht (tasks.start_date): reines Planungsdatum (DATE, nullable, kein Personenbezug im Feldwert selbst), manuell durch die zuständige Person, den Projektmanager oder einen Admin gesetzt/geändert (serverseitig durchgesetzt). Neue Kalenderansicht (`/aufgaben?ansicht=kalender`) zeigt Aufgaben- und Projekt-Zeitbalken gruppiert nach zuständiger Person (tasks.assignee_id) bzw. Projektmanager (projects.project_manager_id) — keine neuen Datenkategorien ggü. den bereits dokumentierten Zuweisungs-/PM-Feldern, nur eine zusätzliche zeitliche Darstellung bestehender, bereits dokumentierter Zuweisungen. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung, Projekt-/Ressourcenplanung).
- PROJ-1668 Aufgaben & Kalender — Darstellungskonzept (tasks.status_since): Zeitstempel des letzten Statuswechsels (TIMESTAMPTZ, kein Personenbezug im Feldwert selbst), automatisch bei jedem Statuswechsel gesetzt — Grundlage für eine Eskalations-Markierung (`wie lange im aktuellen Status`), kein eigenes Eskalationsfeld. Vier Ansichten (Liste, Kanban, Gruppiert-nach-Kunde, Karten) sowie eine erweiterte Kalenderansicht (4 Zeiträume × 2 Ausrichtungen) zeigen ausschließlich bereits bestehende, dokumentierte Zuweisungs-/Kunden-Felder (tasks.assignee_id, projects.contact_id → contacts.name, bereits PROJ-1532) in neuen Darstellungsformen — keine neuen Datenkategorien. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung, Projektsteuerung) bzw. Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse, analog PROJ-699 Audit-Nachvollziehbarkeit) für status_since.
- PROJ-2107 Aufgaben-Priorisierung (tasks.is_important/is_urgent/prio_index/prio_index_updated_at, task_statuses.prio_category, task_prio_factors, project_prio_mappings): Zwei manuell setzbare Aufgaben-Kennzeichen 'Wichtig'/'Dringend' (Boolean, kein Personenbezug), ein daraus formelbasiert berechneter Prioritäts-Wert (PrioIndex, numerisch, Arbeitsorganisations-Metadatum der Aufgabe — KEINE automatisierte Entscheidung über Personen: priorisiert werden Aufgaben, nicht Mitarbeitende, ohne Rechtsfolge oder Leistungsbewertung) sowie workspace-weite, admin-konfigurierbare Formel-Faktoren und Status-/Prioritäts-Zuordnungstabellen (reine Konfigurationsdaten ohne Personenbezug). Der neue Inbox-Aufgaben-Kanal und die Projektleitungs-Übersicht zeigen ausschließlich bereits dokumentierte Zuweisungs-/Termin-Felder (tasks.assignee_id, due_date, projects.project_manager_id) in neuer Sortierung — keine neuen Personenbezugs-Kategorien. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung, Projekt-/Aufgabensteuerung). Lebenszyklus: Felder folgen der Aufgabe (CASCADE), Konfigurationstabellen dem Workspace (CASCADE).
- PROJ-1872 Plan gegen Ist (project_plan_baselines, project_phases.actual_end_date): Einmaliger Snapshot des geplanten Projektplans (Phasen-Start/-Ende, Meilenstein-Solltermine, Aufgaben-Solltermine — ausschließlich bereits dokumentierte Termin-/Namensfelder, keine neue Personenbezugs-Kategorie) zum Go-Live-Zeitpunkt, plus wer/wann eingefroren hat (frozen_by → auth.users, frozen_at). Eine Baseline pro Projekt (UNIQUE project_id), automatisch beim Erreichen von projects.end_date oder manuell durch ein Agentur-Mitglied ausgelöst; spätere Umplanungen ändern die Baseline nicht rückwirkend. actual_end_date (DATE, nullable) ergänzt project_phases um das tatsächliche Abschlussdatum einer Phase, analog zum bereits dokumentierten Meilenstein-Paar target_date/achieved_date. Beide dienen ausschließlich dem internen Plan-gegen-Ist-Vergleich (Ampel-Status), keine Kunden-Sichtbarkeit. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Projekt-/Terminsteuerung, analog PROJ-539 Audit-Snapshot).
Zeiterfassung
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
- Erfasste Arbeitszeiten
- Projekt- und Aufgabenzuordnung
- Nutzer-Zuordnung
- PROJ-1524 Pausenzeiten (work_time_breaks): manuell erfasste Pausen auf Arbeitszeit-Ebene (Start, Ende, Quelle: 'manual' = Pause-Button oder 'gap_decision' = nachträglich als Pause eingeordnete Zeitlücke) — getrennt von der Kunden-/Aufgabenzeit, kein Projekt-/Aufgabenbezug. RLS: eigene Zeilen oder Admin/Manager im Workspace. CASCADE-Löschung bei Account-/Workspace-Löschung, analog zu Erfassten Arbeitszeiten. Fließt aggregiert (Pausenminuten) in die gesetzliche Arbeitszeitaufzeichnung ein, siehe Eintrag 'Gesetzliche Arbeitszeiterfassung'.
- PROJ-2008 Direkt-Start-Marker (work_time_day_starts): Zeitpunkt, zu dem eine Person ihre Arbeitszeit per Start-Button begonnen hat, ohne einen Projekt-/Aufgaben-Timer zu starten (Startzeitpunkt + Kalendertag, max. ein Marker pro Person und Tag) — kein Projekt-/Aufgabenbezug, keine Dauer-Erfassung. Nachträgliche Korrektur der Startzeit durch die Person selbst möglich (nur innerhalb des laufenden Tages). RLS: eigene Zeilen oder Admin/Manager im Workspace, analog Pausenzeiten. CASCADE-Löschung bei Account-/Workspace-Löschung. Fließt als frühester Arbeitsbeginn in die Live-Tagesstatus-Ableitung ein (siehe Eintrag 'Gesetzliche Arbeitszeiterfassung').
- PROJ-1524 Tätigkeitswechsel: Ein Wechsel der Tätigkeit am laufenden Timer erzeugt ein zusätzliches, separat getaggtes time_entries-Segment (Split zum Wechsel-Zeitpunkt) statt eines neuen, unabhängigen Zeiteintrags — keine neue Datenkategorie, nur eine feinere zeitliche Aufteilung bereits erfasster Arbeitszeit.
- PROJ-1614 'Zuletzt genutzt' entfernen (time_entry_recent_dismissals): rein persönliche UI-Präferenz — welche Kunde/Aufgabe/Tätigkeit-Kombination die Person aus ihrer eigenen Schnellauswahl-Liste ausgeblendet hat (Zeitstempel + dieselbe Projekt-/Aufgaben-/Tätigkeits-Referenz wie die Zeiteinträge selbst, keine neue Datenkategorie). Nur für die eigene Ansicht wirksam, keine Sichtbarkeit für andere Workspace-Mitglieder. CASCADE-Löschung bei Nutzer-/Workspace-/Projekt-/Aufgaben-Löschung, analog zu Erfassten Arbeitszeiten.
Gesetzliche Arbeitszeiterfassung (ArbZG-konform)
Rechtsgrundlage: Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung) — §16 Abs. 2 ArbZG verpflichtet Arbeitgeber zur Aufzeichnung der über die werktägliche Arbeitszeit hinausgehenden Arbeitszeit. Zusätzlich Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) für die vollständige Arbeitszeitdokumentation
- Tägliche Arbeitszeitaufzeichnungen (daily_work_records): Arbeitsbeginn, Arbeitsende, Brutto-/Netto-Arbeitsminuten, Pausenminuten, Soll-Minuten, Toleranzminuten, Delta-Berechnung, Tagestyp (Arbeitstag/Wochenende/Feiertag/Urlaub/Krank/Sonstige Abwesenheit/Individuell frei [PROJ-2052])
- ArbZG-Compliance-Warnungen: Überschreitung der 10-Stunden-Grenze (§3 ArbZG), Unterschreitung der 11-Stunden-Ruhezeit (§5 ArbZG), automatische Pausen-Auffüllung (§4 ArbZG)
- Manuelle Korrekturen: Korrigierte Arbeitszeiten, Korrekturnotizen, Status 'manuell angepasst'. PROJ-1524: zusätzliche Korrekturwege über die neuen Lücken-Dialoge — proaktiver Vorschlag nach Inaktivitäts-Schwelle (Auslöser 2) sowie ein Pflicht-Dialog beim ersten Öffnen an einem neuen Kalendertag mit offener Vortages-Lücke (Auslöser 3, inkl. Abwesenheits-Pfad 'war nicht im Dienst'). Keine neue Datenkategorie, nur zusätzliche, bewusste Erfassungswege für dieselben Tagesaufzeichnungsfelder
- Workspace-Konfiguration: Wöchentliche Sollstunden, Arbeitstage pro Woche, Toleranzminuten, Pausenlücken-Schwelle, Bundesland (für Feiertagsberechnung). PROJ-1524: zusätzlich Inaktivitäts-Schwelle für den proaktiven Lücken-Vorschlag (work_time_inactivity_threshold_minutes, Default 60 Minuten)
- Individuelle Wochenstunden: Abweichende Sollstunden pro Mitarbeiter in den Lohn-Stammdaten (historisiert mit Gültigkeitsdatum)
- Individuelle Wochenarbeitstage (PROJ-2052, payroll_employee_data.individual_workdays): Optionale Auswahl, an welchen der sieben Wochentage ein Mitarbeitender regulär arbeitet (z.B. bei Teilzeit-Mustern wie „nicht montags“) — historisiert wie die individuellen Wochenstunden mit Gültigkeitsdatum. Ohne Eintrag gilt automatisch Montag–Freitag, keine Änderung für Mitarbeitende ohne individuelles Muster. Fließt in die tägliche Arbeitszeitaufzeichnung ein: Tage außerhalb des Musters erhalten den Tagestyp „Individuell frei“ statt einer verbrauchten Abwesenheit (Urlaub/Krankheit), falls beide zusammenfallen. Zugriff/Pflege wie bei den individuellen Wochenstunden ausschließlich durch Mitglieder mit Lohnbuchhaltungs-Zugriff
- Automatische Ableitung: Tägliche Aufzeichnungen werden aus den bestehenden Projekt-Zeiteinträgen (time_entries) sowie den manuell erfassten Pausen (work_time_breaks, PROJ-1524, siehe Eintrag 'Zeiterfassung') automatisch berechnet. Es werden keine zusätzlichen personenbezogenen Daten erhoben. PROJ-1524 ergänzt zudem eine Live-Ableitung des Tagesstatus (aktiv/pausiert/beendet) während des Tages — rein berechnet aus denselben Quelldaten, keine zusätzliche Speicherung
- PROJ-2050 Nächster-Arbeitstag-Hinweis: Beim Klick auf 'Feierabend' berechnet ein Selbst-Auskunfts-Endpunkt (GET /api/work-time/next-workday) aus dem individuellen Wochenmuster, dem Bundes-Feiertagskalender und den eigenen Abwesenheiten (siehe jeweilige Einträge) den nächsten regulären Arbeitstag und zeigt ihn als Toast-/Banner-Text an ('bis Montag!'). Rein lesend und rein berechnend — keine neue Datenkategorie, keine Speicherung des Ergebnisses, ausschließlich für die eigene Anzeige des aufrufenden Mitarbeitenden (kein Zugriff auf fremde Daten, unabhängig von der Lohnbuchhaltungs-Berechtigung)
- Aufbewahrung: 2 Jahre gemäß §16 Abs. 2 ArbZG. Löschung bei Account-Löschung via CASCADE
Überstunden-Vergütungsfähigkeit & Urlaubskonto (PROJ-1482)
Rechtsgrundlage: Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung — ArbZG-Aufzeichnungspflicht, BAG-Beschluss vom 13.09.2022, 1 ABR 22/21) i.V.m. §7 Arbeitsvertrag (Überstunden nur auf Anordnung, Dokumentations- und Anzeigepflicht bis zum Folgetag) sowie Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) für die Einordnung der Vergütungsfähigkeit und das Urlaubskonto
- Überstunden-Meldungen (overtime_reports): Pro Mitarbeiter, Tag und Aufgabe der über das Tagessoll hinausgehende, auf einer vorab freigegebenen Aufgabe gebuchte Minuten-Anteil, Status (wartet auf Bestätigung / bestätigt = vergütungsfähig / verfallen = Frist verpasst), Bestätigungsfrist (Ende des Folgetags), Bestätigungszeitpunkt sowie Aufgaben-Referenz mit Aufgabentitel-Snapshot (bleibt nach Aufgaben-Löschung lesbar). Automatisch durch den täglichen Arbeitszeit-Cron aus den bestehenden Zeiteinträgen abgeleitet — es werden keine zusätzlichen Rohdaten erhoben. Die vollständige gesetzliche Arbeitszeitaufzeichnung (daily_work_records, siehe Eintrag Gesetzliche Arbeitszeiterfassung) bleibt unverändert bestehen
- Aufgaben-Freigabe-Flag (tasks.overtime_approved): Ja/Nein-Markierung an Aufgaben, nur durch Admin/Manager setzbar — kein direkter Personenbezug, wirkt sich aber auf die Vergütungsfähigkeit der auf der Aufgabe gebuchten Mitarbeiterzeit aus
- Freigabe-Änderungshistorie (activity_log, event_type=overtime_approval_changed): Wer das Freigabe-Flag wann von welchem auf welchen Wert umgestellt hat (Aktor-User-ID, alter/neuer Wert, Zeitstempel). Dient als Nachweis-Grundlage für Vergütungsansprüche (Rekonstruktion des Freigabe-Stands zum Buchungszeitpunkt) — append-only, Aktor wird bei Account-Löschung anonymisiert (SET NULL)
- Inbox-Benachrichtigung (Typ overtime_confirmation_required): Hinweis an den betroffenen Mitarbeiter, dass Überstunden vom Vortag bis Ende des Folgetags bestätigt werden müssen (Datum, aggregierte Minuten, Frist) — nur workspace-intern an den Betroffenen selbst
- Sichtbarkeit: Mitarbeitende sehen ausschließlich eigene Überstunden-Daten (Seite Mein Bereich); Urlaub/Krankheit sind im Cockpit dokumentiert (siehe dortiger Eintrag). Admins/Manager sehen zusätzlich eine aggregierte Team-Übersicht (RLS-geschützt plus serverseitige Rollen-Checks)
- Aufbewahrung/Löschung: overtime_reports werden bei Workspace- oder Account-Löschung via CASCADE gelöscht. Bestätigte Meldungen sind vergütungsrelevant und danach nur noch per Admin-Korrektur änderbar (Berichtigungsweg nach Art. 16). Keine automatische zeitbasierte Löschung — Vergütungsnachweise werden analog zu Lohnunterlagen aufbewahrt
- Datenexport (Art. 15/20): Eigene Überstunden-Meldungen sind im Workspace-Datenexport enthalten (analog daily_work_records); die Freigabe-Änderungshistorie ist über den bestehenden activity_log-Export abgedeckt
Aufwands-Abgleich Zeiterfassung vs. Preisliste (PROJ-1411)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an korrekter Preislisten-Kalkulation und wirtschaftlicher Projektsteuerung)
- Aggregierte Ist-Stunden pro abgeschlossener Aufgabe (task_effort_variance_log.actual_hours): Summe aller Zeiterfassungs-Einträge (time_entries.duration_seconds) einer Aufgabe zum Abschlusszeitpunkt — ohne Nutzer-Bezug gespeichert (keine user_id im Log, keine Aufschlüsselung pro Mitarbeiter, kein Einzel-Ranking)
- Soll-Stunden, Abweichung in Prozent, angewendeter Schwellenwert und Richtung (schneller / langsamer / ohne Soll-Aufwand) je Aufgabe — reine Kalkulationswerte auf Aufgaben-Ebene, plus Aufgaben-Titel-Snapshot zum Abschlusszeitpunkt
- Zweck: Abgleich pauschaler Preislisten-Positionen mit dem tatsächlichen Aufwand (Kalkulations-Auswertung) — KEINE individuelle Leistungsbewertung von Mitarbeitenden. Sichtbarkeit ausschließlich für Admin/Manager von Agentur-Workspaces (RLS-Policy + serverseitiger Rollen- und Workspace-Typ-Guard); Mitarbeitende ohne Admin/Manager-Rolle und Kunden-Workspaces haben keinen Zugriff
- Mittelbare Personenbeziehbarkeit: Bei Aufgaben, an denen nur eine Person Zeit erfasst hat, entspricht die Summe deren Einzelzeit. Die zugrunde liegenden Einzelzeiten sind bereits Teil der Verarbeitung `Zeiterfassung` (siehe dort) und werden hier nicht erneut gespeichert
- Aufbewahrung: Lebenszyklus an die Aufgabe gekoppelt — Löschung der Aufgabe oder des Workspace löscht den Abgleichs-Eintrag automatisch (CASCADE). Keine zusätzliche zeitbasierte Löschung, da der Eintrag eine rückwirkende Kalkulations-Historie ohne direkten Personenbezug ist
E-Mail-Versand (Transaktional)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
- E-Mail-Adresse des Empfängers
- Name des Empfängers
- E-Mail-Inhalt (Benachrichtigungen, Einladungen)
KI-Assistent & SSOT-Vorschläge
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und lit. f DSGVO (berechtigtes Interesse an effizienter Projektsteuerung)
- Nutzereingaben im Chat
- Anonymisierte Projektdaten als Kontext
- Projektkontext inklusive Mitarbeiter-Anzeigenamen und Aufgabenzuweisungen
- Generierte KI-Antworten
- Feature-Wissensbasis (PROJ-460): Der globale KI-Assistent im Header (Bot-Icon) erhält bei jeder Frage die 3 semantisch ähnlichsten veröffentlichten Hilfe-Artikel sowie eine kompakte App-Feature-Übersicht (Menü-Pfade, Kurzbeschreibungen) als Wissensbasis. Übermittelt werden ausschließlich öffentliche Produktdokumentation — keine personenbezogenen Daten Dritter
- Unbeantwortete Fragen-Audit-Log (PROJ-460): Wenn der KI-Assistent signalisiert, dass er eine Frage nicht beantworten kann, wird die Frage (max. 2000 Zeichen) zusammen mit Workspace-ID, User-ID, Rolle und Seiten-Route in ai_assistant_unanswered_questions gespeichert. Zweck: Platform-Admins erkennen Wissenslücken und ergänzen Hilfe-Artikel. Der Fragentext kann selbst-eingegebene personenbezogene Daten enthalten. Aufbewahrung: 30 Tage, danach automatisches Löschen via Cleanup-Cron (DSGVO-konform). Zugriff nur für den eingeloggten Nutzer selbst und Plattform-Administratoren
- SSOT Initial-Multi-Source-Befüllung (PROJ-1378) und SSOT Domain-Re-Crawl-Validierung (PROJ-1379): Rohtext aus Website-Crawls, Google-Drive-Dateien, Datei-Uploads (Bild/PDF via OCR; TXT/MD/Word .docx seit PROJ-1424 direkt als Text), NotebookLM-Exporten, internen Kommentaren/Kommunikationshistorie und Meeting-Transkripten wird zur Extraktion strukturierter SSOT-Vorschläge (ssot_ai_suggestions, Status pending/accepted/rejected) verarbeitet. Bei PROJ-1379 werden zusätzlich bereits gespeicherte SSOT-Werte (Zielgruppen, Personas, Marketingziel-Beschreibungen) als Vergleichsbasis an Anthropic übermittelt (siehe PROCESSORS-Eintrag Anthropic PBC). Tabu-Felder (Budget, Vertragskennzahlen, Laufzeiten) werden serverseitig nie automatisch übernommen. Jeder Vorschlag durchläuft eine manuelle Bestätigung durch einen Agentur-Mitarbeiter vor Übernahme in die SSOT — kein automatisches Schreiben. Aufbewahrung: Vorschläge bleiben bis zur manuellen Entscheidung, danach dauerhaft mit Status (Audit-Trail), Löschung mit dem zugehörigen Kontakt (CASCADE). PROJ-1543 (SSOT-Domain-Crawl Segment-Scope, 2026-07-20): Hat mehrere Kontakte mehrere Domains die unterschiedlichen Segmenten (Marken/Bereichen, siehe Verarbeitung 'SSOT Segment-Datenmodell') zugeordnet sind, wird der Re-Crawl jetzt pro Segment-Gruppe getrennt durchgeführt — sowohl der Crawl-Text als auch die an Anthropic übermittelte Vergleichsbasis bleiben je Lauf auf ein Segment beschränkt (verhindert Vermischung markenspezifischer Inhalte). Neue Spalte ssot_ai_suggestions.segment_id (nullable FK auf crm_segments, ON DELETE SET NULL) hält fest, aus welcher Segment-Gruppe ein Vorschlag stammt, und wird beim manuellen Akzeptieren auf die neue SSOT-Entität übertragen. Keine neue personenbezogene Datenkategorie, kein neuer Auftragsverarbeiter — reine Zuordnungs-/Scoping-Erweiterung derselben bereits beschriebenen Verarbeitung
- SSOT laufende Aktualisierung aus NEULAND-Aktivität (PROJ-1380): erweitert das KI-Vorschlags-Muster von einmaliger Befüllung (PROJ-1378) und manuellem Re-Crawl (PROJ-1379) um einen wöchentlichen, automatisierten Scan pro aktivem Kunden-Kontakt (contacts.status='aktiv') mit gepflegter SSOT. Verarbeitete Quellen: interne Kommentare (Kontakt/Projekt/Aufgabe), Deal-Notizen, Vertriebs-Gesprächsauswertungen, Meeting-Transkripte, Google-Drive-Dateiänderungen (inkl. OCR-Text). Scan-Fortschritt wird pro Kontakt in ssot_activity_scan_state (Zeitstempel-Merker, keine Inhalte) gespeichert. @Mention-Personenverweise werden vor jeder KI-Übermittlung aus ALLEN Quellen entfernt (zentraler anonymizeMentions()-Pass — QA-verifiziert nach einem initial unvollständigen Rollout). Zweistufige Confidence-Prüfung (Zuordnung zum Kunden + inhaltliche Änderungsrechtfertigung) vor Vorschlagserstellung. Kein automatisches Schreiben — jeder Vorschlag durchläuft eine manuelle Bestätigung; Kunden haben keinen Zugriff. Zusätzlich manueller Sofort-Trigger pro Kontakt (max. 3×/Tag). Aufbewahrung: wie PROJ-1378/1379 — Vorschläge bis zur manuellen Entscheidung, danach dauerhaft mit Status (Audit-Trail), Löschung mit dem zugehörigen Kontakt (CASCADE); Scan-Zustand ebenfalls CASCADE bei Kontakt-Löschung
KI-Mitarbeiter (autonome KI-Arbeitskräfte)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung), lit. f (berechtigtes Interesse an Automatisierung). Für CRM-Kontaktdaten Dritter (KI-Vertriebsassistent): Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter Vertriebssteuerung)
- Aufgabeninhalte und Kommentare als Kontext für KI-Ausführungen (Kommentar-Autoren werden anonymisiert)
- CRM-Kontaktdaten (Kontaktname, Firma, E-Mail, Pipeline-Stage) für KI-Vertriebsassistent — Klartext, da für Vertriebsanalyse erforderlich
- Ausführungsprotokolle: Trigger, Status, Dauer, Token-Verbrauch, Ergebnisdaten (Löschung nach 90 Tagen)
- KI-generierte Entwürfe und Kommentare (als solche gekennzeichnet, Aufbewahrung bis Workspace-Löschung)
- Token-Nutzungsprotokolle (Modell, Feature, Kosten): Aufbewahrung 12 Monate für Kostenauswertung
- PROJ-821 W-0.2 knowledge_documents (brand_asset + ssot_item Chunks): 1536-dim-Vektoren + content_plain + metadata. Workspace-scoped, CASCADE-DELETE bei Workspace-Löschung. Kein PII im Regelfall (Marken-Dokumente); Admins tragen Verantwortung für PII-freie Uploads.
- PROJ-822 W-0.3 workspace_auto_approve_actions (Workspace-Konfiguration zur Auto-Freigabe einzelner Worker-Tools): Pro Eintrag tool_name + created_by (Workspace-Admin). Kein PII — reine Konfigurations-Tabelle. CASCADE-DELETE bei Workspace-Löschung. Hardcoded-Blocklist verhindert kritische Tools (send_email, create_invoice, transfer_funds, delete_task, delete_contact) — diese erfordern stets menschliche Freigabe. ai_worker_actions.auto_approved-Flag dokumentiert pro Action-Eintrag, ob sie automatisch oder manuell freigegeben wurde (volle Audit-Spur erhalten).
- PROJ-823 W-0.4 Reject-Gründe auf ai_worker_actions: reject_reason (Enum: off_brand, factually_wrong, off_topic, wrong_format, sensitive_content, other) + reject_reason_text (optionaler Freitext, max 500 Zeichen). Workspace-interner Audit-Trail zur Worker-Qualitätssteuerung. Kein PII im Regelfall (Reasons beziehen sich auf Output-Qualität, nicht Personen). Freitext kann theoretisch Kundennamen enthalten falls Manager sie reinschreibt — akzeptables Restrisiko (Workspace-intern, RLS-geschützt, CASCADE-DELETE über execution_id). Felder ergänzen den bestehenden Datenexport (Art. 15/20 DSGVO). PROJ-1749 Fehler-Lern-Mechanismus (NEUER Datenfluss): reject_reason + reject_reason_text derselben Worker-Rolle (max. 3, 30-Tage-Fenster) werden jetzt zusätzlich als 'negative Beispiele' in den System-Prompt künftiger Ausführungen aufgenommen und damit an Anthropic übermittelt (derselbe Auftragsverarbeiter-Zweck 'KI-Mitarbeiter' wie die bereits dokumentierten positiven Few-Shot-Outputs, kein neuer Prozessor). Erhöht das oben genannte Freitext-Restrisiko leicht (Freitext kann jetzt in mehreren zukünftigen Prompts wiederverwendet werden, nicht nur einmalig gespeichert) — weiterhin akzeptabel, da Workspace-intern, RLS-geschützt und Reasons sich auf Output-Qualität statt Personen beziehen. PROJ-1807 (Fehler-Lern-Sichtbarkeit, NEUE Sichtbarkeitsstufe derselben Daten, kein neuer Empfängerkreis): Admin/Manager konnten bislang nur aggregierte Ablehnungs-Zahlen je Grund einsehen (z.B. „Markenstimme: 3x“); ab diesem Feature können sie zusätzlich die einzelnen zugrundeliegenden Fälle aufklappen (Aufgaben-Titel, KI-Output-Auszug bis 1.500 Zeichen, reject_reason_text im Klartext). Gleicher Empfängerkreis wie bisher (Admin+Manager desselben Workspace, keine Ausweitung), aber höhere Detailtiefe pro Aufruf. Kein neuer Auftragsverarbeiter, kein neuer Datenexport-Pfad — die Beispiel-Daten sind bereits über den bestehenden Workspace-Datenexport (Art. 15/20) abgedeckt.
- PROJ-830 W-0.5 Kunden-spezifische Worker (ai_workers.contact_id) + Kunden-Knowledge-Isolation (knowledge_documents.contact_id). Pro CRM-Kunde können eigene KI-Worker aktiviert werden — eigene Persona/System-Prompt, eigenes Token-Budget, isolierter Knowledge-Scope. RAG-Suche filtert auf den Kunden: Kunden-Worker sieht nur Brand-Assets + SSOT-Items dieses einen Kunden. Workspace-Worker (contact_id NULL) sehen weiterhin alle workspace-globalen Embeddings. Bei Kontakt-Löschung: knowledge_documents CASCADE (verwaiste Embeddings hart gelöscht); ai_workers SET NULL (Worker werden zu Workspace-Default degradiert, Audit-Spur bleibt). Kein neuer Auftragsverarbeiter — OpenAI-Embedding-Pipeline unverändert.
- PROJ-1744 Kommunikations-Berechtigungen (agency_access_mode/agency_access_roles/client_access/tax_advisor_access): Pro KI-Mitarbeiter granular konfigurierbar, wer ihn per @-Erwähnung ansprechen darf — Agentur-Mitglieder (alle, nur bestimmte Rollen, oder deaktiviert), Kunden im Kunden-Workspace (Opt-in, Default aus) sowie Steuerberater im Mandanten-Workspace (Opt-in, aktuell rein gespeichertes Feld ohne Wirkung — im Mandanten-Portal existiert noch kein Kommunikationskanal). Reine Zugriffssteuerungs-Konfiguration, keine neue Datenkategorie. Relevanter NEUER Datenfluss: War die @-Erwähnung eines KI-Mitarbeiters aus einem Kunden-Kommentar zuvor strukturell unmöglich (harte Sperre), kann bei aktiviertem client_access jetzt auch der Kommentarinhalt eines Kunden-Workspace-Mitglieds als Kontext an die KI-Ausführung (und damit an Anthropic, siehe Kommentar-Autoren-Anonymisierung oben) übermittelt werden — deckungsgleiche Verarbeitung wie beim bestehenden Agentur-Trigger-Pfad, nur um eine weitere berechtigte Auslöser-Gruppe erweitert. Serverseitig fail-closed durchgesetzt (Rollen-Prüfung live bei jedem Trigger-Versuch, kein Caching). Keine neue Rechtsgrundlage nötig (Art. 6 Abs. 1 lit. b DSGVO, Vertragserfüllung im Kundenverhältnis).
- PROJ-1773 KI-Mitarbeiter-Aktionen im Projekt-Änderungsverlauf (NEUER Sichtbarkeits-Datenfluss, keine neue Datenkategorie): Ausgewählte fachliche Worker-Aktionen (Status-Änderung, Handoff an einen anderen Worker, Freigabe-Anfrage, Confidence-Fallback an einen Menschen, dauerhafter Ausführungsfehlschlag) erzeugen ab Deploy zusätzlich einen Eintrag im bestehenden, allgemeinen activity_log der betroffenen Aufgabe (entity_type=task, actor_id=NULL, metadata.ai_worker_id/ai_worker_name/execution_id). Dadurch werden diese bereits in ai_worker_actions/Ausführungsprotokollen gespeicherten Vorgänge jetzt auch für alle Projekt-/Workspace-Mitglieder mit Lesezugriff auf die jeweilige Aufgabe sichtbar (Kommunikations-Timeline) statt nur für Admins im Bereich Einstellungen → KI-Mitarbeiter — die Sichtbarkeit folgt exakt der bestehenden workspace-scoped, RLS-geschützten activity_log-Sichtbarkeit menschlicher Einträge, es entsteht keine neue Exposition gegenüber externen Empfängern. Der KI-Mitarbeiter-Name ist keine natürliche Person. In metadata werden zwei Freitextfelder mitgeschrieben: reason der Freigabe-Anfrage (max 500 Zeichen) und error bei dauerhaftem Fehlschlag (max 200 Zeichen) — analog zum reject_reason_text-Restrisiko oben: kein PII im Regelfall, ein theoretisch möglicher Kundenbezug bleibt workspace-intern und RLS-geschützt. Handoff- und Confidence-Fallback-Einträge enthalten bewusst KEINE Kontext-/Aufgabenzusammenfassung, nur Worker-IDs/-Namen und kategorische Felder. Rein additiv, kein Backfill historischer Aktionen. Die Einträge sind über den bestehenden activity_log-Datenexport (Art. 15/20, R-241) abgedeckt und kaskadieren bei Workspace-/Aufgaben-Löschung mit; bei Löschung des referenzierten KI-Mitarbeiters oder der Ausführung bleibt der Audit-Eintrag mit dem metadata-Namens-Snapshot bestehen (Revisionssicherheit, keine FK auf ai_workers).
Template-Engine & KI-Asset-Generierung
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter Content-Produktion)
- Template-Definitionen: Ebenen-Konfigurationen (Position, Größe, Stil, Inhalte) — i.d.R. keine personenbezogenen Daten
- KI-generierte Marketing-Texte (Headline, Subline, CTA, Body, Hashtags): Gespeichert als JSONB in der Datenbank. Marketing-Briefing-Daten (Thema, Tonalität, Keywords, Key Message) werden anonymisiert (sanitizePii) an Claude (Anthropic) übermittelt
- KI-generierte Bild-Prompts: Ein englischsprachiger Prompt wird aus dem Marketing-Text abgeleitet und an OpenAI DALL-E 3 gesendet — keine personenbezogenen Daten enthalten
- Exportierte Asset-Dateien (PNG/JPG): Werden in Supabase Storage gespeichert. Löschung bei Workspace-Löschung via CASCADE oder manuell durch den Nutzer
- Generierungs-Metadaten: Zeitstempel und Nutzer-ID des Generierenden. Nutzer-ID wird bei Account-Löschung auf NULL gesetzt (SET NULL FK-Constraint)
- API-Key-Speicherung für externe Bildmodelle: Verschlüsselt mit AES-256-GCM, nur letzte 4 Zeichen sichtbar. Nur Workspace-Admins können Keys verwalten
- Token-Nutzungsprotokolle: Modell, Feature-Typ (asset_generation_text / asset_generation_image), geschätzte Kosten. Aufbewahrung: 12 Monate
KI-generierte Persona-Profilbilder (PROJ-368)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an visueller Persona-Darstellung)
- Persona-Beschreibungsdaten (Name, Alter, Geschlecht, Beruf, Wohnort, Beschreibung): Werden als englischsprachiger Bild-Prompt an OpenAI GPT Image 1 übermittelt. Es handelt sich um fiktive Persona-Daten, keine echten Personen
- KI-generierte Persona-Bilder (PNG, 1024x1024): Werden in Supabase Storage (EU-Region) gespeichert. Pfad: {workspace_id}/{persona_item_id}.png. Löschung bei Neugenerierung (Überschreibung) oder via Cleanup-Cron nach 30 Tagen wenn zugehörige Persona gelöscht wurde
- Token-Nutzungsprotokolle: Feature-Typ persona_image_generation, Modell gpt-image-1, Kosten pro Bild. Aufbewahrung: 12 Monate
Dokumentenmanagementsystem (DMS)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung), lit. f (berechtigtes Interesse an effizienter Dokumentenverwaltung), lit. a (Einwilligung) für E-Mail-Posteingang
- Hochgeladene Dokumente (Rechnungen, Verträge, Belege, Kontoauszüge)
- OCR-extrahierte Metadaten (Lieferant, Betrag, Datum, Rechnungsnummer) — extrahiert durch KI (Claude Vision)
- Dokumenten-Tags und Kategorisierung
- Freigabeinformationen für Steuerberater
- PROJ-876 Granulare Ordner-Freigabe (dms_folder_shares): Vertrauliche Ordner können vom Workspace-Admin gezielt für einzelne Workspace-Mitglieder freigegeben werden (statt nur 'nur für Admins sichtbar'). Gespeichert wird die Verknüpfung freigegebenes Mitglied (user_id) ↔ Ordner (folder_id) sowie wer die Freigabe erteilt hat (created_by) und der Zeitpunkt. Zweck: feingranulare Zugriffssteuerung auf vertrauliche Dokumente (z.B. persönliche Steuerunterlagen einzelner Personen). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an differenzierter Zugriffskontrolle). Durchsetzung über RLS mit Vererbung auf Unterordner und Dateien. RLS-Sichtbarkeit: nur Admins und die explizit freigegebenen Mitglieder sehen den Ordner und dessen Inhalte. CASCADE-Löschung bei Ordner-Löschung, Workspace-Löschung und beim Ausscheiden des Mitglieds aus dem Workspace; beim Zurückstellen eines Ordners auf nicht-vertraulich werden alle Mitglieder-Freigaben entfernt
- E-Mail-Posteingang (automatischer Import): Workspace-Admins können ein persönliches Google-Konto als DMS-Posteingang konfigurieren. Alle 10 Minuten werden E-Mail-Anhänge (Rechnungen, Belege, Dokumente) automatisch in das DMS importiert. Gespeicherte Herkunfts-Metadaten pro importiertem Dokument: Absender-E-Mail-Adresse, E-Mail-Betreff, Empfangsdatum. Es werden ausschließlich Dateianhänge importiert — der E-Mail-Text wird weder gelesen noch gespeichert. Die E-Mail bleibt nach dem Import unverändert im Posteingang (kein Archivieren, kein automatisches als-gelesen-Markieren); nur wenn der Workspace-Admin eine Filterregel auf 'als gelesen markieren' stellt, wird sie als gelesen markiert. Der Gmail-API-Zugriff erfolgt über das persönliche OAuth-Token des konfigurierenden Admins (PROJ-127). Import-Protokoll: Gmail-Nachrichten-ID, Status (importiert/fehlgeschlagen/übersprungen), Fehlermeldung (technisch). Aufbewahrung Import-Protokoll: 12 Monate, danach automatisch bereinigt
- PROJ-900 Multi-Konto-Posteingang & Filterregeln (workspace_dms_inbox, email_filter_rules mit Aktion 'Ins DMS importieren'): Der DMS-Posteingang kann mehrere Google-Konten gleichzeitig als Quelle nutzen — eigene Konten des verwaltenden Admins sowie über google_token_shares workspace-geteilte Postfächer (z.B. ein gemeinsames Buchhaltungs-Postfach). Pro aktiviertem Konto werden die Konto-E-Mail-Adresse (google_account_email) und ein Standard-Zielordner gespeichert. Filterregeln (Kriterien: Absender exakt, Absender-Domain, Betreff-Bestandteil, Anhang-Typ) bestimmen, in welchen DMS-Ordner die Anhänge passender E-Mails importiert werden (erste passende Regel gewinnt); ohne Treffer greift der Standard-Zielordner. Erhöhter Sichtbarkeits-Scope bei geteilten Postfächern: Importierte Anhänge werden im Ziel-Workspace abgelegt und unterliegen dessen DMS-Berechtigungen (Ordner-Sichtbarkeit und -Freigaben, siehe PROJ-876). Wird ein gemeinsames Postfach genutzt, können dadurch mehr Personen die importierten Dokumente einsehen als bei einem rein persönlichen Postfach — die importierten Daten externer Absender (Dateianhänge, Absender-E-Mail-Adresse, Betreff, Empfangsdatum) sind damit allen im Ziel-Ordner berechtigten Workspace-Mitgliedern zugänglich. Die Verantwortung für die Rechtmäßigkeit der Weiterverarbeitung von Anhängen Dritter trägt der Workspace-Betreiber. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter, regelbasierter Dokumentenablage). Verwaltung der Quell-Konten und Filterregeln durch Workspace-Admin/Manager; seit PROJ-1372 zusätzlich Selbstverwaltung durch einzelne Mitarbeiter für ihr eigenes Postfach (siehe eigener PROJ-1372-Eintrag unten). Keine neue Datenkategorie und kein neuer Auftragsverarbeiter gegenüber dem bestehenden E-Mail-Posteingang (Gmail-API/Google LLC, persönliches OAuth-Token); Idempotenz (dms_email_import_log) und 12-Monats-Aufbewahrung des Import-Protokolls gelten unverändert. Bei Trennung/Widerruf eines Konto-Zugriffs schlägt der Sync für dieses Konto fehl und der Workspace-Admin wird benachrichtigt
- PROJ-1372 Mitarbeiter-Self-Service-Ablage-Regeln (email_filter_rules mit Aktion 'Ins DMS importieren', angelegt in den persönlichen Profileinstellungen statt durch einen Workspace-Admin): Jedes aktive Workspace-Mitglied kann für sein eigenes oder ein mit ihm geteiltes Google-Konto eine eigene Ablege-Regel erstellen, ohne dass ein Admin das Postfach vorab freischalten muss — die Quelle wird automatisch in workspace_dms_inbox aktiviert (Modus 'nur bei Regel-Treffer ablegen', bestehende Admin-Konfigurationen bleiben unverändert). Erweiterter Sichtbarkeits-Scope: Workspace-Admins/-Manager sehen zusätzlich zu ihren eigenen Regeln eine read-only Governance-Übersicht aller Mitarbeiter-Regeln ihres Workspace (Name des Erstellers, Postfach-E-Mail-Adresse, Kriterien-Zusammenfassung, Zielordner) und können eine Regel bei Missbrauch deaktivieren oder löschen, aber nicht inhaltlich bearbeiten oder das Postfach selbst einsehen. Wird eine Regel moderiert, erhält der Ersteller eine Inbox-Benachrichtigung mit Verweis auf die betroffene Regel. Verliert ein Mitarbeiter die aktive Mitgliedschaft im Ziel-Workspace, wird seine Regel automatisch deaktiviert (Datenbank-Trigger, greift unabhängig vom Entfernungsweg). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an dezentraler, aber für den Workspace nachvollziehbarer Dokumentenablage). Keine neue Datenkategorie und kein neuer Auftragsverarbeiter gegenüber dem bestehenden PROJ-900-Posteingang. RLS auf workspace_dms_inbox/dms_folders bleibt unverändert Admin-only als Datenbank-Schutzebene; die erweiterte Berechtigung (aktive Mitgliedschaft statt Admin-Rolle) wird ausschließlich auf Anwendungsebene durchgesetzt, mit serverseitiger Wiederholungsprüfung der Workspace-Mitgliedschaft bei jeder Regel-Erstellung/-Änderung
- PROJ-977 Regelbasierte Weiterleitung samt Anhang (email_filter_rules.action_config.forward_to): Zu einer Ablege-Filterregel kann der Workspace-Admin/Manager optional eine oder mehrere Empfänger-E-Mail-Adressen hinterlegen (max. 10). Trifft die Regel auf eine eingehende E-Mail zu, wird diese — zusätzlich zum Import der Anhänge — samt allen Original-Anhängen an die konfigurierten Adressen weitergeleitet. Der Versand erfolgt über das verbundene Google-Konto der Regel via Gmail-API (gleiches persönliches OAuth-Token wie beim Posteingang-Import) — KEIN neuer Auftragsverarbeiter gegenüber dem bestehenden E-Mail-Posteingang (Gmail-API/Google LLC). NEUER Empfänger-Datenfluss: Die Weiterleitungs-Adressen sind vom Workspace-Admin frei bestimmte Dritte und können außerhalb der Plattform bzw. außerhalb der EU liegen; an sie werden der E-Mail-Inhalt und die Anhänge (potentiell personenbezogene Daten externer Absender) übermittelt. Die Verantwortung für die Rechtmäßigkeit dieser Weiterleitung (Empfängerauswahl, Rechtsgrundlage, ggf. erforderliche Vereinbarungen) trägt der Workspace-Betreiber. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an regelbasierter Dokumenten-Verteilung). Idempotenz und Diagnose über dms_email_import_log (forward_status, forwarded_at, redigierte forward_error ohne Empfängerliste/Inhalt) — pro E-Mail höchstens eine erfolgreiche Weiterleitung; 12-Monats-Aufbewahrung des Import-/Forward-Protokolls wie beim Posteingang. Rückwirkender Import (Backfill) einer Ablege-Regel leitet bewusst NICHT weiter — außer der Workspace-Admin aktiviert die Weiterleitung im Backfill-Dialog ausdrücklich (Opt-in, Standard aus). Klarstellung (PROJ-1633-Bugfix, 04.08.2026): Davon zu unterscheiden ist eine Regel, deren Aktion selbst 'Weiterleiten' ist (allein oder als Teil einer gebündelten Multi-Aktion) — beim rückwirkenden Anwenden einer solchen Regel werden die getroffenen E-Mails tatsächlich an die konfigurierten Empfänger versendet, in derselben Verantwortung des Workspace-Betreibers wie beim laufenden Betrieb. Pro Regel und E-Mail ist höchstens ein rückwirkender Versand möglich (Sperre über email_filter_rule_backfill_log), auch bei mehrfacher Ausführung. Nur Ablege-Regeln (include) leiten weiter; Ausschluss-Regeln nie. Konfiguration ausschließlich durch Workspace-Admin/Manager. Im Datenexport (Art. 15/20 DSGVO) als Teil von email_filter_rules und dms_email_import_log enthalten
- Gelöschte Dokumente werden 30 Tage im Papierkorb aufbewahrt und danach endgültig aus Datenbank und Dateispeicher entfernt
- PROJ-877/899 Steuer-Checklisten (dms_est_checklists, dms_est_checklist_items, dms_est_document_links, dms_checklist_types, dms_checklist_type_default_items, dms_document_tax_year_override): Strukturierte Checklisten zur Vorbereitung steuerlicher Unterlagen, je nach Typ — Einkommensteuer, Umsatzsteuer, Körperschaftsteuer, Gewerbesteuer, Jahresabschluss/Buchführung, Lohnsteuer oder freie Checkliste (datengetriebene Typ-Registry). Der Personenbezug folgt dem Typ: Personen-Checklisten sind einem Workspace-Mitglied zugeordnet (owner_user_id), Unternehmens-Checklisten sind workspace-/unternehmensweit ohne Einzelpersonenbezug. Genau eine Checkliste pro Steuerart (bei Personen-Typen zusätzlich pro Inhaber), jahresübergreifend — mit Punkten (Standard aus der Typ-Registry + custom), optionaler Einreichungsfrist und logischen Zuordnungen von DMS-Dokumenten zu Checklisten-Punkten (Status, KI-Konfidenz, KI-Begründung). Das Steuerjahr eines Dokuments wird automatisch aus dem per OCR erkannten Belegdatum abgeleitet; eine manuelle Übersteuerung wird in dms_document_tax_year_override gespeichert (Dokument-ID, Steuerjahr, setzende Person). Das erkannte Jahr dient nur der Gruppierung der Dokumente in der Detailansicht (kein eigener Ordner/keine eigene Checkliste pro Jahr). Zweck: strukturierte Steuervorbereitung und Übergabe an den Steuerberater. Steuerrelevanz-Klassifikation per KI (Anthropic Claude Haiku, siehe PROCESSORS-Eintrag) auf Basis des OCR-Texts — nur on-demand bzw. für die OCR-fertigen Dokumente im als Quelle gewählten Ordner (jahresübergreifend, nicht pauschal über alle Ordner). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an strukturierter Steuervorbereitung). RLS: Personen-Checklisten ausschließlich Inhaber und Workspace-Admins, Unternehmens-Checklisten Workspace-Admins/Manager; die Typ-Registry ist lesbare, nicht-personenbezogene Referenzdaten. Sichtbar nur für diese; nicht in der globalen Suche. CASCADE-Löschung bei Workspace-, Checklisten-, Dokument- oder Nutzer-Löschung (auch beim Ausscheiden aus dem Workspace); beim Löschen einer Checkliste werden Punkte und Zuordnungen entfernt — die DMS-Dokumente selbst bleiben unverändert erhalten. Die Zuordnung ist rein logisch (kein Kopieren/Verschieben von Dateien)
Proof-System (Korrektur-Workflow)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) — Proof-Workflows sind wesentlicher Bestandteil der Agentur-Kunden-Dienstleistung (Korrektur- und Freigabeprozesse)
- Proof-Dateien: PDF (max. 100 MB), Bilder (PNG, JPG, WEBP, SVG; max. 50 MB), Videos (MP4, MOV, WEBM; max. 500 MB). Gespeichert in privatem Supabase Storage Bucket mit Verschlüsselung at-rest. Zugriff ausschließlich über zeitbegrenzte signierte URLs (24 Stunden Gültigkeit) — keine öffentlichen URLs
- Proof-Metadaten: Titel, Medientyp, Status, Versionsnummer, Ersteller (User-ID), zugeordneter Kontakt, Erstelldatum
- Versionierung: Jede Proof-Überarbeitung wird als neue Version gespeichert (V1, V2, …). Alte Versionen bleiben für den Vergleich erhalten, werden aber als inaktiv markiert
- Pin-Kommentare: Positionsbasierte Korrekturmarkierungen auf dem Proof-Medium (x/y-Koordinaten in Prozent, Seitenzahl bei PDF, Zeitstempel bei Video). Kommentartext als Freitext, Ersteller (User-ID oder Kontakt-ID), Status (offen/erledigt)
- Pin-Antworten: Textuelle Antworten auf Pin-Kommentare, Ersteller (User-ID oder Kontakt-ID)
- Interne Reviewer: Zugewiesene Workspace-Mitglieder für die interne Freigabe, Entscheidungsstatus (ausstehend/freigegeben/Änderungen angefordert), Zeitpunkt der Entscheidung
- Korrektur-Runden: Protokoll der eingereichten Korrekturen mit Rundennummer, optionaler Notiz und Einreicher (User-ID oder Kontakt-ID)
- Kunden-Portal-Zugriff: Kunden können über einen Token-Link (ohne Login) ihre zugeordneten Proofs einsehen, Korrekturen markieren und Freigaben erteilen. Die IP-Adresse wird nur in-memory für Rate-Limiting verwendet und nicht gespeichert
- Löschung: Bei Löschung eines Proofs werden alle zugehörigen Versionen, Pins, Antworten, Reviewer-Zuweisungen und Korrektur-Runden automatisch gelöscht (CASCADE). Bei Löschung eines Kontakts oder Users werden die Referenzen anonymisiert (SET NULL)
CMS & Website-Builder
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) für Seitenverwaltung; Art. 6 Abs. 1 lit. a DSGVO (Einwilligung) für YouTube-Einbettung und Formular-Einsendungen; Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse) für Download-Tracking
- Seiteninhalte, Vorlagen und SEO-Metadaten (redaktionelle Daten, keine personenbezogenen Daten i.d.R.)
- Mediathek: Hochgeladene Bilder und Dokumente, Datei-Metadaten (Dateiname, Alt-Text). Zugriff über zeitbegrenzte signierte URLs (1 Stunde Gültigkeit)
- Formulare: Feld-Definitionen und Konfiguration (keine personenbezogenen Daten)
- Formular-Einsendungen: Alle vom Website-Besucher eingegebenen Daten (z.B. Name, E-Mail, Telefon, Freitext). Speicherung bis zur manuellen Löschung durch den Workspace-Administrator
- IP-Adresse bei Formular-Einsendung und Download-Tracking: Wird als SHA-256-Hash gespeichert (pseudonymisiert, nie im Klartext). Zweck: Spam-Schutz, Rate-Limiting und Deduplizierung von Download-Zählern. Bei Downloads: Kurzfristig im flüchtigen Server-Cache (max. 1 Stunde), keine dauerhafte Speicherung
- Bestätigungs-E-Mail: Wenn vom Formular-Ersteller aktiviert, wird die im Formular eingegebene E-Mail-Adresse an den E-Mail-Dienstleister (Resend) zur Zustellung der Bestätigungs-E-Mail übermittelt
- Download-Tracking: Bei Datei-Downloads wird ein anonymer, aggregierter Zähler inkrementiert (keine Zuordnung zu einzelnen Nutzern möglich). Zweck: Beliebtheitsmessung für den Website-Betreiber
- Video-Galerie mit YouTube-Einbettung: YouTube-Videos werden erst nach expliziter Einwilligung des Besuchers geladen (Consent-Overlay). Es wird die datenschutzfreundliche Domain youtube-nocookie.com verwendet. Die Einwilligung wird im Cookie 'yt_consent' (30 Tage) gespeichert. Durch das Laden des YouTube-Players können von Google/YouTube Cookies gesetzt und IP-Adressen verarbeitet werden
- Autorennamen in News- und Blog-Artikeln: Wenn ein Autorenname im CMS-Eintrag hinterlegt ist, wird dieser auf der öffentlichen Website angezeigt und in Schema.org JSON-LD (Article/Event) als strukturierte Daten eingebettet. Suchmaschinen können diese Daten indexieren. Die Angabe des Autorennamens ist freiwillig und kann jederzeit vom Content-Editor entfernt werden
- PROJ-592 Block- & Page-Versionierung (cms_block_versions, cms_page_versions): Jeder Save eines CMS-Blocks oder einer CMS-Seite erzeugt einen vollständigen Inhalts-Snapshot (Block-Inhalt bzw. Page-Meta + Block-Tree-Reihenfolge) zur Wiederherstellbarkeit nach versehentlichen Änderungen. Snapshot enthält ggf. die im Block redaktionell hinterlegten Inhalte (z.B. Kunden-Testimonials mit Klarnamen, Personenbilder), wenn diese im Block stehen. Aufbewahrung: 90 Tage für automatische Versionen (täglicher Cleanup-Cron cms-version-cleanup), unbegrenzt für manuelle Snapshots (mit Pflicht-Beschreibung), CASCADE-DELETE bei Block-/Seite-/Workspace-Löschung. RLS: workspace-scoped, nur Workspace-Mitglieder (admin/manager/member) sehen Versionen, Endkunde nicht. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an redaktioneller Datensicherung)
- PROJ-592 Soft-Delete-Konzept (cms_pages.deleted_at): Page-Löschungen sind 30 Tage rückgängig zu machen (deleted_at-Timestamp wird gesetzt, Page verschwindet aus allen User-sichtbaren Listen, Public-Render und Sitemap). Hard-Delete vor Ablauf der 30 Tage nur durch Workspace-Admin (DELETE /pages/[id]/permanent). Nach 30 Tagen werden soft-deleted Pages durch den Cleanup-Cron hart gelöscht (CASCADE auf Blocks, Versions und Audit-Log)
- PROJ-592 Audit-Log (cms_audit_log): Alle versions- und lifecycle-relevanten Aktionen (Restore, manueller Snapshot, Soft-Delete, Hard-Delete, Cron-Cleanup) werden mit User-ID, Timestamp und Aktion protokolliert. Aufbewahrung: dauerhaft (kein Cleanup) für Compliance- und Nachvollziehbarkeitszwecke. Sichtbar nur für Workspace-Admin und Manager. CASCADE-DELETE bei Workspace-Löschung
- PROJ-596 Higgsfield AI On-Brand Bild-Generator (cms_higgsfield_jobs, workspace_higgsfield_settings, workspace_higgsfield_usage, platform_higgsfield_config): KI-gestützte Bildgenerierung für CMS-Blocks im 2-Phasen-Adapter-Pattern. Phase 1 (jetzt aktiv): MockHiggsfieldAdapter rendert deterministische SVG-Test-Bilder lokal — keine Datenübermittlung. Phase 2 (nach DPA-Bestätigung durch Plattform-Admin + Setzen von adapter_mode='live'): RealHiggsfieldAdapter sendet sanitisierte User-Prompts + On-Brand-Constraints (CI-Farben + Brand-Style aus SSOT) an Higgsfield Inc. Hardcoded Wordlist-Filter (Personen-Namen, NSFW, Markenrechte) blockt vor Übermittlung. Pro Generierungs-Aufruf 3 Bild-Varianten, max. 50/Monat/Workspace (Default, konfigurierbar). Klartext-Prompts werden 30 Tage in cms_higgsfield_jobs.prompt_text_temp gehalten (für Audit), danach durch Cleanup-Cron auf NULL gesetzt — Hash bleibt für Deduplication. Generierte Bilder werden als brand_assets gespeichert (is_ai_generated=true, ai_generated_by='higgsfield' für EU AI Act Art. 50 Transparenzkennzeichnung). Workspace-Aktivierung pro Endkunde durch Agentur-Admin (workspace_higgsfield_settings.enabled). PROJ-675 Bildformat-Output-Metadaten: cms_higgsfield_jobs erfasst zusätzlich output_format_kind (ratio/render), output_render_format (RenderFormatKey aus PROJ-641-Liste bei kind=render), output_width und output_height (Pixel-Zielmaße für Sharp-Resize-Pipeline). Diese 4 Spalten enthalten ausschließlich technische Pixel-Metadaten, keine PII. Sie ermöglichen Re-Generate-Workflows und Audit der Output-Auflösung. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (effiziente Content-Produktion). RLS: workspace-scoped (admin/manager/member SELECT, alle Writes via Service-Role). CASCADE-DELETE bei Workspace-Löschung. Quota wird täglich am 1. jedes Monats via pg_cron zurückgesetzt
- PROJ-588 Component Lab Global Sync (pending_master_component_updates, master_component_sync_log, vw_component_adoption): Workspace-Admin-getriebener Update-Mechanismus für Master-Komponenten aus dem Component Lab. 15-Min-pg_cron erkennt outdated (Workspace × Komponente × Ziel-Version)-Tripel und legt Pending-Eintrag idempotent an. AST-Diff-Engine (TypeScript-Compiler-API) extrahiert Prop-Schema aus TSX-Code und klassifiziert Änderungen als kompatibel oder breaking. Workspace-Admin sieht Update-Manager mit Diff-Vorschau (Side-by-Side iFrame mit Workspace-CI + AST-Prop-Diff) und entscheidet pro Komponente. Sync-Transaktion atomar: cms_blocks.master_component_version_id wird auf neue Version aktualisiert, content JSONB bleibt unverändert (lokale Anpassungen erhalten). Audit-Trail in master_component_sync_log dauerhaft. Plattform-Admin-Adoption-Übersicht (Materialized View) zeigt Cross-Workspace-Versions-Verteilung — interner Use-Case ohne Endkunden-PII. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO. RLS: workspace-scoped Pending-Updates (admin SELECT/UPDATE, manager SELECT-only), Adoption-View nur Plattform-Admin. CASCADE bei Workspace-Löschung. Daily-batched Notifications (1× pro Tag pro Workspace, AC-5)
- PROJ-587 AI Site Planner mit Wireframe-Freigabe (ai_site_planner_jobs): Zweistufiger KI-Flow zur Erzeugung neuer CMS-Landingpages. Phase 1 (synchron, ≤30s): Agentur-Admin/Manager wählt Bedarfsgruppen + optional Personas + freie Stichworte aus SSOT — Claude Haiku 4.5 generiert ein strukturiertes Wireframe (5–12 Sections mit Name, Purpose, target_component_type) als Skizze. Wireframe-Editor erlaubt Drag-Drop, Inline-Edit, Section-Reformulierung. Phase 2 (asynchron, 60–180s, pg_cron-Worker alle 2 Min): Nach expliziter Freigabe (admin/manager) erzeugt Claude Sonnet 4.5 pro Section deutsche Marketing-Inhalte und befüllt eine neue cms_pages-Seite (status='draft'). Übermittelte SSOT-Daten (Bedarfsgruppen, Personas, USPs, CI-Tone) werden vor Anthropic-Calls via sanitizePii() bereinigt. Keine Endkunden-Daten — nur Agentur-eigene Marketing-Intelligenz. Aufbewahrung: ai_site_planner_jobs unbegrenzt (Audit-Trail für Cloudcode-Generierungen), CASCADE-DELETE bei Workspace-Löschung. RLS: workspace-scoped, nur Workspace-Mitglieder (admin/manager/member) sehen Jobs, Endkunde nie. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter Content-Produktion). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung an erzeugten Pages und Wireframes
- PROJ-590 Visual Theme-Editor / Layout-Regeln (cms_layout_tokens, cms_layout_tokens_audit, cms_blocks.theme_overrides): Workspace-Admin/Manager pflegt globale Layout-Tokens (Grid-Spalten, Gutter, Container-Max, Side-Padding, Spacing-7-Stufen-Skala xs–2xl, Radius-5-Tokens none/sm/md/lg/full) als CSS-Custom-Properties. Default-Set (19 Tokens) wird via Trigger bei jeder neuen Workspace-Anlage geseedet. CMS-Public-Renderer injiziert :root-Variablen pro Page-Render in den HTML-Head — keine PII, nur Layout-Konfiguration (Pixel-/REM-Werte, Token-References). Audit-Tabelle protokolliert jede Änderung mit user_id (FK ON DELETE SET NULL), token_path, alt-/neu-JSONB-Snapshot, Zeitstempel — personenbezogen via user_id. Aufbewahrung: cms_layout_tokens unbegrenzt (Workspace-Konfiguration); cms_layout_tokens_audit unbegrenzt für Compliance-Nachvollziehbarkeit, im DSGVO-Datenexport enthalten. RLS: cms_layout_tokens SELECT alle Workspace-Mitglieder + Endkunden, UPDATE/INSERT/DELETE nur admin/manager; cms_layout_tokens_audit SELECT nur admin/manager. CASCADE-DELETE bei Workspace-Löschung. PROJ-999 Domain+Stage-Scope (cms_layout_tokens.site_id, cms_layout_tokens_audit.site_id, FK cms_sites): Layout-Tokens koennen seit PROJ-999 pro Domain+Stage (cms_sites, Spalte environment live/staging) gescopet werden — site_id NULL bedeutet Workspace-Default-Ebene (Fallback), site_id = UUID bedeutet ein Domain+Stage-spezifischer Override. Der Audit-Trail erfasst den Domain+Stage-Kontext (site_id) zusaetzlich. Kein neues personenbezogenes Datum, nur eine feinere Scope-Ebene der Layout-Konfiguration. PROJ-88 Border-Radius-Migration: bestehende cms_sites.settings.theme.border_radius wurden 1:1 in cms_layout_tokens.radius.md übertragen. PROJ-776 Erweiterung 10-Slot-Farbpalette (cms_sites.settings.theme.colors + colors_meta, JSONB-Sub-Objekt): Pro CMS-Site speichert der Workspace-Admin/Manager 10 kanonische Farb-Slot-Werte (primary, secondary, third, fourth, fifth, sixth, cta, light, dark, background) als Hex-Strings oder null. Pflicht-Slots primary + background, andere 8 optional. Zusätzlich colors_meta pro Slot mit ssot_item_id (UUID des verknüpften SSOT-Items, falls aus SSOT gepullt) + ssot_pulled_at (Zeitstempel des letzten Pulls). Werte werden als --cms-color-<slot>-CSS-Variablen vom Public-Renderer ausgespielt — keine PII, nur Brand-/Design-Konfiguration. Initialer Pull aus ssot_items (section=ci_color) beim ersten Tab-Öffnen, danach CMS-Wert ist die Wahrheit; bidirektionaler Sync nur auf explizite User-Entscheidung pro Save-Vorgang (siehe DATA_PROCESSING-Eintrag für SSOT CI). Audit über bestehende cms_audit_log-Tabelle (action=cms_site.theme_colors_update bzw. _pull bzw. _sync_to_ssot). Cross-Repo-Sync (R-777): der Hetzner-CMS-Renderer spiegelt die generateThemeCss-Logik. Keine zusätzliche Datenkategorie gegenüber dem Theme-Editor-Bestand — Farbpalette ist Brand-Design, kein personenbezogenes Datum. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an konsistenter CI-Vererbung über alle CMS-Seiten)
- PROJ-595 Workspace-lokale Komponenten-Bibliothek (cms_local_components, cms_blocks.local_component_id): Workspace-Admin/Manager legen eigene CMS-Komponenten an (component_type aus 6-Werte-Enum, content_jsx, prop_schema). Komponenten haben Workflow-Status (draft → submitted → under_review → promoted/rejected/cancelled). Bei Promotion durch Plattform-Admin: atomic Postgres-RPC promote_local_component_to_master() — Master-Komponente in lab_components/lab_component_versions erzeugt, alle cms_blocks-Verwendungen via Hot-Swap auf master umgestellt (component_source='master', master_component_id=neu, local_component_id=NULL), promoted_to_master_component_id-Backlink gesetzt. submitted_by_user_id, reviewed_by_agency_user_id, created_by_user_id alle FK ON DELETE SET NULL auf auth.users. RLS: cms_local_components SELECT alle Workspace-Mitglieder, INSERT/UPDATE/DELETE admin/manager des Workspaces; Cross-Workspace-Promotion-Queue-Sicht nur Plattform-Admin (via isPlatformAdmin()). 3 neue Notification-Types (master_component_promotion_requested/_approved/_rejected) im notifications_type_check via Rollup-Migration registriert (R-686), mit voller R-265 Stellen-Sync (NOTIFICATION_TYPES + NOTIFICATION_TYPE_CONFIG + Zod-Enum). CASCADE-DELETE bei Workspace-Löschung. Aufbewahrung: unbegrenzt (Workspace-Konfiguration), promotete Komponenten haben Backlink im lab_components-Eintrag. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an wiederverwendbaren Workspace-Komponenten + Cross-Workspace-Sharing über Promotion-Workflow)
- PROJ-594 Multi-Layout Theme Manager (cms_layouts, cms_pages.layout_id): Workspace-Admin/Manager pflegt mehrere Seitenlayouts pro Workspace (Header/Footer-Komponenten-Referenzen, Container-Max-Width, Section-Spacing-Override, Background-Config). Standard-Seitenlayouts (Startseite/Landingpage/Bereichsleitseite/Detailseite) werden via Trigger bei jeder neuen Workspace-Anlage geseedet. Bestehende Workspaces wurden via Backfill-Migration mit denselben 4 Seitenlayouts versehen + alle existing Pages auf 'Detailseite'-Default umgehängt. Seitenlayout-Properties werden zur Render-Zeit als CSS-Custom-Properties (--cms-container-max, --cms-section-spacing, --cms-page-background, --cms-page-background-image) auf der Public-Page injiziert — keine PII, nur Seitenlayout-Konfiguration (Pixel-/REM-Werte, Hex-Farben, Storage-URLs). created_by/updated_by FK auf auth.users (ON DELETE SET NULL). RLS: SELECT alle Workspace-Mitglieder, INSERT/UPDATE/DELETE nur admin/manager, set-default nur admin. CASCADE-DELETE bei Workspace-Löschung; ON DELETE SET NULL für lab_components-FKs (Header/Footer-Komponenten); cms_pages.layout_id ON DELETE SET NULL — beim Löschen eines Seitenlayouts werden Pages auf das Default-Seitenlayout umgehängt. Aufbewahrung: unbegrenzt (Workspace-Konfiguration). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an konsistenter Seitenlayout-Vererbung)
- PROJ-593 Smart Frontend-Inline-Editor (cms_block_versions.source-Spalte): Eingeloggte Workspace-Mitglieder (admin/manager/member) editieren Public-CMS-Seiten direkt im Browser ohne Wechsel in den Backend-Editor. Click-to-Edit-Surface auf Headlines/Sublines/CTA-Texten (contentEditable + Optimistic-Lock via cms_blocks.updated_at), Klick auf Bild öffnet Markenassets-Picker, Drag-and-Drop für Block-Reihenfolge, Plus-Buttons für Insert (7 Block-Templates), Trash mit 5s Undo, Paint-Roller-Icon für per-Block Theme-Override (PROJ-590-Tokens). {{-Trigger im Inline-Editor öffnet Insert-Tag-Autocomplete (PROJ-591). Jeder Save erzeugt eine cms_block_versions-Zeile mit source='inline_editor' (vs. 'backend_editor'/'ai_generated'/'system_restore') — vollständiger Audit-Trail wer welche Edit-Surface genutzt hat. Endkunden ohne Workspace-Membership sehen weder Toolbar noch Edit-Capabilities (Server-Permission-Check via getInlineEditPermission). Kein Edit-Token in URL — Edit-Capability ist an Auth-Session gebunden. Aufbewahrung: cms_block_versions wie PROJ-592 (90 Tage automatische Versionen, manuelle Snapshots unbegrenzt, audit-log dauerhaft). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter redaktioneller Pflege). RLS: cms_block_versions wie PROJ-592, source-Spalte ist Teil der bestehenden RLS-Policy. CASCADE-DELETE bei Workspace/Page-Löschung
- PROJ-591 Insert Tag Manager (cms_insert_tags, cms_insert_tag_translations): Workspace-Admin/Manager pflegt Custom-Insert-Tags (Format {{namespace.key}}) mit Default-Wert + optionalen Übersetzungen (locale → value). Tags werden in CMS-Block-Inhalten verwendet (Headlines, Body-Text, Button-Labels) und zur Render-Zeit von der Public-CMS-Engine ersetzt. System-Tags (site.phone/email/address aus workspaces, page.title/slug/url/published_at, contact.greeting nach Locale) sind hardcoded im Code (src/lib/cms/insert-tags-system.ts, kein DB-Lookup) und liefern keine Endkunden-PII (Workspace-Stammdaten der Agentur). KI-Übersetzungs-Vorschläge: Bei Klick auf 'KI-Vorschlag' wird der Default-Wert (deutscher Marketing-Text der Agentur) + optionale Tag-Description an Anthropic Claude Haiku übermittelt — KEINE Endkunden-Daten, nur agentureigene Marketing-Inhalte. created_by/updated_by FK auf auth.users (ON DELETE SET NULL bei User-Löschung). RLS: SELECT alle Workspace-Mitglieder + Endkunden (Render-Pfad benötigt Lookup), INSERT/UPDATE/DELETE nur admin/manager. CASCADE-DELETE bei Workspace-Löschung. Aufbewahrung: unbegrenzt (Workspace-Konfiguration). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an wiederverwendbaren Marketing-Bausteinen mit Mehrsprachigkeit)
- PROJ-625 Kamera-Presets pro Kunde (brand_camera_presets): Pro CRM-Kontakt speichert Workspace-Mitglied wiederverwendbare Kamera-Konfigurationen (Name, Kameramodell, Objektiv, Brennweite in mm, Blende). Werden als Foto-Stil-Suffix (z.B. 'Shot on Sony A7 IV with 50mm at 50mm, f/1.4') an den sanitisierten User-Prompt + Brand-Constraints angehängt — kein Endkunden-PII (rein technische Foto-Metadaten). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO. RLS: alle Workspace-Mitglieder lesen/schreiben (workspace-scoped). Workspace+Contact-scoped, CASCADE-DELETE bei Kontakt-/Workspace-Löschung. Im Datenexport (Art. 15/20 DSGVO) enthalten.
- PROJ-626 KI-Studio Referenz-Bilder via @mention: Bestehende brand_assets (Markenassets) eines Kunden können im KI-Studio-Prompt via @-Mention referenziert werden. Backend lädt die file_url (max. 4 Assets) und hängt sie als Block 'Reference Images' an den enriched Prompt an, der an Higgsfield übermittelt wird. Die file_url verweist auf workspace-eigenen Storage — Higgsfield greift im Live-Modus auf die URL zu, um das Bild als Inspirations-Input zu nutzen. Keine zusätzliche Datenkategorie gegenüber PROJ-596 (Higgsfield-Adapter existiert bereits) — referenzierte Bilder fallen unter denselben EU AI Act Art. 50 Hinweis. Keine Endkunden-PII (nur Brand-Asset-URLs aus Workspace-Storage).
- PROJ-674 KI-Studio Face-Identity-Preservation (cms_higgsfield_jobs.face_lock_asset_id, neue Spalte): Wenn der User im KI-Studio den Toggle 'Gesicht exakt übernehmen' für ein Referenzbild aktiviert, wird die UUID des markierten brand_assets-Eintrags als face_lock_asset_id im Job persistiert (Cap auf 1 pro Job). Im Higgsfield-Live-Modus erhält die zugehörige file_url den Image-Weight 1.0 (statt Default 0.5) — das KI-Modell gewichtet die Identitäts-Übernahme entsprechend stärker. Wenn ein face-fähiges Modell (SoulID/PuLID/IP-Adapter-Face-ID) via models_explore-Discovery erkannt wird, bevorzugt der Adapter dieses; sonst Fallback auf Standard-Modell + englischer Prompt-Marker '(preserving the exact facial identity from Reference Image N)'. Datenfluss zu Higgsfield ist identisch zu PROJ-626 (Signed-URL via Workspace-Storage) — KEINE zusätzlichen Datenpfade, nur eine erweiterte Verarbeitungs-Intention. **Art. 9 DSGVO (biometrische Daten):** Bei Bildern mit echten Personen MUSS der User vor Upload die Einwilligung der abgebildeten Person eingeholt haben. User-Aufklärung erfolgt via Help-Center-Eintrag und Erst-Nutzungs-Modal (One-time per User). Keine Speicherung biometrischer Embeddings im System — Face-Detection läuft ausschließlich clientseitig (face-api.js) zur UI-Anzeige; keine Server-Persistenz von Face-Vektoren oder Landmarks. Cleanup-Verhalten: face_lock_asset_id als UUID-FK wird bei Asset-Löschung automatisch via ON DELETE SET NULL geleert; Job-Eintrag bleibt erhalten (Audit-Trail). Im Datenexport (Art. 15/20 DSGVO) automatisch enthalten als Teil der cms_higgsfield_jobs-Row. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO + (bei Personen-Bildern) Art. 9 Abs. 2 lit. a DSGVO (Einwilligung der abgebildeten Person, eingeholt durch User vor Upload). Keine RLS-Änderungen — neue Spalte folgt bestehender cms_higgsfield_jobs-Policy.
- PROJ-621 Open Graph Tag Management (workspace_og_settings, site_og_settings, og_image_templates, Twitter/OG-Felder an cms_pages + cms_page_translations, workspaces.branding_version): Pro Workspace KI-Opt-In + Tonality-Hinweis + Monatsquota. Pro CMS-Site Default-OG-Werte (og:site_name, Default-Image, twitter:site-Handle, Default-Locale, Default-Template, Section-Defaults via JSONB-Pfad-Präfix-Regeln). Pro Workspace 1–N Auto-OG-Bild-Templates (Branded Hero, Minimal, Quote-Style). Pro Page/Translation manuelle OG-Werte (og_title, og_description, og_image_url, twitter_title, twitter_description, twitter_image_url), Override-Lock-Marker (og_manually_edited_fields), og_image_mode (manual/auto/inherit), og_image_template_id-Auswahl. Auto-Bilder werden Edge-CDN-cached, nicht persistiert (deterministisch aus Page-Daten + branding_version regeneriert). KI-Generation via Anthropic Haiku (siehe PROCESSORS-Eintrag): Page-Title + extrahierter Plain-Text der ersten 3 Blocks (max 2.000 Zeichen) + Workspace-Tonality-Hinweis — KEINE Endkunden-Daten aus CRM/Identity, nur Marketing-Texte; Aktivierung nur bei Workspace-Opt-In (workspace_og_settings.ki_generation_enabled=true). Sharing-Klicks von Plattform-Hostnames (LinkedIn/X/Facebook/Slack/Discord/WhatsApp/Reddit/Pinterest) werden als og_share_referral-Events in tracking_events (anonym, kein PII, nur Hostname + Page-Pfad) erfasst. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse, Marketing-Performance + Klickraten-Optimierung). RLS: workspace_og_settings + og_image_templates SELECT alle Workspace-Mitglieder, INSERT/UPDATE/DELETE nur admin/manager; site_og_settings analog admin/manager pflegt, Member sieht Defaults; Page-Override-Felder editierbar durch member+ (CMS-Editor-Rolle). Workspace-scoped, CASCADE-DELETE bei Workspace-/Site-/Page-Löschung. Im Datenexport (Art. 15/20 DSGVO) enthalten.
- PROJ-683 Multi-Provider KI-Bildgenerierung — Post-Production-Pipeline (cms_postproduction_jobs): Pro Verfeinerungs-Auftrag speichert die Tabelle die Quell-Asset-UUID (source_asset_id, FK auf brand_assets), den Quell-Generation-Job (source_job_id, FK auf cms_higgsfield_jobs), die Operationen-Liste (operations[] Array — Werte aus 'upscale_2x','upscale_4x','face_restore','skin_enhance'), Status (queued/processing/succeeded/failed/partial_failed), Provider-Key (aktuell 'replicate'), Provider-Job-IDs (provider_job_ids JSONB Map operation->prediction_id, interne Verarbeitungs-Metadata — NICHT im Datenexport), Result-Asset-UUID, Kosten (cost_cents), error_reason + error_per_operation, triggered_by_user_id, Lifecycle-Timestamps (created_at, started_at, completed_at, last_polled_at). Bilder werden transient an Replicate (USA, EU-US-DPF) übermittelt — siehe PROCESSORS-Eintrag Replicate Inc. Output ist neues brand_assets-Item mit derivative_kind='postproduction' und parent_asset_id=source_asset_id (Audit-Kette). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (effiziente Bildqualitätssteigerung im Agentur-Workflow). RLS: SELECT alle aktiven Workspace-Mitglieder, Writes via Service-Role (Webhook + Cron-Worker). Workspace-scoped, CASCADE-DELETE bei Workspace-Löschung. Im Datenexport (Art. 15/20 DSGVO) enthalten (ohne provider_job_ids). 180-Tage-Retention nach erfolgreichem Abschluss via Cleanup-Cron (PROJ-683 Phase 3).
- PROJ-683 Multi-Provider KI-Bildgenerierung — Provider-Aktivierung pro Workspace (workspace_ai_image_providers): Pro Workspace + provider_model_id (FK auf ai_image_provider_models) eine Aktivierungs-Zeile mit is_enabled (boolean), enabled_at, enabled_by_user_id (FK auth.users ON DELETE SET NULL). Steuert ob ein bestimmtes Replicate-Modell (z.B. SDXL, Flux dev, RealisticVision) im KI-Studio des Workspace verfügbar ist. KEINE Endkunden-PII, nur Workspace-Konfiguration mit User-Audit. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO. RLS: SELECT alle Workspace-Mitglieder, INSERT/UPDATE/DELETE nur admin/manager. Workspace-scoped, CASCADE-DELETE bei Workspace-Löschung. Im Datenexport (Art. 15/20 DSGVO) enthalten.
- PROJ-683 Multi-Provider KI-Bildgenerierung — Use-Case-Routing (workspace_ai_image_routing_rules): Pro Workspace + use_case_key (text — z.B. 'cms_block_hero', 'crm_reference_mockup') eine Routing-Regel auf ein konkretes provider_model_id. Erlaubt Agentur-Admin das Default-Modell pro Use-Case zu überschreiben. KEINE PII, nur technische Mapping-Konfiguration. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO. RLS: SELECT alle Workspace-Mitglieder, INSERT/UPDATE/DELETE nur admin/manager. Workspace-scoped, CASCADE-DELETE bei Workspace-Löschung. Im Datenexport (Art. 15/20 DSGVO) enthalten.
- PROJ-683 Multi-Provider KI-Bildgenerierung — Provider-Modell-Katalog (ai_image_provider_models, platform_replicate_config): Plattform-globale Stammdaten — pro KI-Bild-Modell (provider_key, model_id, version, capabilities_jsonb mit unterstützten Aspect-Ratios, Variants, Face-Lock-Fähigkeit). platform_replicate_config enthält den AES-256-GCM-verschlüsselten REPLICATE_API_TOKEN und das Webhook-Signing-Secret (HMAC-SHA256 nach Standard-Webhooks-Spec). KEIN Workspace-Scope, KEINE Endkunden-PII. Plattform-Admin-only RLS. Nicht im Workspace-Datenexport (plattform-globale Konfiguration ohne Workspace-Bezug). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (Plattform-Betrieb).
- PROJ-683 Multi-Provider KI-Bildgenerierung — Replicate-Webhook-Diagnose (replicate_webhook_logs): Pro eingehendem Webhook eine Log-Zeile mit prediction_id, workspace_id (nullable bei unknown_destination), received_at, source_ip (Diagnose-only, nicht im Datenexport), processing_status (accepted/duplicate/invalid_signature/unknown_destination/insert_failed/constraint_violation/no_config/rate_limited/...), Payload-JSONB (Replicate-Response), headers_snapshot (Webhook-Header für Signaturprüfung-Diagnose), error_message. 30-Tage-Retention via Cleanup-Cron (PROJ-683 Phase 3). RLS: SELECT nur Admins. Workspace-scoped via workspace_id (CASCADE-DELETE bei Workspace-Löschung). Im Datenexport (Art. 15/20 DSGVO) enthalten — ohne source_ip (PII-Redaktion analog matelso_webhook_logs).
- PROJ-683 Multi-Provider KI-Bildgenerierung — erweiterte Generation-Job-Spalten (cms_higgsfield_jobs.provider_key, provider_model_id, provider_job_id, provider_cost_cents, prompt_was_enhanced): Generation-Jobs sind seit Phase 4 multi-provider-fähig — provider_key markiert ob Higgsfield oder Replicate genutzt wurde, provider_model_id (UUID) verweist auf ai_image_provider_models, provider_job_id ist die externe Job-ID des Anbieters, provider_cost_cents der gemeldete Verbrauch, prompt_was_enhanced markiert ob der Prompt-Enhancer (Anthropic Claude Sonnet 4.6, siehe PROCESSORS) den User-Prompt vor der Generierung angereichert hat. Bestehende Higgsfield-Jobs ohne diese Felder bleiben unverändert (provider_key Default 'higgsfield', andere NULL). Im bestehenden cms_higgsfield_jobs-Datenexport-Block (PROJ-596) automatisch enthalten. KEINE zusätzliche PII gegenüber bestehender Job-Tabelle.
- PROJ-683 Multi-Provider KI-Bildgenerierung — Parent-Asset-Verkettung (brand_assets.parent_asset_id): Bei Post-Production-Output zeigt parent_asset_id (FK self-reference auf brand_assets) auf das Quell-Asset der Verfeinerung — z.B. ein Upscale-4x-Output verweist auf das Original. Erlaubt Audit-Kette: Verfeinerung -> Source-Asset -> Generation-Job -> User. Bei Workspace-Löschung CASCADE über brand_assets. ON DELETE SET NULL falls Quell-Asset einzeln gelöscht wird (Audit-Trail bleibt erhalten, Verfeinerung wird zur Waise — wird vom Orphan-Detector erfasst). KEINE zusätzliche PII gegenüber bestehender brand_assets-Tabelle.
- PROJ-683 EU AI Act Art. 50 (verbindlich ab 02.08.2026) — Maschinenlesbare KI-Kennzeichnung: Alle von Higgsfield ODER Replicate generierten Bilder erhalten beim Storage-Upload einen EXIF/IPTC-Software-Tag im Metadata-Block ('neuland-os AI Studio (Higgsfield)', 'neuland-os AI Studio (Replicate)', 'neuland-os AI Studio (Replicate Post-Production)'). Sharp wird vor dem Storage-Upload als Transparenz-Pipeline durchgeführt (`.withMetadata({ exif: { IFD0: { Software: '...' } } })`). Defense-in-Depth: bei Sharp-Fehler (unsupported Format) wird das Original ohne EXIF gespeichert — kein Hard-Failure, aber Audit-Log via trackError. Ergänzt den existierenden DB-Marker `is_ai_generated=true` + `ai_generated_by` um eine zweite, dateibasierte Kennzeichnung die auch nach dem Download/Re-Share erhalten bleibt.
- PROJ-800 CMS Page Builder Paket 1 MVP (cms_pagebuilder_pages, cms_pagebuilder_templates, cms_pages.editor_mode): Zweite, parallel zum bestehenden Block-Editor verfügbare Editor-Variante für CMS-Seiten. Pro Seite + Locale ein content_tree (JSONB-Baum aus Paragraph- und Section-Knoten mit UUIDs). Die Inhalte sind redaktionelle Marketing-Texte (Paragraph.props.text) und Layout-Konfigurationen (Section.props.bgColor/padding/id) der Agentur — können in Einzelfällen Kunden-Testimonials mit Klarnamen tragen, wenn solche Texte direkt im Editor eingegeben werden. cms_pagebuilder_templates speichert wiederverwendbare Bausteine (in Paket 1 nur Schema, Endpunkte folgen Paket 4). cms_pages.editor_mode (Default 'legacy') entscheidet pro Seite, welcher Editor genutzt wird — Bestandsseiten bleiben auf 'legacy', neue Seiten können optional auf 'pagebuilder' angelegt werden. Berechtigungen: alle Workspace-Mitglieder (admin/manager/member/client) dürfen lesen und schreiben (Paket 1 ohne Rollen-Differenzierung), durchgesetzt per RLS-Policy gegen workspace_members. Keine externen Auftragsverarbeiter — Save/Load/Tokens laufen vollständig in der NEULAND.-OS-Supabase. Last-Write-Wins ohne Optimistic-Locking (Versionierung kommt in Folgepaketen). Aufbewahrung: solange die zugehörige cms_pages-Seite existiert (CASCADE-DELETE bei Page-/Workspace-Löschung). Tree-Limits (Defense-in-Depth gegen JSONB-Bombs): max. 20 Verschachtelungs-Ebenen, max. 500 Knoten pro Seite. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an einer effizienten visuellen Seitenbearbeitung). Im Workspace-Datenexport (Art. 15/20 DSGVO) als cms_pagebuilder_pages und cms_pagebuilder_templates enthalten (R-241/R-707). Public-Renderer-Anbindung NICHT in Paket 1 — Editor-erstellte Inhalte sind in Paket 1 ausschließlich im Editor sichtbar und werden erst mit Paket 4 (Layouts + Public-Renderer) auf der öffentlichen Kunden-Website ausgespielt.
- PROJ-847 CMS Page Builder Paket 3 — Atome & Interaktion (cms_pagebuilder_pages.content_tree-Erweiterung um 13 neue Knoten-Typen): Erweitert den Page Builder um Inhalts-Atome (Headline mit h1–h6 + Sprunglink-Anchor, Image mit Markenasset-Referenz, Video mit YouTube/Vimeo/Self-Hosted, Button und Link mit href-URLs) und Interaktions-Container (IconList, Accordion, Tabs, Carousel inkl. Sub-Container). Persistenz: weiterhin ausschließlich in cms_pagebuilder_pages.content_tree (JSONB), kein neues Schema, keine neue Tabelle. Datenfluss-spezifische Hinweise: (a) Image-Atom referenziert via assetId einen Eintrag in brand_assets (workspace-scoped, RLS-geschützt). Beim Rendern im Editor wird via GET /api/brand-assets/:id ein Live-Refresh der Metadaten (alt_text_de → alt-Text, description → Caption, file_url → Bild-URL) durchgeführt — keine externen Quellen. (b) Video-Atom self-hosted: analog zu Image-Atom über brand_assets (kein Direkt-Upload, kein externer Drittanbieter). (c) Video-Atom YouTube: lädt im Editor ein iframe von https://www.youtube-nocookie.com/embed/{videoId} (datenschutzfreundlicher Modus ohne Tracking-Cookies — siehe Google LLC im Verarbeitungsverzeichnis). (d) Video-Atom Vimeo: lädt im Editor ein iframe von https://player.vimeo.com/video/{videoId} — Vimeo, Inc. ist als neuer Sub-Auftragsverarbeiter aufgenommen (siehe PROCESSORS). Beide Embeds werden ausschließlich im authentifizierten Editor-Kontext gerendert (Workspace-Mitarbeiter, Art. 88 BDSG / Art. 6 Abs. 1 lit. f). (e) Button/Link-href: User-konfigurierte URLs werden ausschließlich als HTML-Output gespeichert (target="_blank" mit rel="noopener noreferrer"), kein automatischer Abruf. (f) Public-Renderer-Anbindung für Paket-3-Typen NICHT in Paket 3 — die im Editor erstellten Inhalte sind ausschließlich im Editor sichtbar; eine spätere Public-Renderer-Erweiterung wird einen 2-Klick-Consent-Wrapper für YouTube-/Vimeo-iframes vor End-Besucher-Browsern einführen. Tree-Limits aus Paket 1 bleiben unverändert (MAX_DEPTH=20, MAX_NODES=500). Datenexport-Pfad und CASCADE-Löschung unverändert — alle neuen Knoten-Typen liegen weiterhin im content_tree-JSONB der bestehenden Seite.
- PROJ-954 CMS Page Builder Paket 4 — Symbole & Seitenlayouts (cms_pagebuilder_templates.type/overridable_fields/slots, cms_pagebuilder_pages.layout_id): Erweitert die bestehende cms_pagebuilder_templates-Tabelle um eine type-Spalte (template/symbol/layout). type='symbol' speichert wiederverwendbare redaktionelle Bausteine (z.B. Header, Footer, CTA) als content_tree-JSONB-Baum plus overridable_fields (JSONB-Map nodeId -> erlaubte Prop-Namen, rein technische Konfiguration welche Felder pro Instanz überschreibbar sind). type='layout' speichert Seitenlayout-Rahmen als slots-JSONB-Array (Slot-Definitionen mit id/name/typ und optionaler defaultSymbolId-Referenz auf ein Symbol desselben Workspaces). Beide Typen sind redaktionelle Strukturdaten der Agentur OHNE zusätzliche personenbezogene Daten gegenüber Paket 1 — sie tragen Marketing-Texte und Layout-Konfigurationen, in Einzelfällen Klarnamen nur wenn solche Texte direkt im Editor eingegeben werden (identisch zu Paket 1). cms_pagebuilder_pages.layout_id (UUID, nullable, FK auf cms_pagebuilder_templates ON DELETE SET NULL) verknüpft eine Seite mit ihrem Layout — Slot-Inhalte und Symbol-Overrides auf Seitenebene liegen im bestehenden content_tree-JSONB (kein neues Feld). Berechtigungen: Symbole/Layouts erstellen/bearbeiten nur admin/manager; Seiten mit Layout verknüpfen und Slots/Overrides befüllen auch member. Durchgesetzt im Backend per Rollen-Check gegen workspace_members (RLS-Policies decken die neuen Spalten ab). Keine externen Auftragsverarbeiter — Symbol-/Layout-CRUD läuft vollständig in der NEULAND.-OS-Supabase. Aufbewahrung: solange das Template bzw. die zugehörige cms_pages-Seite existiert (CASCADE-DELETE bei Workspace-Löschung; layout_id wird bei Layout-Löschung auf NULL gesetzt). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (effiziente visuelle Seitenbearbeitung). Im Workspace-Datenexport (Art. 15/20 DSGVO) als cms_pagebuilder_templates (inkl. type/overridable_fields/slots) und cms_pagebuilder_pages (inkl. layout_id) enthalten (R-241/R-707).
- PROJ-1003 CMS Frontend-Inline-Editor: Angemeldete Agentur-Mitglieder (admin/manager/member) bearbeiten den content_tree direkt auf der gerenderten Website (Doppelklick Text/Bild). Klarstellung zu Paket 1/3/4: Pagebuilder-Inhalte sind seit der Pagebuilder-Konsolidierung (PROJ-996) NICHT mehr nur im Editor sichtbar, sondern werden öffentlich ausgespielt (neuland-os-Renderer für die os-Domain, Hetzner-cms-renderer für Kunden-Domains) — der Inline-Editor bearbeitet genau diese öffentlich gerenderte Seite. Inline-Edit nur auf Staging (Live ist seit PROJ-1000 schreibgeschützt). Versionierung (Korrektur zur Paket-1-Aussage Last-Write-Wins ohne Optimistic-Locking): Jeder Pagebuilder- UND Inline-Save erzeugt jetzt einen cms_page_versions-Snapshot (content_tree im block_tree_snapshot, author_user_id FK ON DELETE SET NULL, Auto-Versionen 90 Tage / manuelle unbegrenzt, identisch zur PROJ-592-Retention); zusätzlich Optimistic-Lock via updated_at. Symbol-Inline-Edits (Bezugskomponenten) wirken workspace-weit auf alle Seiten und werden in cms_audit_log protokolliert (actor_user_id). Datenschutz: Bild- und Hintergrundbild-Wechsel betten ausschließlich workspace-eigene brand_assets ein — src und fileUrl werden serverseitig aus brand_assets.file_url abgeleitet, keine beliebigen externen Bild-URLs auf öffentlichen Seiten. Keine neue Tabelle, kein neuer Auftragsverarbeiter, kein Cookie. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO.
- PROJ-1004 CMS Frontend-KI-Assistent: Ein als KI gekennzeichneter Chat-Assistent (Art. 50 EU AI Act) auf der gerenderten Staging-Seite schlägt CI-konforme Texte vor. Bei einer Vorschlags-Anfrage werden der aktuelle Element-Text + die CI-Vorgaben (Tonalität/Dos&Donts aus ssot_ci_language, USPs aus ssot_items) transient an Anthropic (Claude Haiku 4.5) übermittelt — kein Speichern beim Anbieter, SSOT-Inputs durchlaufen sanitizePii. Anthropic ist bereits als Auftragsverarbeiter gelistet (siehe PROCESSORS); neuer Zweck Token-Logging unter ai_feature='cms_frontend_assistant' (ai_token_logs, kein personenbezogener Inhalt). Schreibaktionen (Bestätigung) laufen über den PROJ-1003-Inline-Edit-Pfad (Versionierung, Markenasset-only Bilder, href-Härtung). Keine automatisierte Entscheidung über Personen, keine neue Tabelle, kein Cookie. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO.
- PROJ-1620 Modul-Style-KI-Assistent: Ein als KI gekennzeichneter Chat-Assistent (Art. 50 EU AI Act) im Vorlagen-Bereich (Admin/Manager-only, ModuleEditSheet) schlägt Style-Änderungen an CMS-Modul-Konfigurationen vor (cms_modules.config — Farben, Varianten, strukturelle Werte, keine Endkunden-PII). Bei einer Vorschlags-Anfrage werden die aktuelle Modul-Config (nur die per Assistent änderbaren Felder) + die Nutzeranweisung + optional die CI-Farbpalette der Website (Name/Hex/Rolle aus ssot_items.section='ci_color', rein technische Markendaten ohne PII) transient an Anthropic (Claude Haiku 4.5) übermittelt — kein Speichern beim Anbieter. Anthropic ist bereits als Auftragsverarbeiter gelistet (siehe PROCESSORS); neuer Zweck Token-Logging unter ai_feature='cms_module_style_assistant' (ai_token_logs, kein personenbezogener Inhalt). Vorschläge werden serverseitig gegen eine harte Feld-Allowlist + das Modul-Schema geprüft, bevor sie angezeigt werden; das eigentliche Speichern (nach expliziter Bestätigung) läuft über die bestehende, bereits validierende Modul-PATCH-Route — kein neuer Schreibpfad. Keine automatisierte Entscheidung über Personen, keine neue Tabelle, kein Cookie. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO.
KI-Seitenersteller (CMS-Landingpage-Generierung)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter Content-Produktion)
- Nutzereingabe: Haupt-Keyword / Thema (max. 100 Zeichen) und optionale Anweisungen (max. 500 Zeichen). Thema wird als Seitentitel gespeichert, Anweisungen nur während des Requests verarbeitet (nicht persistent)
- SSOT-Kontextdaten: CI-Sprache, USPs, Zielgruppen, Positionierung — anonymisiert (sanitizePii) an Claude (Anthropic) übermittelt. Nur gelesen, nicht kopiert
- Bedarfsgruppen-Informationen: Problemfelder, Lösungsversprechen, URL-Struktur — anonymisiert (sanitizePii) an Claude (Anthropic) übermittelt. Nur gelesen, nicht kopiert
- Keyword-Analysen: Suchvolumen, Suchintention, Cluster-Namen — anonymisiert (sanitizePii) an Claude (Anthropic) übermittelt. Nur gelesen, nicht kopiert
- KI-generierter Content: Seitentitel, Meta-Description, URL-Slug, Block-Inhalte (Hero, Text, Feature-Grid, Testimonial, FAQ, CTA). Gespeichert in cms_pages und cms_page_blocks. Löschung bei Seiten-Löschung (CASCADE)
- KI-Herkunftsmarker: ai_generated_at (Zeitstempel) und ai_generated_by (Modellname) auf der CMS-Seite. Dient der EU AI Act Transparenzkennzeichnung
- Token-Nutzungsprotokoll: Modell, Feature-Typ (ki_seitenersteller), Prompt- und Completion-Tokens, geschätzte Kosten, anonymisiertes Thema. Aufbewahrung: bis Workspace-Löschung
- Rate-Limiting: Max. 5 Generierungen pro Workspace pro Tag. Zählung erfolgt über ai_token_logs (DB-basiert)
Spracheingabe (Voice-to-Text)
Rechtsgrundlage: Art. 6 Abs. 1 lit. a DSGVO (Einwilligung) — Aktivierung nur nach explizitem Opt-in des Nutzers
- Audio-Aufnahme (Mikrofon) — Web-App und iOS: Wird ausschließlich zur Transkription an OpenAI (Whisper-1) übermittelt. Die Audiodaten werden nur im Arbeitsspeicher des Servers verarbeitet und nicht auf Festplatte oder in der Datenbank gespeichert. OpenAI kann Audio-Rohdaten bis zu 30 Tage für Sicherheits- und Missbrauchserkennungszwecke aufbewahren (gemäß OpenAI API Data Usage Policy). Ein Auftragsverarbeitungsvertrag (AVV) mit OpenAI ist abgeschlossen
- Audio-Aufnahme (Mikrofon) — macOS Companion App (PROJ-373, geändert mit PROJ-1878): Die Transkription erfolgt im Regelfall über die Cloud — die Audio-Aufnahme wird an den NEULAND.-Server gesendet und von dort an OpenAI (Whisper-1) zur Transkription weitergeleitet (gleicher Pfad wie Web-App und iOS; Verarbeitung nur im Arbeitsspeicher des Servers, keine dauerhafte Speicherung, OpenAI-Aufbewahrung bis zu 30 Tage gemäß API Data Usage Policy, AVV abgeschlossen). Grund der Umstellung (PROJ-1878): deutlich geringere Wartezeit (unter 2-3 Sekunden statt 4-23 Sekunden lokal). Bei fehlender Internetverbindung oder Cloud-Fehler fällt die App automatisch auf die lokale Transkription via WhisperKit zurück (quelloffene Apple-ML-Runtime mit OpenAI-Whisper-Modell, ~800 MB, GPU-beschleunigt) — in diesem Fallback-Fall verlassen die Audiodaten das Gerät NICHT. Das WhisperKit-Modell liegt im lokalen User-Cache-Verzeichnis von macOS und wird nur vom Nutzer selbst entfernt
- Persönliches Wörterbuch als Erkennungshilfe (PROJ-1878): Die vom Nutzer selbst gepflegten Wörterbuch-Einträge der macOS-App (Eigennamen/Fachbegriffe, lokal in UserDefaults gespeichert) werden bei Cloud-Transkription als Erkennungs-Kontext (max. 224 Tokens) an OpenAI mitübertragen, damit Eigennamen korrekt erkannt werden — identische Funktion wie beim lokalen Pfad. Die Einträge werden serverseitig nicht gespeichert, nur transient durchgereicht
- Transkribierter Text: Wird in das jeweilige Eingabefeld eingefügt und nur gespeichert, wenn der Nutzer den Inhalt aktiv absendet
- Nutzungsdauer (Sekunden): Wird für die Kostenverfolgung im KI-Token-Tracking protokolliert (workspace-bezogen, nicht personenbezogen). Bei lokaler Transkription via WhisperKit (macOS) entstehen keine externen Kosten; der Vorgang wird dennoch protokolliert, um Nutzungsstatistiken zu führen. Aufbewahrung: bis Workspace-Löschung
- Einwilligung: Wird im Browser gespeichert (localStorage 'neuland_voice_consent') bzw. in der macOS Companion App lokal auf dem Gerät (UserDefaults 'dsgvo_voice_consent'). Kann jederzeit widerrufen werden
- Kunden-Portal: Spracheingabe im Portal erfordert eine zusätzliche Aktivierung durch den Agentur-Administrator (voice_input_enabled auf der Workspace-Verbindung). Kosten werden dem Agentur-Workspace zugeordnet
- Native Companion App (macOS/iOS) — Authentifizierung: Die Einwilligung wird lokal auf dem Gerät gespeichert (UserDefaults). Authentifizierung erfolgt über Bearer-Token (Supabase JWT), gespeichert im System-Keychain (biometrisch geschützt). iOS verwendet denselben OpenAI-Cloud-Pfad wie die Web-App (kein lokales Whisper-Modell auf iOS)
- Tägliches Limit: Maximal 60 Minuten pro Workspace und Tag. Die Limitprüfung erfolgt über die bestehende KI-Token-Tracking-Infrastruktur
Persönliche Google-Kontoanbindung (Gmail & Kalender)
Rechtsgrundlage: Art. 6 Abs. 1 lit. a DSGVO (Einwilligung) — Nutzer initiiert OAuth-Flow aktiv und erteilt explizit Einwilligung über den Google-Consent-Screen. Widerruf jederzeit durch Trennung des Kontos im Profil
- Google-E-Mail-Adresse und Anzeigename des verbundenen Kontos: Gespeichert in der Datenbank zur Identifikation. Löschung bei Konto-Trennung oder Account-Löschung (CASCADE)
- OAuth-Tokens (Access-Token, Refresh-Token, Ablaufzeit, Scopes): Verschlüsselt mit AES-256-GCM gespeichert (INTEGRATION_ENCRYPTION_KEY). Nie im Klartext in Logs, API-Antworten oder Admin-Oberflächen sichtbar
- Verbindungsstatus (aktiv/fehlerhaft) und Zeitstempel: Technische Metadaten ohne personenbezogenen Inhalt
- Temporärer CSRF-Cookie (google_oauth_nonce): httpOnly, 10 Minuten Lebensdauer, pfadbeschränkt auf den Callback-Endpunkt. Wird nach einmaliger Verwendung gelöscht
- Admin-Sichtbarkeit: Workspace-Admins sehen ausschließlich die Anzahl verbundener Google-Konten pro Teammitglied (Zahl-Badge). Kein Zugriff auf E-Mail-Adressen, Namen oder Tokens (Privacy by Design)
Persönliche GitHub-Kontoanbindung (Entwickler — manueller CI-Trigger-Neustart)
Rechtsgrundlage: Art. 6 Abs. 1 lit. a DSGVO (Einwilligung) — der Entwickler initiiert den OAuth-Flow aktiv und erteilt die Einwilligung über den GitHub-Consent-Screen. Widerruf jederzeit durch Trennung der Verbindung im Profil (DELETE /api/user/github/tokens/:id) oder Token-Widerruf direkt bei GitHub. Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse) für die korrekte Commit-Attribution: Der manuelle Branch-Neustart (PROJ-1832) erzeugt Commits/PRs bewusst unter der echten GitHub-Identität des auslösenden Entwicklers statt unter einer Automatik-Identität — Attributions-Ehrlichkeit und Vercel-Deployment-Zuordnung
- GitHub-Identität des verbundenen Kontos (user_github_tokens): GitHub-Login, Anzeigename, Avatar-URL, numerische GitHub-User-ID — gespeichert zur Anzeige im Profil und für die Verweis-Texte am neuen PR ('ausgelöst von @login'). Löschung bei Verbindungs-Trennung oder Account-Löschung (CASCADE auf user_id)
- OAuth-Zugriffstoken (Scope 'repo'): Verschlüsselt mit AES-256-GCM gespeichert (INTEGRATION_ENCRYPTION_KEY, Format iv:authTag:ciphertext — identisches Muster wie die Google-Kontoanbindung). Nie im Klartext in Logs, API-Antworten oder Admin-Oberflächen; die Status-API liefert ausschließlich die Anzeige-Spalten (R-160)
- Verbindungsstatus (active/error) + letzter Fehlertext + Zeitstempel: Technische Metadaten, z.B. 'Token von GitHub abgelehnt (401)' nach einem Widerruf
- Temporärer CSRF-Cookie (github_user_oauth_nonce): httpOnly, 10 Minuten Lebensdauer, pfadbeschränkt auf den OAuth-Callback-Endpunkt. Wird nach einmaliger Verwendung gelöscht
- Übermittlung an GitHub Inc. (USA) beim Neustart: PR-Nummern, Commit-SHAs, Datei-Inhalte des eigenen Code-Repositories, Kommentar-Texte mit dem GitHub-Login des Auslösers — keine Endkunden-Personendaten (siehe PROCESSORS-Eintrag GitHub, Inc.)
- Zugriffsschutz: Nur die eigene Verbindung ist les-/lösch-/nutzbar (RLS user_id-scoped + serverseitige Session-Bindung; kein Cross-User-Token-Zugriff). Der Neustart-Endpunkt erzwingt zusätzlich serverseitig die is_developer-Kennung im Workspace
- DSGVO-Datenexport (Art. 15/20): user_github_tokens ist wie die Schwester-Tabelle user_google_tokens nutzer-gebunden (nicht kontakt-/workspace-gebunden) und daher nicht Teil der Kontakt-/Workspace-Datenexporte; der Nutzer sieht seine Verbindung vollständig im Profil (Art. 15) und kann sie dort jederzeit löschen (Art. 17)
Persönlicher & Team-Kalender (Google Calendar)
Rechtsgrundlage: Art. 6 Abs. 1 lit. a DSGVO (Einwilligung) — Kalender-Zugriff erfordert aktive Google-Kontoanbindung durch den Nutzer. Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse) für Team-Kalender-Ansicht und Terminerinnerungen
- Google-Calendar-Termine: Werden live über die Google Calendar API v3 abgerufen und für die reine Kalender-Anzeige nicht dauerhaft in NEULAND. OS gespeichert. Angezeigt werden: Titel, Start-/Endzeit, Ort, Beschreibung, Teilnehmer, Video-Link. Für den Team-Kalender anderer Mitglieder werden private Events automatisch gefiltert (Anzeige nur als 'Beschäftigt' ohne Details). Ausnahme (PROJ-1024): Enthält ein Termin-Titel ein im Vertrieb hinterlegtes Keyword, wird der Termin als Vertriebsgespräch erkannt und dauerhaft gespeichert (Titel, Start-/Endzeit, Teilnehmer-Name/-E-Mail) — die Verarbeitung ist im Eintrag 'Terminbuchungen-Modul (Calendly- & Google-Kalender-Integration)' dokumentiert
- Weiterer Anzeigeort — Inbox-Kanal 'Termine' (PROJ-2106): Dieselben live abgerufenen Google-Calendar-Termine (siehe oben, keine gesonderte Speicherung) werden zusätzlich in einem rollierenden 7-Tage-Fenster im Inbox-Kanal 'Termine' angezeigt — ausschließlich die eigenen Termine des angemeldeten Nutzers, kein neuer Empfängerkreis, kein neuer Speicherort, keine neue Drittanbieter-Übertragung gegenüber der bestehenden Kalender-Ansicht
- Kalender-Einstellungen (user_calendar_settings): Erinnerungs-Präferenzen pro User — ob Erinnerungen aktiviert sind, Vorlaufzeit in Minuten (5/10/15/30/60), Vortags-Erinnerung. Aufbewahrung: Bis zur Account-Löschung (CASCADE). Keine personenbezogenen Inhalte
- Gesendete Erinnerungen (calendar_reminder_sent): Deduplizierungs-Einträge — Google-Event-ID, Erinnerungstyp, Event-Startzeit. Keine Termininhalte oder -titel gespeichert. Aufbewahrung: 7 Tage nach Event-Datum (automatische Bereinigung). Zweck: Verhindert mehrfache Erinnerungen für denselben Termin
- Terminerinnerungen (Inbox-Notifications): Bei konfigurierten Erinnerungen wird eine Inbox-Benachrichtigung erstellt. Enthält Terminname und formatierte Startzeit. Kein interner Link (Google-Event). Aufbewahrung: Standard-Notification-Retention (90 Tage)
- Team-Kalender-Zugriff: Workspace-Mitglieder können Termine anderer Mitglieder im Team-Kalender sehen (Read-Only). Ereignisse mit visibility='private' oder 'confidential' werden automatisch als 'Beschäftigt' angezeigt — ohne Titel, Ort, Beschreibung oder Teilnehmer (Privacy by Design)
- Kalender-Blockierung für Mitarbeitergespräch-Buchungsfenster (PROJ-2214, employee_conversation_calendar_blocks): Neuer Schreibzweck auf der bestehenden Google-Calendar-Anbindung — für die Dauer eines offenen Mitarbeitergespräch-Buchungsfensters wird im Google-Kalender jedes aktiven Geschäftsleitungs-Mitglieds (nur bei aktiver eigener Google-Verbindung) automatisch ein ganztägiger Platzhalter-Termin ('Reserviert: Mitarbeitergespräche-Fenster', als privat markiert) angelegt und nach Fensterschluss bzw. bei Deaktivierung/Löschung des Fensters wieder entfernt. Der Termin enthält KEINE Mitarbeitendennamen und keinen Gehaltsbezug. In NEULAND. OS gespeichert wird nur eine Tracking-Zeile (Buchungsseiten-Referenz, Fenster-Startdatum, GL-User-ID, Google-Event-ID) zur idempotenten Erstellung/Löschung — Aufbewahrung: bis zum Fensterschluss (automatische Löschung durch den täglichen Cron), CASCADE bei Löschung der Buchungsseite oder des Accounts. Im Workspace-Datenexport (Art. 15/20) enthalten. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse, Terminplanung der Geschäftsleitung) auf Basis der bestehenden Einwilligung zur Google-Kontoanbindung
- Kalender-Anzeige-Präferenzen (calendar_user_sidebar_state, PROJ-1283/PROJ-1510): Pro Nutzer gespeicherte Sidebar-/Ansichts-Einstellungen — aktive Kalender-Konten, Feiertags-/KW-Anzeige, Farbzuweisungen pro Kollege (color_overrides), gewählte Perspektive (Person/Agentur), genau eine gewählte Person (selected_person_id, Referenz auf ein Workspace-Mitglied, null = eigener Kalender) und Zoom-Stufe der Tages-/Wochenansicht (70–150 %). Reine UI-Personalisierung, keine Termininhalte. Aufbewahrung: Bis zur Account-Löschung (CASCADE); bei Löschung der gewählten Person wird die Referenz automatisch auf den eigenen Kalender zurückgesetzt (ON DELETE SET NULL)
- DSGVO-Datenexport (Art. 15/20): user_calendar_settings, calendar_reminder_sent und calendar_user_sidebar_state sind im Workspace-Datenexport enthalten. Kalender-Termine selbst werden nicht exportiert, da sie nicht in NEULAND. OS gespeichert sind (live Google-API-Abruf)
- Löschung: Bei Account-Löschung werden user_calendar_settings, calendar_reminder_sent und calendar_user_sidebar_state automatisch gelöscht (CASCADE). Bei Trennung des Google-Kontos im Profil entfällt der Kalender-Zugriff sofort und gespeicherte Erinnerungsdaten werden unmittelbar gelöscht
Gmail-Integration & E-Mail-Inbox
Rechtsgrundlage: Art. 6 Abs. 1 lit. a DSGVO (Einwilligung) — Nutzer initiiert Gmail-Zugriff aktiv über die Google-Kontoanbindung. Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse) für Projektzuordnung von E-Mails
- Gmail-Nachrichten-Cache (gmail_messages_cache): E-Mail-Metadaten (Betreff, Absender-E-Mail und -Name, Empfänger inkl. CC-Empfänger (cc_email, seit PROJ-1534 — Grundlage für die Inbox-Kennzeichnung 'Direkt an mich' / 'Nur in CC'), Textvorschau, Empfangsdatum, Labels, Attachment-Flag, Gmail-Message-ID, Google-Konto-E-Mail) werden in einer Cache-Tabelle gespeichert, um schnelles Laden der E-Mail-Inbox zu ermöglichen. Maximal 1.000 Einträge pro Google-Konto (bis PROJ-1925: 200); wird diese Grenze überschritten, werden die ältesten Einträge automatisch gelöscht. Zusätzlich wird seit PROJ-1772 der Textinhalt der E-Mail (body_text, gekürzt auf maximal 20.000 Zeichen) serverseitig gespeichert und in einen Suchindex (search_vector) übernommen, damit die Volltextsuche der Inbox Betreff und Nachrichtentext durchsuchen kann. Anhänge werden NICHT serverseitig gespeichert — sie werden bei Bedarf live über die Gmail API abgerufen; die HTML-Darstellung der E-Mail wird im Browser durch rehype-sanitize bereinigt. Seit PROJ-2108 (11.08.2026) umfasst die Synchronisation zusätzlich zum Posteingang auch die Gmail-Systemordner Gesendet, Spam und Papierkorb (Ordner-Kennzeichen: neue folder-Spalte, Werte inbox/sent/spam/trash) — dieselben Datenkategorien wie oben, jetzt für alle vier Systemordner statt nur für den Posteingang; individuelle/benutzerdefinierte Gmail-Ordner werden weiterhin nicht synchronisiert
- Live-Suche im Postfach (PROJ-1925, GET /api/inbox/live-search, GET /api/inbox/live-search/message): Findet das Suchfeld der Inbox weniger als 3 Zeichen Eingabe unverändert nur im lokalen Cache statt; ab 3 Zeichen wird der eingegebene Suchbegriff zusätzlich zur Ausführung der Suche an die Gmail API des jeweils sichtbaren Google-Kontos übermittelt (bis zu 25 Treffer je Postfach). Die Trefferliste (Betreff, Absender, Datum, Vorschautext) und der Volltext eines darüber geöffneten Treffers werden ausschließlich zur Anzeige im Browser verarbeitet und **nicht** in gmail_messages_cache oder einer anderen Tabelle gespeichert — es entsteht kein zusätzliches Mail-Archiv auf dem Server. Zugriffsprüfung wie bei der übrigen Inbox: nur Postfächer, die der Nutzer laut getInboxAccountVisibility() (eigene sichtbare Konten plus über google_token_shares freigegebene) auch sonst sieht
- KI-gestützte E-Mail-Kategorisierung: Betreff und Textvorschau werden anonymisiert (sanitizePii — E-Mail-Adressen, Telefonnummern entfernt) an Claude Haiku (Anthropic) übermittelt. Ergebnis: Kategorie (Kunde, Team, Werbung, Newsletter, Social Media, Automatisiert), Priorität (Hoch/Normal/Niedrig), Handlungsempfehlung (Antworten/Zur Kenntnis/Kann gelöscht werden). Gespeichert in der Cache-Tabelle. Als KI-generiert gekennzeichnet (Sparkles-Icon + Label 'KI-Einschätzung', EU AI Act). Token-Verbrauch wird erfasst (Feature: gmail_categorization)
- Synchronisationsstatus (gmail_sync_state): History-ID und Zeitstempel der letzten Synchronisation pro Google-Konto. Rein technische Daten ohne personenbezogene Inhalte. Die Synchronisation der oben genannten E-Mail-Metadaten erfolgt seit PROJ-1118 nicht nur bei aktiver Nutzung, sondern zusätzlich automatisiert in regelmäßigen Intervallen im Hintergrund (alle 10 Minuten, auch bei geschlossener Anwendung), damit der Posteingang stets aktuell ist. Es werden dabei dieselben Datenkategorien wie bei der nutzergesteuerten Synchronisation verarbeitet — keine neue Datenkategorie, kein neuer Empfänger, gleiche Aufbewahrung
- Projekt-E-Mail-Metadaten (project_emails): Betreff, Absender-E-Mail und -Name, Empfänger-E-Mail, Textvorschau (200 Zeichen), Empfangsdatum, Gmail-Message-ID, Google-Konto-E-Mail. Gespeichert in der Datenbank zur Projektzuordnung. Kein E-Mail-Body oder Anhänge
- Aufgaben-E-Mail-Metadaten (task_emails): Betreff, Absender-E-Mail und -Name, Empfänger-E-Mail, Textvorschau (200 Zeichen), Empfangsdatum, Gmail-Message-ID, Google-Konto-E-Mail. Gespeichert in der Datenbank zur Aufgabenzuordnung (analog zu project_emails). Kein E-Mail-Body oder Anhänge. Löschung automatisch bei Aufgaben-Löschung (CASCADE auf task_id) oder manuell über Soft-Delete (archived_at)
- E-Mail-Filterregeln (email_filter_rules): Name, Konto-Scope, Filterkriterien (Absender, Domain, Betreff, Body-Inhalt, KI-Kategorie, Anhang-Typ), Aktion (als gelesen markieren / löschen / Aufgabe erstellen / Ins DMS importieren / Weiterleiten / Archivieren). Bei der Aktion 'Aufgabe erstellen' wird zusätzlich eine Aktionskonfiguration gespeichert (Ziel-Projekt, Aufgabenvorlage). Bei der Aktion 'Ins DMS importieren' (PROJ-900, DMS-Posteingang) wird als Aktionskonfiguration der Ziel-DMS-Ordner (folder_id) gespeichert; die Regel ist an ein Quell-Google-Konto gebunden und steuert das Auto-Routing importierter E-Mail-Anhänge in DMS-Ordner (Details siehe DATA_PROCESSING-Eintrag 'Dokumentenmanagementsystem (DMS)'). Bei der Aktion 'Weiterleiten' (PROJ-969) wird als Aktionskonfiguration eine vom Nutzer frei wählbare Zieladresse (to_address) gespeichert; trifft eine eingehende E-Mail auf die Regel, werden Betreff und Inhalt der Original-E-Mail (inkl. Absenderangabe als Zitat) automatisch über die Gmail-API aus dem verbundenen Konto des Nutzers an diese Adresse weitergeleitet — dabei können E-Mail-Inhalte Dritter (Absender) an eine konfigurierbare, ggf. externe Empfängeradresse übermittelt werden; die Verantwortung für die Rechtmäßigkeit dieser Weiterleitung trägt der konfigurierende Nutzer (Art. 6 Abs. 1 lit. f DSGVO). Bei der Aktion 'Archivieren' (PROJ-969) wird die E-Mail über die Gmail-API aus dem Posteingang entfernt (INBOX-Label), aber nicht gelöscht — keine zusätzliche Aktionskonfiguration. Gespeichert pro Nutzer. Löschung bei Account-Löschung (CASCADE)
- Letztes Absender-Konto (localStorage gmail_last_account): Google-E-Mail-Adresse des zuletzt genutzten Absender-Kontos. Rein lokal im Browser gespeichert, keine serverseitige Übertragung
- Postfach-Sichtbarkeit in der Inbox (user_google_tokens.show_in_inbox, PROJ-1847): Pro Nutzer und eigenem Google-Konto gespeicherte Anzeige-Präferenz (Standard: sichtbar) — blendet das Postfach nur aus der eigenen Inbox-Darstellung des Nutzers aus (Liste, Suche, Ungelesen-Zähler). Reine UI-Personalisierung ohne Auswirkung auf Synchronisierung oder KI-Kategorisierung, die unverändert weiterlaufen. Aufbewahrung: Bis zur Trennung des Google-Kontos bzw. Account-Löschung (CASCADE, Teil der bestehenden user_google_tokens-Zeile)
- Löschung: Gmail-Cache und Synchronisationsstatus werden sofort gelöscht, wenn das Google-Konto getrennt wird. Bei Account-Löschung werden alle Gmail-Daten automatisch gelöscht (CASCADE auf user_id). Projekt-E-Mail-Metadaten bleiben für den Projektkontext erhalten, aber die Nutzer-Zuordnung (user_id) und das Google-Konto (google_account_email) werden automatisch anonymisiert (SET NULL + DB-Trigger)
- DSGVO-Datenexport (Art. 15/20): project_emails, task_emails, email_filter_rules, gmail_messages_cache und gmail_sync_state sind im Workspace-Datenexport enthalten
Geteilte Google-Konten (Workspace-interne E-Mail-/Kalender-Freigabe)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse) — gemeinsamer Zugriff auf geschäftliche E-Mail-Postfächer innerhalb eines Workspace zur effizienten Teamarbeit. Art. 6 Abs. 1 lit. a DSGVO (Einwilligung) — der Inhaber initiiert die Freigabe aktiv
- Freigabe-Datensatz (google_token_shares): Referenz auf das Google-Konto des Inhabers (token_id), User-ID des Empfängers, User-ID des Inhabers, Workspace-ID, Berechtigungsstufe (Lesen oder Lesen+Senden), Zeitstempel der Erstellung/Aktualisierung. Keine E-Mail-Inhalte oder Passwörter gespeichert
- Zugriff auf E-Mail-Cache des Inhabers: Empfänger erhalten Lesezugriff auf den bestehenden Gmail-Nachrichten-Cache (gmail_messages_cache) des Inhabers — E-Mail-Metadaten (Betreff, Absender, Empfänger, Textvorschau) sowie den dort gespeicherten Nachrichtentext (body_text, siehe Eintrag 'Gmail-Integration & E-Mail-Inbox'). Anhänge werden bei Bedarf live über die Gmail API des Inhabers abgerufen, nicht dupliziert
- Live-Suche im freigegebenen Postfach (PROJ-1925): Ist ein Postfach über google_token_shares freigegeben und in der Inbox sichtbar, schließt die Live-Suche (siehe Eintrag 'Gmail-Integration & E-Mail-Inbox') dieses Postfach automatisch mit ein — der Suchbegriff des Empfängers wird dabei über das OAuth-Token des Inhabers an die Gmail API übermittelt. Zugriffsprüfung wie beim übrigen Lesezugriff: nur solange die Freigabe aktiv und show_in_inbox nicht deaktiviert ist. Auch hier keine Speicherung der Trefferliste oder gelesener Nachrichtentexte
- Kalender-Sichtbarkeit: Bei freigegebenen Google-Konten werden die Kalender-Einträge des Inhabers für Empfänger in der Kalender-Sidebar angezeigt (Read-Only). Private Events werden automatisch als 'Beschäftigt' angezeigt (Privacy by Design)
- Sende-Berechtigung: Falls vom Inhaber aktiviert, können Empfänger E-Mails im Namen des geteilten Kontos senden. Der Versand erfolgt über die Gmail API des Inhabers. Gesendete E-Mails erscheinen im Postfach des Inhabers
- Postfach-Sichtbarkeit in der Inbox (google_token_shares.show_in_inbox, PROJ-1847): Pro Empfänger gespeicherte, vom Inhaber-Flag vollständig unabhängige Anzeige-Präferenz (Standard: sichtbar) — der Empfänger kann das freigegebene Postfach nur für sich selbst aus seiner Inbox-Darstellung ausblenden, ohne die Freigabe zu ändern oder den Inhaber zu beeinflussen. Reine UI-Personalisierung
- Löschung: Freigaben werden sofort gelöscht, wenn: (a) der Inhaber die Freigabe widerruft, (b) der Inhaber das Google-Konto trennt (CASCADE auf token_id), (c) der Inhaber oder Empfänger den Account löscht (CASCADE auf user_id), (d) der Workspace gelöscht wird. Keine Datenreste nach Widerruf — kein separater Cache für Empfänger
- Benachrichtigungen: Bei Freigabe, Widerruf und Konto-Trennung des Inhabers werden Inbox-Benachrichtigungen an die betroffenen Empfänger gesendet (Benachrichtigungstypen: google_account_shared, google_account_share_revoked, google_account_owner_left)
- DSGVO-Datenexport (Art. 15/20): google_token_shares (als Inhaber und als Empfänger) sind im Workspace-Datenexport enthalten
Kunden-Portal
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
- Portal-Zugangstoken
- Einsicht in freigegebene Projekte und Deliverables
- Feedback und Bestätigungen
- CRM-Ansprechpartner-Verknüpfung: Beim Einladen eines Ansprechpartners zum Kunden-Workspace wird die CRM-Ansprechpartner-ID (contact_person_id) mit dem Workspace-Mitglied verknüpft, um Zugangsstatus (eingeladen, aktiv, gesperrt) im CRM anzuzeigen. Wird im DSGVO-Datenexport (Art. 15/20) ausgegeben
- Ereignis-Verlauf (PROJ-1860, customer_timeline_events — löst client_feed_events ab): Zentrales Ereignis-Log über Projektarbeit und laufende Vermarktung eines Kunden, automatisch generiert (Projektstatus, Phasenabschluss, Aufgabe abgeschlossen, Deliverable hinterlegt, bedeutsame SSOT-Änderung, Seite veröffentlicht/zurückgezogen) sowie manuell durch Agentur-Mitarbeiter erfasst. Anker ist der Kunde (contacts.id) — nicht der Kunden-Workspace —, damit Ereignisse auch ohne verbundenen Kunden-Workspace entstehen und die Zeitachse eine getrennte oder beendete Verbindung überdauert; die Kundensicht wird erst zur Anzeigezeit über eine aktive workspace_connections-Verbindung aufgelöst. Gespeicherte Felder: Ereignistyp und Quelle (feste, DB-geprüfte Wertelisten), Ereigniszeitpunkt (occurred_at, getrennt vom Anlagezeitpunkt — bei manuellen Nachträgen können beide auseinanderfallen, Zukunftsdaten werden abgelehnt), Wichtigkeitsstufe (Meilenstein/normal/Detail), Sichtbarkeit (intern als Standard, kunde nach Freigabe durch die Agentur — manuell je Ereignis oder, seit PROJ-2186, automatisch über eine je Ereignis-Quelle konfigurierbare Regel, siehe unten), Titel (max. 200 Zeichen), optionale Beschreibung (max. 2.000 Zeichen, nur bei manuellen Einträgen), JSONB-Metadaten (z.B. alter/neuer Status — ausschließlich intern, wird dem Kunden nie ausgeliefert), Urheber-Referenz created_by (ON DELETE SET NULL — verlässt die Person die Agentur, bleibt das Ereignis erhalten), Freigabe-Protokoll released_at/released_by. Zugriffsscope: Agentur-Mitglieder lesen Ereignisse ihres Workspace (RLS-SELECT), Kunden-Workspace-Mitglieder ausschließlich Ereignisse mit Sichtbarkeit 'kunde' ihres verbundenen Kontakts. Schreibzugriff ausschließlich über einen einzigen zentralen Helfer im API-Layer (workspace-scoped). Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Transparenz über Agenturtätigkeit gegenüber dem Kunden). Aufbewahrung: Bis zur Workspace-Löschung; created_by/released_by werden bei Mitglieder-Löschung auf NULL gesetzt, Ereignisse bleiben erhalten. Datenexport (Art. 15/20): customer_timeline_events ist im Workspace-Datenexport enthalten (als Agentur-Ersteller und als Kunden-Empfänger). Die abgelöste Alt-Tabelle client_feed_events bleibt bestehen (kein Backfill, keine Löschung) und weiterhin im Datenexport, wird aber nicht mehr beschrieben. Erweiterung PROJ-1876: Zu den bisherigen internen Quellen kommt die Quelle `google_ads` — die Änderungshistorie verbundener Google-Ads-Werbekonten wird täglich abgerufen und als verdichtete Ereignisse (elf `ads_*`-Ereignistypen) in dieselbe Tabelle geschrieben; `source_id` ist dafür von UUID auf Text erweitert und über eine Eindeutigkeitsregel (Workspace + Kontakt + Quelle + Kennung) gegen doppelte Importe abgesichert. Ads-Ereignisse entstehen immer mit Sichtbarkeit `intern` und tragen in `metadata` eine pseudonyme Urheber-Einstufung (`agentur`/`kunde`/`unbekannt`) — Einzelheiten im eigenen Verzeichniseintrag `PROJ-1876 Google-Ads-Änderungshistorie als Ereignisquelle`. Erweiterung PROJ-2186: Ein Admin/Manager der Agentur kann je Ereignis-Quelle (und optional je Kunde) eine Regel hinterlegen (`timeline_visibility_rules`), nach der neue Ereignisse dieser Quelle automatisch für den Kunden freigegeben werden (`release_source`='rule'), statt jedes Ereignis einzeln manuell freizugeben; Standard bleibt intern (Opt-in, fail-closed). Beim Anlegen einer Regel können bereits bestehende interne Ereignisse derselben Quelle auf Wunsch rückwirkend freigegeben werden. Eine manuell zurückgenommene automatische Freigabe wird protokolliert (`manually_withheld_at`/`manually_withheld_by`). Die Regel betrifft ausschließlich den Zeitpunkt/Automatisierungsgrad der Freigabe — nicht, welche Felder der Kunde sieht (unverändert wie oben beschrieben), und begründet keinen neuen Auftragsverarbeiter. Erweiterung PROJ-2003 (AP6 des Pakets PROJ-1997): Zu den bisherigen internen Quellen kommt die Quelle `repricing` — jede tatsächliche, vom HAWEGO-Repricing-Cron geschriebene Preisänderung erzeugt einen Eintrag (Ereignistyp `repricing_price_changed`) beim CRM-Kontakt 'Sonntag Handels GmbH & Co. KG'. Gespeicherte Daten sind ausschließlich Produkt-/Preisdaten (Artikel-ID/SKU/Name, Preis vorher/nachher, Marge, Produktgruppe, Kategorie) in `metadata` — keine personenbezogenen Enduser-Daten, kein Bezug zu natürlichen Personen. Sichtbarkeit entsteht wie bei den anderen automatischen Quellen immer `intern`; kundensichtbar wird ein Ereignis nur über die bestehende manuelle Freigabe oder eine von der Agentur konfigurierte PROJ-2186-Regel für die Quelle `repricing`. Idempotenz über `source_id` (`repricing:<product_id>:<Tag>`) verhindert Duplikate bei erneutem Cron-Lauf am selben Tag. Kein neuer Auftragsverarbeiter, keine neue Tabelle — reine Werteerweiterung auf der bestehenden `customer_timeline_events`.
- SSOT-Portal-Segment-Zuordnung (PROJ-1546, portal_tokens.segment_id): Optionales, von der Projekt-Zuordnung unabhängiges Filtermerkmal auf einem Kunden-Portal-Zugang, das die SSOT-Ansicht im Portal auf ein einzelnes Segment (Marke/Bereich) des Kontakts einschränkt — Fremdschlüssel auf crm_segments (siehe Verarbeitung 'SSOT Segment-Datenmodell'), keine neue personenbezogene Datenkategorie. NULL (Standard, alle Bestandszugänge) bedeutet unverändertes Verhalten ohne Filter. Nur die SSOT-Ansicht wird segmentiert — Kommentare, KI-Chat-Kontext und Feature-Board im Kunden-Portal bleiben unverändert unsegmentiert. Zuordnung jederzeit über eine Agentur-interne Verwaltungsoberfläche änderbar (kein Kundenzugriff auf diese Einstellung). Löschkonzept: Bei Segment-Löschung ON DELETE SET NULL (Segmente werden im System aber ohnehin nur archiviert, nie hart gelöscht). Kein neuer Auftragsverarbeiter, kein neues Tracking.
Angebots- & Signing-Workflow
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
- Angebotsinhalt und Konditionen
- Digitale Unterschrift (Name, Datum, Firmenname des Unterzeichners)
- Zahlungsweise beim Signing (Rechnung oder SEPA-Lastschriftmandat)
- E-Mail-Adresse des Unterzeichners
- Anrede des Ansprechpartners (optional, für personalisierte Angebotseinleitung)
- Datum des Erstgesprächs (optional, für Angebotseinleitung)
- Zahlungsplan-Auswahl und Mindestvertragslaufzeit (Beauftragungsoptionen)
- Kontaktperson-Widget (PROJ-264): Kontaktdaten des zuständigen Agentur-Mitarbeiters (Vorname, Nachname, E-Mail, Telefon, Jobtitel, Profilbild-URL) werden auf der öffentlichen, token-geschützten Signing-Seite als Kontaktkarte angezeigt. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung). Konfigurierbar: Agentur-Admin kann das Widget deaktivieren oder einen anderen Mitarbeiter als Ansprechpartner festlegen. Mitarbeiter werden durch die Nutzung des Systems über diese Verarbeitung informiert (interne Datenschutzhinweise / Arbeitsvertrag). Die Kontaktdaten werden nicht dauerhaft beim Besucher gespeichert und sind nur über den Angebots-Token zugänglich.
- Audio-Zusammenfassung (optional): KI-generierte Zusammenfassung des Angebotsinhalts (Leistungen, Konditionen, Ablauf) als MP3-Audiodatei und als Transkript-Text. Erstellt durch Claude Haiku (Textgenerierung) und ElevenLabs Multilingual v2 (Sprachsynthese). Enthält optional Anrede und Nachname der Kontaktperson für persönliche Ansprache — weitere personenbezogene Daten (E-Mail, Adresse) werden nicht einbezogen. Audio gespeichert im privaten Supabase-Storage-Bucket mit signierten URLs (1 Stunde Gültigkeit), Transkript-Text in der Datenbank. Löschung bei Angebots-Löschung. KI-Kennzeichnung auf der Signing-Seite gemäß EU AI Act
- Performance-KPIs (workspace_performance_kpis): Workspace-konfigurierbare Agentur-Leistungskennzahlen (z.B. '+45% Traffic-Anstieg') ohne Personenbezug — aggregierte Geschäftsmetriken, keine Daten zu identifizierbaren Personen. Werden auf der öffentlichen Signing-Seite angezeigt wenn aktiviert. Kein DSGVO-Erfordernis zur gesonderten Dokumentation, Erwähnung aus Transparenzgründen
- Team-Vorstellung auf der Signing-Seite (PROJ-285/286): Vorname, Nachname, Jobtitel und Profilbild der als Signing-Team konfigurierten Mitarbeiter werden auf der öffentlichen Signing-Seite angezeigt. Optional kann ein separates Signing-Portrait hinterlegt werden (siehe Feature 'Signing-Portraits'). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an professioneller Geschäftspräsentation)
- Buchungskalender-Link (PROJ-333): Optional kann auf der Signing-Seite ein Button angezeigt werden, der auf eine interne Buchungsseite des Terminbuchungssystems (/book/[token]) verlinkt. Die Buchungsseite selbst wird unter 'Terminbuchungssystem' dokumentiert. Der Link enthält keine personenbezogenen Daten — es handelt sich ausschließlich um einen Weiterleitungs-Button zu einem bestehenden internen Service. Konfiguration über workspace-weite Einstellungen (UUIDs + Text-Labels, kein Personenbezug).
- Angebots-Historie & View-Tracking (PROJ-335): Bei jedem Besuch der Signing-Seite durch einen externen Besucher wird ein pseudonymisierter Zugriffs-Eintrag erstellt. Gespeicherte Daten: SHA-256-Hash der IP-Adresse (nicht rückrechenbar), Geräte-Kategorie (Desktop/Mobilgerät/Tablet), Zeitstempel. Zweck: Vertriebssteuerung (Nachfass-Timing) und Debounce (mehrfache Aufrufe innerhalb von 5 Minuten werden zusammengefasst). Eingeloggte Agentur-Mitarbeiter lösen keinen Eintrag aus. Zusätzlich werden Angebots-Änderungen (Status-Übergänge, Feld-Änderungen, System-Aktionen) in einem internen Audit-Trail protokolliert, einschließlich der User-ID des Ändernden. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Vertriebssteuerung und Änderungsnachvollziehbarkeit). Speicherdauer: Bis zur Löschung des Angebots (CASCADE). Wird im DSGVO-Datenexport (Art. 15/20) ausgegeben.
- Manuelle Auftragsannahme (PROJ-678): Wenn ein Kunde ein Angebot außerhalb der digitalen Signing-Seite bestätigt (E-Mail, Telefon, persönlich), kann ein Admin/Manager das Angebot manuell als angenommen markieren. Gespeicherte Daten: Bestätigungsweg (E-Mail/Telefon/Vor-Ort), Freitext-Notiz des Mitarbeiters (acceptance_note, max. 1.000 Zeichen — kann Kunden-PII enthalten, z.B. Auszüge aus der Bestätigungs-E-Mail, Name des Ansprechpartners), Zeitstempel der Bestätigung, interne User-ID des bestätigenden Mitarbeiters. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Beauftragungsnachweis). Keine Übermittlung an externe Auftragsverarbeiter. Speicherdauer: Bis zur Löschung des Angebots (CASCADE-DELETE). Wird im DSGVO-Datenexport (Art. 15/20) ausgegeben (via contacts.ts data-export, R-241).
- Beleg-E-Mail-Verknüpfung (PROJ-679): Bei Bestätigungsweg 'E-Mail' (siehe Manuelle Auftragsannahme) kann der Mitarbeiter optional eine konkrete eingehende Kunden-E-Mail aus dem Sales-CRM-Posteingang (siehe Verarbeitung 'Sales CRM E-Mail Inbox-Sync') als Beleg verknüpfen. Gespeichert wird nur eine UUID-Referenz (acceptance_evidence_communication_id) auf den bestehenden sales_communication_log-Eintrag — keine Kopie oder Snapshot des E-Mail-Inhalts. Bei Löschung der referenzierten E-Mail aus dem Posteingang wird die Referenz automatisch genullt (ON DELETE SET NULL), das Angebot bleibt erhalten. Keine neue Datenverarbeitung, kein neuer Auftragsverarbeiter — reine Verknüpfung bestehender Datenkategorien. Im DSGVO-Datenexport als acceptance_evidence_subject (aufgelöster Betreff) ausgegeben.
- Beauftragungsbeleg-Snapshot (PROJ-681): Bei manueller Annahme mit verknüpfter Beleg-E-Mail wird die vollständige E-Mail GoBD-konform persistiert (Aufbewahrungspflicht 10 Jahre nach § 147 AO). Gespeicherte Daten: HTML-Body + Plain-Text-Body (acceptance_evidence_body_html/_plain — kann Kunden-PII enthalten: Empfänger-Name, Kommunikations-Inhalt), Empfänger-Listen (acceptance_evidence_to_emails/_cc_emails), Anhänge (quote_acceptance_evidence_attachments-Tabelle + Dateien im privaten Supabase-Storage-Bucket 'acceptance-evidence' mit RLS workspace-scoped). Größen-Limits: 10 MB pro Anhang, 50 MB gesamt pro Quote — übergroße Anhänge werden nur als Metadata (too_large=true) erfasst, nicht im Storage abgelegt. Rechtsgrundlage: Art. 6 Abs. 1 lit. c DSGVO (gesetzliche Aufbewahrungspflicht GoBD/AO) i.V.m. Art. 6 Abs. 1 lit. b (Vertragserfüllung — Beauftragungsnachweis). Keine externe Übermittlung — Snapshot läuft komplett in NEULAND-Infrastruktur (Supabase DB + Storage). CASCADE-DELETE bei Quote-/Workspace-Löschung. Im DSGVO-Datenexport ausgegeben (body_html, body_plain, to/cc-Listen, Attachment-Metadata).
- Auftragsstart-Transparenz (PROJ-723): Konfigurationsfeld workspaces.pm_notification_recipients (UUID[], default leer) speichert interne User-IDs der Workspace-Mitarbeiter, die bei Auftragseingang (digitale Signatur oder manuelle Offline-Annahme) per Inbox-Notification + E-Mail informiert werden. Enthält keine Kundendaten — ausschließlich interne Mitarbeiter-IDs (Referenz auf auth.users → workspace_members). Nur durch Workspace-Admin konfigurierbar. Löschkonzept: Bei Löschung eines Workspace-Mitglieds aus workspace_members wird seine ID bei der nächsten Notification-Auflösung aktiv herausgefiltert (is_active=false-Filter) und greift nicht mehr; das Array selbst wird nicht automatisch bereinigt (keine CASCADE) — veraltete IDs werden still ignoriert und erzeugen keine Notification. Löschung des Workspaces: CASCADE auf workspaces-Zeile, Spalte entfällt. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter interner Auftragskoordination). Nicht im Datenexport (Art. 15/20) enthalten — es handelt sich um eine interne Organisationskonfiguration ohne Kundenbezug; die referenzierten User-IDs sind über workspace_members bereits im Export erfasst.
- Archivieren von Angeboten (PROJ-981, quotes.archived/archived_at/archived_reason/archived_by): Angebote können vom Angebotsstatus getrennt archiviert werden (Boolean-Flag archived). Gespeichert werden: Zeitpunkt der Archivierung (archived_at), Archivierungsgrund als Vorgabe oder Freitext max. 500 Zeichen (archived_reason — in der Regel ohne Personenbezug, z.B. Angebot veraltet oder Deal verloren) und die interne User-ID des archivierenden Mitarbeiters (archived_by, Referenz auf auth.users, ON DELETE SET NULL; NULL bei automatischer System-Archivierung wenn ein verknüpfter Deal als verloren markiert wird). Reine Verwaltungs-Metadaten ohne Kundendaten — keine neue externe Übermittlung, kein KI-Einsatz. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an übersichtlicher Vertriebs- und Angebotsverwaltung). Löschkonzept: Die Felder sind Teil der quotes-Zeile und werden bei Angebots-Löschung (nur Entwürfe ohne Außenwirkung löschbar) bzw. Workspace-Löschung per CASCADE entfernt; archived_by wird bei Mitarbeiter-Löschung auf NULL gesetzt. Im DSGVO-Datenexport (Art. 15/20) als Teil der Quote-Daten enthalten.
Belegsystem (Auftragsbestätigungen, Rechnungen)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung nach GoBD/AO)
- PROJ-632 + PROJ-863 Auftragsbestätigungen (order_confirmations, order_confirmation_items): Pro AB werden Kontakt-Snapshot (Name + E-Mail) und Workspace-Snapshot persistiert. Positionen mit description/quantity/unit/unit_price_cents/tax_rate/phase analog Rechnungs-Positionen. Status: entwurf | gesendet | storniert. Beim Versand werden sent_at + sent_to_email + last_opened_at + open_count protokolliert (E-Mail-Tracking-Cross-Cutting PROJ-633). PROJ-863 Online-Ansicht: Pro AB wird ein UUID-Token (token, token_expires_at, Workspace-Default 90 Tage konfigurierbar 7-365) für einen Public-Link erzeugt, der dem Kunden eine reine Lese-Ansicht (digitales Abbild der AB + PDF-Download) ermöglicht — KEINE Signing-Seite und kein Accept/Reject-Workflow (eine AB ist die Bestätigung der Agentur über einen bereits angenommenen Auftrag und braucht keine erneute Kundenbestätigung). Geöffnet-Tracking ausschließlich über last_opened_at + open_count. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung), Art. 6 Abs. 1 lit. c (GoBD). RLS: agency_member SELECT, admin/manager INSERT/UPDATE/DELETE. Aufbewahrung: 8 Jahre §147 AO (analog Rechnungen). CASCADE-DELETE bei Workspace-Löschung. AB kann via /api/order-confirmations/:id/create-invoice eine Rechnung erzeugen (Verkettung via invoices.source_order_confirmation_id, ON DELETE SET NULL). Im DSGVO-Datenexport (Art. 15/20) enthalten — Token wird bewusst NICHT exportiert (Klartext-Geheimnis). PROJ-1719: Die Online-Ansicht zeigt zusätzlich zwei rein informative, zur Laufzeit berechnete Anzeigefelder — Abrechnungsmodell (Label + Beschreibungstext aus dem bereits dokumentierten quotes.signing_snapshot, s.o.) und Zahlungsart (Label aus quotes.payment_method bzw. aktivem SEPA-Mandat, s. PROJ-901-Eintrag). Beide Werte werden ausschließlich aus bereits an anderer Stelle dokumentierten Feldern abgeleitet. PROJ-1724: Beide Anzeigen erscheinen kompakt im Kopfbereich der Online-Ansicht sowie in beiden AB-PDFs (öffentlicher Download + interne Vorschau). Zusätzlich neues persistiertes Geschäftsdaten-Feld payment_method_override (Werte: rechnung | sepa | NULL) — ein manuell durch Agentur-Admin/Manager setzbarer Zahlungsart-Override ohne Personenbezug (reine Zahlungsmodalität des Belegs, keine Bankdaten); ein aktives SEPA-Mandat hat bei der Anzeige stets Vorrang. PROJ-1734: Analog dazu neues persistiertes Geschäftsdaten-Feld billing_model_override (Werte: monatliche_pauschale | nach_aufgabe | NULL) — ein manuell setzbarer Abrechnungsmodell-Override ohne Personenbezug (reine Abrechnungsmodalität des Belegs); der Override hat bei der Anzeige stets Vorrang vor dem Signing-Snapshot des Quell-Angebots. Im Workspace-Datenexport (Art. 20) enthalten.
- PROJ-687 Annahme-Pfad-Marker auf Angeboten (quotes.signed_via): Unterscheidet drei Pfade — customer_online (Kunde via Signing-Seite mit signing_snapshot), agency_on_behalf (Workspace-Member signiert stellvertretend für den Kunden, accepted_by_user_id dokumentiert welcher Member), offline_legacy (Bestands-Annahmen aus /accept-offline ohne Snapshot). Bei agency_on_behalf optional signed_email_attachment_path: Storage-Pfad zur Bestätigungs-E-Mail/PDF-Datei als Beleg (Bucket quote-acceptance-evidence, private, workspace-scoped RLS, Schema {workspace_id}/{quote_id}/{filename}, max 10 MB). Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung) + Art. 6 Abs. 1 lit. f (berechtigtes Interesse an GoBD-konformer Beleg-Kette). Aufbewahrung: 8 Jahre §147 AO (analog Quote-Snapshot). Storage-Objekt wird bei Quote-Löschung über CASCADE-Hook entfernt. Im DSGVO-Datenexport (Art. 15/20) als Teil der Quote-Daten enthalten.
- Kontaktname und E-Mail-Adresse (als Snapshot auf dem Beleg eingefroren)
- Firmenanschrift des Empfängers (Snapshot)
- Absender-Adresse und Steuernummer/USt-IdNr. (Snapshot)
- Bankverbindung: IBAN, BIC, Kontoinhaber (Snapshot auf Rechnungen)
- Rechnungsbeträge, Steuersätze, Leistungszeitraum, Zahlungsinformationen
- Belegnummern (fortlaufend, GoBD-konform). Aufbewahrung: 8 Jahre gemäß §147 AO
- Zeitpunkt der erstmaligen Einsichtnahme durch den Empfänger (Zustellbestätigung, Art. 6 Abs. 1 lit. f DSGVO — berechtigtes Interesse)
- Automatisierte Rechnungserstellung (Cron) basierend auf konfigurierten Vorlagen — Rechnungen werden als Entwurf erstellt und erfordern manuelle Freigabe. Konfigurationsgrundlage: Tabelle recurring_invoice_configs (gespeichert je Projekt: Kontaktreferenz, Titel, Positionen mit Beschreibung und Betrag, Zahlungskonditionen, Versandmodus, Starttag). PROJ-540 Auftragsstart-Wizard: Workspace-Admins können im Wizard-Schritt 3 eine Dauerrechnung direkt aus einem bestätigten Angebot konfigurieren. PROJ-558 Erweiterte Konfiguration: Interval-Einheit (8 Werte: wöchentlich bis zweijährlich), Häufigkeit (occurrences_limit — Anzahl Rechnungen bis zum automatischen Stopp, NULL = unbegrenzt), Zähler bereits generierter Rechnungen (invoices_generated — kein Personenbezug, reine Steuerungsgröße), Leistungsdatum-Template inkl. from_billed_items (MIN/MAX der optionalen item_date-Felder aus den Rechnungspositionen). Löschung: CASCADE DELETE bei Projekt-Löschung. Im DSGVO-Datenexport (Art. 15/20) enthalten. PROJ-1007 Kostenstellen-Split + Startmonat: billing_address_id (FK auf billing_addresses — Anschrift/Kostenstelle, ON DELETE SET NULL, indirekter Personenbezug über Empfänger-Kette) + billing_start_month (Startdatum, kein Personenbezug) — beide im Datenexport enthalten. Öffentliche Online-Vorschau (recurring_invoice_configs.online_token): Die Vorschau der nächsten generierten Rechnung kann login-frei über einen unratbaren UUID-Token abgerufen werden (Seite /dauerrechnung/[token] + Endpunkte /api/public/recurring-invoices/[token]/preview-data|preview-pdf|preview-zugferd) — analog zur Rechnungs-Online-Ansicht. Der Token wird lazy beim ersten Öffnen erzeugt (kein Ablaufdatum). Exponiert werden nur Beleg-Daten (Kundenname, Positionen, Beträge, Workspace-Bankdaten); interne Konfigurations-Notizen (notes) werden im öffentlichen Pfad bewusst NICHT angezeigt. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an einer teilbaren Beleg-Vorschau für den Kunden).
- ZUGFeRD 2.1-XML (E-Rechnung nach EU-Richtlinie 2014/55/EU): maschinenlesbare Rechnungsdaten mit Geschäftspartner-Informationen, on-the-fly generiert (nicht dauerhaft gespeichert)
- PROJ-538 Anzahlungs-/Teil-/Schlussrechnungen: Pro Angebot können mehrere Rechnungen erstellt werden — Anzahlungsrechnungen (mit Prozentsatz oder Pauschalbetrag-Snapshot in invoices.anzahlungs_basis), Teilrechnungen (fortlaufend nummeriert via invoices.invoice_sequence_no) und Schlussrechnungen (mit unveränderlichem Verrechnungs-Snapshot der vorherigen Anzahlungen in invoices.verrechnungs_snapshot — GoBD-konform). Rechnungstyp-Klassifikation in invoices.invoice_type (voll/anzahlung/teilrechnung/schlussrechnung). Im ZUGFeRD-XML wird pro Typ der korrekte documentTypeCode (380 Rechnung, 386 Anzahlung, 326 Teilrechnung) übermittelt; Schlussrechnungen enthalten zusätzlich den BG-22 priorPayments-Block. Rechtsgrundlage: § 14 UStG, GoBD §147 AO. RLS: Workspace-Mitglieder lesen, Admins/Manager schreiben. Aufbewahrung 8 Jahre (§147 AO). CASCADE-DELETE bei Workspace-Löschung. Im DSGVO-Datenexport (Art. 15/20) enthalten.
- PROJ-537 Eigene Kunden-Gutschriften (Credit Notes, § 14 Abs. 4 UStG): Zu jeder ausgestellten Rechnung können Gutschriften erstellt werden — als Vollgutschrift (alle Original-Positionen mit negativer Menge) oder Teilgutschrift (ausgewählte Positionen oder Pauschalbetrag mit Pflichtangabe Grund). Eigene Tabelle credit_notes mit eigenständigem Nummernkreis (Standard KG-YYYY-NNNN, konfigurierbar via document_number_configs.document_type='kg', distinkt von PROJ-110 Partner-GS). Gespeichert: Pflicht-FK auf Original-Rechnung (original_invoice_id, ON DELETE RESTRICT), Snapshot der Empfänger- und Absender-Adresse, Bankverbindung-Snapshot, Original-Rechnungs-Header (Nummer + Datum), Aggregat-Beträge (total_net/total_tax/total_gross), Steuermodus (is_kleinunternehmer vom Original geerbt), Status-Lifecycle (ausgestellt -> versendet -> kunde_angesehen). Positionen in credit_note_items mit negativer Menge (ZUGFeRD-381-Konvention). Public-Tokens in credit_note_tokens für /gutschrift/[token]-Seite (analog Rechnungen). Im ZUGFeRD-XML wird documentTypeCode 381 (Credit Note) übermittelt. Auto-Booking bei Anlage als negative accounting_entries-Buchung mit source_credit_note_id. Rechtsgrundlage: § 14 Abs. 4 UStG, GoBD §147 AO. RLS: Workspace-Mitglieder lesen, Admins/Manager schreiben. Aufbewahrung 10 Jahre (§147 AO Rechnungsbelege). Storno einer Gutschrift ist nicht möglich (GoBD); Korrektur erfolgt durch korrigierende Rechnung. CASCADE-DELETE auf credit_note_items + credit_note_tokens bei Gutschrift-Löschung; ON DELETE RESTRICT auf Original-Rechnung. Im DSGVO-Datenexport (Art. 15/20) enthalten.
- PROJ-572 Sprint-Kontingent-Verbrauchstracking (monthly_sprint_quota_periods): Pro Pauschale × Periode wird ein Snapshot mit Allocation, verbrauchten Sprints, Carryover-In/Out und Sprint-Preis-Snapshot geschrieben — rein technisches Verbrauchstracking ohne direkten Personenbezug. Workspace-scoped, CASCADE-DELETE bei Pauschale/Workspace-Löschung. Im DSGVO-Datenexport (Art. 15/20) als Teil der Pauschale-Konfiguration enthalten.
- PROJ-572 Vertragswechsel-Historie (recurring_invoice_config_revisions): Pro Pauschale-Anpassung (Stichtags-basiert) wird eine Revision angelegt mit Allocation, Sprint-Preis, Pauschale-Betrag, Begründung (Freitext) und Ersteller (User-Referenz auf Workspace-Member). Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) + Art. 6 Abs. 1 lit. f (berechtigtes Interesse an GoBD-konformer Vertragsdokumentation). Aufbewahrung: 8 Jahre (§147 AO, GoBD-Snapshot — wie Rechnungen). Workspace-scoped, CASCADE-DELETE bei Pauschale-Löschung (eigentlich GoBD-relevant — sollte später in Anonymisierungs-Cron statt CASCADE überführt werden). Im DSGVO-Datenexport (Art. 15/20) enthalten.
- PROJ-572 Leistungsnachweis-Verknüpfung (invoice_items.task_id, sprint_count, sprint_price_eur, cost_section): Rechnungspositionen können optional auf eine ausgeführte Aufgabe (tasks-Tabelle, FK ON DELETE SET NULL) verweisen. Sprint-Snapshot pro Position (sprint_count, sprint_price_eur) für GoBD-konforme Unveränderlichkeit. Cost-Section-Klassifikator (agentur/lizenz/system/token/werbe — analog quote_items). Im Online-Rechnungsseite (/rechnung/[token]) wird pro Position der Task-Titel und das Abschluss-Datum als Leistungsnachweis angezeigt — keine internen Daten (Zeiterfassung, Assignee-Namen, Workspace-Links sind ausgeschlossen).
- PROJ-1813 Sammelrechnungs-Konsolidierung: invoice_items.billing_class um den Wert k7_zusatzleistung erweitert (Klassifikator ohne Personenbezug, analog cost_section — davor separater täglicher Cron auto-invoice-completed-tasks für dieselben Zusatzleistungs-Positionen, seither eingegliedert in denselben monatlichen Sammellauf wie K1–K6). Neue Spalte invoice_items.project_id (FK auf projects, ON DELETE SET NULL, kein Personenbezug) hält pro Position das Ursprungsprojekt fest — Grundlage für die interne Anzeige einer Projekt-Kennzeichnung, wenn eine Sammelrechnung mehrere Projekte desselben Kontakts bündelt (siehe cross_project_billing_enabled oben); nur auf der internen Rechnungs-Detailansicht sichtbar, NICHT auf der öffentlichen Online-Rechnungsseite (/rechnung/[token]) — dort bleibt die Positions-Darstellung unverändert. Historische Positionen (vor PROJ-1813): project_id = NULL, keine Rückwirkung.
- PROJ-735 Wizard-Position-Override (quote_plan_items.wizard_billing_override_amount_cents/sprints, wizard_override_updated_at/by/note): Pro Quote-Plan-Item kann der Auftragsstart-Wizard im Schritt 3 (Belege) den Beleg-Betrag überschreiben, ohne den Signing-Snapshot zu verändern. Use-Cases: Goodwill-Nachlass (Lizenzkosten auf 0 €), Sprint-Reduktion einer Agentur-Position. Persistiert wird: Override-Betrag in Cent (NULL = kein Override), Sprint-Anzahl als UI-Hilfsfeld, Zeitstempel, User-ID (auth.users-FK ON DELETE SET NULL), optionale Notiz (max 200 Zeichen, erscheint als Sub-Description auf AB+Rechnung). Hochsetzen über den Signing-Snapshot-Wert hinaus ist nicht erlaubt — entspräche einem neuen Angebot. Nutzungsbasierte Positionen (Werbekosten/Token) sind ausgenommen. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — vertragliche Anpassungen im Annahme-Gespräch), Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an GoBD-konformer Dokumentation). RLS: Workspace-Mitglieder lesen, Admins/Manager schreiben (Application-Layer-Guard zusätzlich). Im DSGVO-Datenexport (Art. 15/20) enthalten.
- PROJ-735 Audit-Log (quote_position_override_log): Append-only-Tabelle protokolliert jede Override-Änderung mit alter Wert, neuer Wert, alte Notiz, neue Notiz, Zeitstempel, User-ID des Bearbeiters. Override-Typen: hours | billing_amount | billing_sprints | note | reset. RLS: Workspace-Mitglieder SELECT, INSERT nur via Service-Role (Application-Logic). Keine UPDATE/DELETE-Policy — Append-only nach GoBD. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an GoBD-konformer Vertragsdokumentation). Aufbewahrung: 8 Jahre §147 AO (analog Beleg-Snapshots). CASCADE-DELETE bei Workspace-Löschung über workspace_id-FK, bei Quote-Löschung über quote_id-FK, bei Plan-Item-Löschung über quote_plan_item_id-FK. Im DSGVO-Datenexport (Art. 15/20) enthalten.
- PROJ-901/PROJ-928 Vertragsdokumente-Bereitstellung beim Beleg-Versand: Die jeweils aktive Version der Allgemeinen Vertragsbedingungen zur Auftragsverarbeitung nach Art. 28 DSGVO (AVV) sowie der AGB werden seit PROJ-928 ausschließlich an der Auftragsbestätigung bereitgestellt — NICHT mehr als E-Mail-Anhang, sondern in der öffentlichen Online-Ansicht des Belegs als Akkordeon mit Links auf die öffentlichen PDF-Versionen (siehe https://os.neuland-agentur.com/avv und https://os.neuland-agentur.com/agb für die jeweils aktuell gültige Fassung). Bei Angeboten und Rechnungen werden AVV/AGB nicht (mehr) versendet. Inhaltsquelle: zentrale platform_legal_documents-Tabelle, plattformweit verwaltet im public-read Storage-Bucket platform-legal-documents. Die verlinkten PDFs sind statische Vertragsdokumente und enthalten keine Empfänger-PII. Ergänzend wird der Mail-Body im NEULAND.-Standardtext mit Anhang-Aufzählung formuliert und enthält bei Kontakten ohne aktives SEPA-Lastschriftmandat (Tabelle sepa_mandates, status='active') einen Hinweis-Block zur Mandats-Erteilung; bei aktivem Mandat wird dieser Hinweis automatisch unterdrückt. Versand erfolgt über den bestehenden Auftragsverarbeiter Resend (siehe PROCESSORS-Eintrag, USA mit Standardvertragsklauseln + EU-US-DPF). Open-Tracking via Resend-Webhook bleibt wie für PROJ-633 dokumentiert (last_opened_at, open_count).
- PROJ-901 CC/BCC-Empfänger-Autocomplete: Der Send-Dialog für Angebote und Auftragsbestätigungen schlägt beim Tippen Empfänger aus zwei Quellen vor: (a) Ansprechpartner des verknüpften Kontakts (contact_persons mit E-Mail-Adresse und ggf. additional_emails) und (b) Mitglieder des aktiven Workspace (workspace_members mit display_name aus profiles und E-Mail aus auth.users). Die Liefer-Route /api/contacts/:id/recipient-suggestions ist Workspace-Scope-geschützt (Kontakt muss zum aktiven Workspace gehören). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — effizienter interner Workflow). Keine Speicherung der Vorschlagsliste — wird pro Dialog-Öffnung neu berechnet. Im DSGVO-Datenexport ist die Datenquelle bereits über contact_persons und workspace_members enthalten.
- PROJ-901 Einheitliches Betreff-Format und einheitlicher E-Mail-Body über die drei Belegtypen (Angebot, Auftragsbestätigung, Rechnung) zur besseren Erkennbarkeit beim Empfänger: Betreff im Format Belegtyp Nummer vom Datum (TT.MM.JJJJ). Body folgt dem NEULAND.-Standardmuster (Anrede personalisiert mit Salutation und Name des Ansprechpartners falls aus dem zugehörigen Signing-Vorgang bekannt, Bullet-Aufzählung der mitgesandten Dokumente, optionaler SEPA-Hinweis, Dankesgruß). Bei Auftragsbestätigungen wird zusätzlich ein Online-Lese-Link zur AB mit PDF-Download-Möglichkeit beigefügt.
Plattform-Vertragsdokumente (AVV nach Art. 28 DSGVO, AGB)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: zentrale, versionierte Verwaltung der Plattform-Vertragsdokumente sowie nachweisbare Bereitstellung gegenüber Kunden) sowie Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung: Pflicht zur Bereitstellung eines Auftragsverarbeitungsvertrags nach Art. 28 DSGVO).
- PROJ-901 platform_legal_documents (zentrale Tabelle ohne Workspace-Scope): Speichert pro Dokumenttyp (avv = Allgemeine Vertragsbedingungen zur Auftragsverarbeitung nach Art. 28 DSGVO; agb = Allgemeine Geschäftsbedingungen) eine Versions-Historie mit Bezeichnung (Freitext, z. B. Stand Juli 2024), Gültigkeits-Datum, Status (draft, active oder archived), Hochlade-Zeitstempel und Hochlade-Identität (uploaded_by als Referenz auf auth.users). Pro Dokumenttyp ist über einen Partial-UNIQUE-Index maximal eine active-Version garantiert. Der Personenbezug beschränkt sich auf den die Aktivierung auslösenden Plattform-Administrator; keine Endkunden- oder Workspace-PII in der Tabelle.
- Storage-Bucket platform-legal-documents (public-read, MIME-Whitelist application/pdf, max. 10 MB pro Datei): Speichert die zugehörigen PDF-Dateien unter Pfadschema doc_type/slug.pdf. Bewusste Abweichung vom Standard-Workspace-Pfad-Muster (kein workspace_id-Prefix), weil die Dokumente plattformweit für alle Kunden gelten — die Inhalte sind nicht vertraulich und sollen über statische öffentliche URLs erreichbar sein. RLS auf der Storage-Objects-Tabelle erlaubt SELECT für alle (anonym und authentifiziert), INSERT/UPDATE/DELETE nur für Platform-Admins. Storage-URLs sind deterministisch und können von Suchmaschinen indexiert werden.
- Öffentliche Bereitstellung: Die jeweils aktive Version pro Dokumenttyp ist ohne Authentifizierung unter https://os.neuland-agentur.com/avv und https://os.neuland-agentur.com/agb abrufbar (Server-Side-Rendering mit ISR von 60 Minuten, eingebettete PDF-Vorschau via Browser-natives object-Element, Download-Button). Die Seiten zeigen Versions-Bezeichnung und Gültigkeits-Datum prominent an, damit Kunden erkennen können welche Fassung aktuell gültig ist. Frühere Fassungen sind nicht öffentlich indexiert, aber bei Bedarf über die Platform-Admin-UI rekonstruierbar.
- Admin-UI unter /admin/platform-documents: Zwei Tabs (AVV und AGB) mit Versions-Tabelle und Upload-Dialog (PDF-Datei, Versionsbezeichnung, Gültigkeits-Datum, optionale Notiz, Toggle für direkte Aktivierung). Beim Aktivieren einer neuen Version wird die bisherige active-Version automatisch in den Status archived überführt (transaktionale Folge im Backend). Entwürfe (status='draft') können gelöscht werden; active- und archived-Versionen bleiben dauerhaft erhalten (DSGVO-Nachweispflicht: welche Version war wann gültig).
- Audit-Trail: Jede Versions-Aktivierung erzeugt einen Eintrag in der zentralen system_logs-Tabelle mit category='platform_legal_documents', message='Plattform-Dokument aktiviert: TYP VERSION' und Details-JSON (event_type='platform_legal_document_activated', document_id, doc_type, version, valid_from, storage_path, previous_status falls Status-Wechsel). Dient als maschinenlesbarer Nachweis nach Art. 5 Abs. 2 DSGVO (Rechenschaftspflicht) für DSGVO-Audits durch Behörden oder Kunden.
- Bereitstellung im Belegversand: AVV und AGB werden seit PROJ-928 ausschließlich an der Auftragsbestätigung bereitgestellt — in deren öffentlicher Online-Ansicht als Links auf die aktuell aktiven PDF-Versionen (siehe Eintrag Belegsystem); bei Angeboten und Rechnungen werden sie nicht versendet. Da die Auftragsverarbeitung mit der Auftragsbestätigung beginnt, erfüllt NEULAND. damit die Pflicht aus Art. 28 DSGVO, dem Kunden vor Beginn der Auftragsverarbeitung den AVV zugänglich zu machen.
- Aufbewahrung: Archivierte Versionen werden NICHT automatisch gelöscht — sie sind der DSGVO-Nachweis dafür, welche Fassung wann gültig war. Nur Drafts können über die Admin-UI gelöscht werden. Bei Platform-Admin-Account-Löschung wird uploaded_by automatisch auf NULL gesetzt (ON DELETE SET NULL) — die Dokumenten-Historie bleibt erhalten. Speicherort: ausschließlich EU (Supabase EU-Region).
- Im workspace-bezogenen DSGVO-Datenexport NICHT enthalten — die Dokumente sind plattformweit und nicht workspace-spezifisch. Endkunden können die jeweils aktive Fassung jederzeit über die statischen URLs herunterladen.
Vorbereitende Finanzbuchhaltung
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung nach GoBD/AO und §147 AO)
- Buchungszeilen: Buchungstext, Nettobetrag, MwSt.-Satz, Belegdatum, Belegnummer (GoBD-Pflichtfeld)
- Kontaktzuordnung: Optionaler Verweis auf Lieferant oder Kunde (Name) für Buchungszeilen
- Buchungskonten (SKR03/SKR04): Sachkontennummern und Gegenkonten — keine personenbezogenen Daten
- DATEV-Exportdateien (CSV und XML): Enthalten Buchungszeilen, Beraternummer und Mandantennummer — als unveränderliche GoBD-Kopien in Supabase Storage gespeichert (8 Jahre gemäß §147 AO)
- UStVA-Zusammenfassungen (PDF): Aggregierte Umsatz- und Vorsteuerbeträge nach Kennzahlen (KZ 81, 86, 66, 65) — als unveränderliche Kopien in Supabase Storage gespeichert
- Perioden-Status: Buchungsmonat (YYYYMM), Abschlussstatus, Öffnungs-Begründung — für GoBD-Audit-Trail
- DMS-Import: Belegdaten werden aus freigegebenen DMS-Dokumenten extrahiert und als Buchungszeile übernommen
- Buchungszeilen mit Status 'storniert' werden nicht gelöscht (GoBD-Unveränderbarkeit). Aufbewahrung: mindestens 8 Jahre nach Buchungsjahr gemäß §147 AO
- Exportdateien in Supabase Storage: Bucket 'accounting-exports' (privat, kein öffentlicher Zugriff), signierte Download-URLs (60 Min. Gültigkeit)
Vorbereitende Lohnbuchhaltung
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung nach GoBD/AO). Für Krankheitstage (Gesundheitsdaten): Art. 9 Abs. 2 lit. b DSGVO i.V.m. §26 BDSG (Durchführung des Beschäftigungsverhältnisses).
- Beschäftigungstyp (Vollzeit, Teilzeit, Minijob, Werkstudent, Freelancer)
- Bruttolohn / Monatshonorar
- Steuerklasse (1–6, nur bei SV-pflichtigen Beschäftigungsverhältnissen)
- Sozialversicherungspflicht (ja/nein)
- DATEV-Personalnummer (eindeutig pro Workspace)
- Organstellung (Geschäftsführer/in, ja/nein) — steuert ausschließlich einen informativen Hinweis zum Arbeitszeitgesetz in der Zeiterfassung, keine Berechtigungswirkung
- Gehaltshistorie (historisiert mit Gültigkeitsdatum, Append-only — bestehende Einträge werden nicht überschrieben)
- Monatliche variable Posten: Urlaubstage, Krankheitstage (AU-Tage), Bonus, Reisekosten, Freitext-Notizen (manuell, keine automatische Befüllung), bei stundenbasierter Vergütung (z. B. Minijob) zusätzlich abgerechnete Stunden und der zum Übernahme-Zeitpunkt gültige Stundensatz
- Ein- und Austrittsdatum (bei Personalveränderungen im laufenden Monat)
- Export-Audit-Trail: Zeitstempel, exportierender Admin, Exporttyp und Dateiname (unveränderlich gespeichert)
- Zugriff ausschließlich für Workspace-Administratoren (RLS-geschützt). Aufbewahrung: 6 Jahre (§257 HGB / §147 AO). Finalisierte Lohnperioden sind GoBD-konform unveränderlich (Datenbank-Trigger).
- Wallbox-Ladestrom-kWh (PROJ-1797): Monatlich automatisch berechnete Sachbezugsgrundlage für privat geladenen Dienstwagen-Strom (charging_kwh), abgeleitet aus einzelnen Ladevorgängen einer privaten Wallbox (RFID-Karten-Bezeichnung, Zeitstempel, kWh, Zählerstände — gespeichert in separaten Tabellen wallbox_reports/wallbox_charging_sessions/wallbox_rfid_card_mappings). Zuordnung RFID-Karte zu Mitarbeiter wird bei Mitarbeiter-Löschung automatisch entfernt (Fremdschlüssel auf NULL gesetzt), die Ladevorgangs-Rohdaten bleiben ohne Personenbezug als Audit-Trail für den steuerlichen Einzelnachweis erhalten. Übernahme in die Lohnperiode erfolgt automatisch nur solange diese nicht finalisiert ist (GoBD-Sperre respektiert). PDF-Berichtstext wird zur strukturierten Extraktion an Anthropic übermittelt (siehe Anthropic-Eintrag oben). Zugriff identisch zu den übrigen Lohnbuchhaltungsdaten dieses Eintrags.
Steuerberater-Workspace
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizientem Belegaustausch)
- Verbindungsdaten: Zuordnung Steuerberater-Workspace ↔ Agentur-Workspace, Verbindungsstatus, Zeitstempel
- Einladungs-E-Mail-Adresse: Wird nur für die Einladung gespeichert und nach Annahme oder Ablauf (7 Tage) automatisch gelöscht
- Kommentare und Rückfragen des Steuerberaters zu freigegebenen Dokumenten (Freitext, max. 2.000 Zeichen, löschbar durch den Ersteller)
- Dokumenten-Prüfstatus: ausstehend/geprüft/Rückfrage — gesetzt vom Steuerberater, sichtbar für Agentur-Admins
- Cross-Workspace-Lesezugriff auf freigegebene DMS-Dokumente und finalisierte Rechnungen des Mandanten (kein Schreibzugriff)
- DATEV-Exportprotokoll: Mandant, Zeitraum, Exportdatum, exportierender Nutzer, Anzahl Rechnungen, Gesamtbeträge — Aufbewahrung 8 Jahre (GoBD)
- Signierte Download-URLs für Dokumente und Rechnungs-PDFs (Gültigkeit: 1 Stunde)
- Benachrichtigungs-E-Mails bei Verbindungsanfragen, Annahme, Trennung und Rückfragen (über Resend)
Partner-Workspace (externe Dienstleister)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Dienstleistungsvertrag mit Freelancer/Partner) und Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung — Aufbewahrung steuerrelevanter Daten nach §147 AO, §257 HGB)
- Partner-Stammdaten: Firmenname, Vorname, Nachname, E-Mail-Adresse, Telefonnummer, Geschäftsadresse (Straße, PLZ, Ort). Zweck: Identifikation, Kommunikation, Rechnungsadressierung. Aufbewahrung: Dauer der Geschäftsbeziehung + 8 Jahre (§147 AO — Partner-Gutschriften sind steuerrelevante Belege)
- Steuerliche Daten: USt-IdNr. und Steuernummer. Zweck: Rechnungsstellung nach UStG §14, steuerliche Zuordnung. Aufbewahrung: 8 Jahre (§147 AO). Bei Änderung: automatische Benachrichtigung an Plattform-Admins per E-Mail und Inbox-Notification
- Bankverbindung (IBAN): Verschlüsselt gespeichert (AES-256-GCM mit eigenem Schlüssel PARTNER_IBAN_ENCRYPTION_KEY, getrennt von SEPA- und Banking-Schlüsseln). Anzeige nur maskiert (erste 4 + letzte 4 Zeichen). Zweck: Zahlungsabwicklung für Partner-Gutschriften. Bei Deaktivierung: IBAN bleibt verschlüsselt erhalten bis Aufbewahrungsfrist abläuft
- Stundensätze: Regulärer Stundensatz und Fahrt-Stundensatz. Zweck: Berechnung von Partner-Gutschriften
- Projektzugänge: Zuordnung Partner ↔ Projekte mit Zeitstempel und gewährendem Nutzer. Zweck: Zugriffskontrolle auf Projektdaten, Aufgaben und Zeiterfassung. Löschung: automatisch bei Projekt-Löschung (CASCADE)
- Workspace-Verbindung: Zuordnung Partner-Workspace ↔ Agentur-Workspace über bestehendes Verbindungssystem. Deaktivierung durch Admin möglich (Soft-Delete: is_active=false)
- Einladungs-E-Mail: Bei Partner-Erstellung wird eine Einladungs-E-Mail mit Registrierungs-Link an die Partner-E-Mail gesendet (über Resend). Der Link enthält Workspace-ID und E-Mail als URL-Parameter
- Öffentliches Registrierungsformular (/partner/registrierung): Datenerhebung ohne Login über ein öffentliches Formular. Nach Eingabe der Firmendaten wird die Gutschriftverfahren-Vereinbarung (§14 Abs. 2 UStG) digital unterzeichnet. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung). Einwilligung zur Datenschutzerklärung wird per Pflicht-Checkbox eingeholt. Rate Limiting: 5 Registrierungen pro IP/Stunde
- Signing-Metadaten: Digitale Unterschrift (Name als Text), Signing-Zeitstempel, IP-Adresse (SHA-256-pseudonymisiert mit Salt, keine Klartextspeicherung), Vereinbarungsversion. Zweck: Rechtliche Nachweisbarkeit des Vertragsschlusses (Art. 6 Abs. 1 lit. f DSGVO — berechtigtes Interesse). PDF der unterzeichneten Vereinbarung wird in einem privaten Storage-Bucket gespeichert (nur Platform-Admins haben Zugriff). Aufbewahrung: 8 Jahre (§147 AO)
- DSGVO-Datenexport (Art. 15/20): Partner-Stammdaten, Signing-Metadaten (Unterschriftsname, Zeitstempel, IP-Hash) und Projektzugänge sind im Workspace-Datenexport enthalten. IBAN ist verschlüsselt gespeichert — Klartext-Auskunft auf Anfrage beim Verantwortlichen
- Löschung/Anonymisierung: Bei Workspace-Löschung werden alle Partner-Daten automatisch gelöscht (CASCADE). Bei Deaktivierung (Soft-Delete) bleiben Daten für die steuerrechtliche Aufbewahrungsfrist erhalten. Automatisierte Anonymisierung nach 8 Jahren Inaktivität (monatlicher Cron, §147 AO) — PII wird durch Platzhalter ersetzt, PDF der Vereinbarung gelöscht
Partner-Zeiterfassung & Tätigkeits-Erfassung
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Dienstleistungsvertrag mit Freelancer/Partner) und Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung — Aufbewahrung steuerrelevanter Daten nach §147 AO, §257 HGB)
- Zeiteinträge: Datum, Eintragstyp (Tätigkeit/Reisezeit/Aufwand), Stundenzahl, Beschreibung (max. 2000 Zeichen), verknüpftes Projekt und Aufgabe (optional), Status (Entwurf/Eingereicht/Freigegeben/Abgelehnt), Ablehnungsgrund. Zweck: Dokumentation geleisteter Arbeit, Grundlage für Gutschrifterstellung. Aufbewahrung: 8 Jahre (§147 AO, GoBD-Belegpflicht)
- Monatseinreichungen: Zeitraum (Monat/Jahr), Einreichungsdatum, Status (Offen/Eingereicht/Teilweise freigegeben/Freigegeben/Abgelehnt), freigegebene Gesamtstunden und Gesamtbetrag. Zweck: Zusammenfassung der monatlichen Zeiterfassung für Admin-Freigabe. Aufbewahrung: 8 Jahre (§147 AO)
- Erinnerungs-E-Mails: Täglicher Cron-Job (ab dem 25. des Monats) sendet Erinnerungs-E-Mails an Partner ohne Einreichung. Am 1. des Folgemonats: Admin-Benachrichtigung über ausstehende Einreichungen. Versand über Resend
- Benachrichtigungen: 5 Notification-Typen (Eingereicht, Freigegeben, Abgelehnt, Erinnerung, Ausstehend) mit Metadaten wie Gesamtstunden, Betrag, Ablehnungsgrund. Zustellung per Inbox und optional per E-Mail/Push
- CSV-Export: Admin-Export aller Zeiteinträge eines Partner-Monats mit DDE-sicherer Sanitisierung. Enthält: Datum, Typ, Projekt, Aufgabe, Beschreibung, Stunden, Status, Ablehnungsgrund
- DSGVO-Datenexport (Art. 15/20): Alle Zeiteinträge und Monatseinreichungen des Partner-Workspaces sind im Workspace-Datenexport enthalten
- Löschung: Bei Workspace-Löschung werden alle Zeiteinträge und Einreichungen automatisch gelöscht (CASCADE). Finalisierte Einträge (Status 'freigegeben') bleiben für die steuerrechtliche Aufbewahrungsfrist erhalten (8 Jahre gemäß §147 AO)
Partner-Gutschriften & Self-Billing
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Gutschriftverfahren nach Partner-Vereinbarung) und Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung — §14 Abs. 2 Nr. 2 UStG Gutschriftverfahren, §147 AO Aufbewahrungspflicht 10 Jahre für Rechnungen/Gutschriften)
- Gutschrift-Daten: Gutschrift-Nummer (GS-YYYY-NNNN), Leistungszeitraum (Monat/Jahr), Status (Entwurf/Finalisiert/Storniert), Finanzbeträge (Netto, Steuersatz, Steuerbetrag, Brutto), Kleinunternehmer-Kennzeichen. Zweck: Abrechnungsdokument nach §14 Abs. 2 Nr. 2 UStG. Aufbewahrung: 10 Jahre (§147 AO — Rechnungen/Gutschriften)
- Adress-Snapshots (GoBD-Momentaufnahmen): Zum Finalisierungszeitpunkt werden Partner-Stammdaten (Firmenname, Name, Adresse, USt-IdNr., Steuernummer) und NEULAND.-Daten als unveränderlicher JSONB-Snapshot gespeichert. Zweck: GoBD-konforme Archivierung — Adressänderungen nach Finalisierung dürfen den Beleg nicht rückwirkend verändern. Aufbewahrung: 10 Jahre (§147 AO)
- Gutschrift-Positionen: Leistungsbeschreibung, Stundenzahl, Stundensatz, Nettobetrag, Positionstyp (Tätigkeit/Reisezeit). Verknüpfung zu Partner-Zeiteinträgen (PROJ-109). Aufbewahrung: 10 Jahre (§147 AO)
- PDF-Dokument: Generiert bei Finalisierung mit allen §14 UStG-Pflichtangaben. Gespeichert in privatem Supabase Storage-Bucket (partner-credit-notes, public=false). Storage-Pfad enthält SHA-256-Content-Hash (Integritätssicherung). Upload nur durch Platform-Admins (Service Role). Download über signierte URLs (60 Sekunden TTL). Aufbewahrung: 10 Jahre (§147 AO, GoBD)
- Storno-Gutschriften: Bei Stornierung wird eine Storno-Gutschrift (SG-YYYY-NNNN) mit negativen Beträgen erstellt. Original-Gutschrift wird als storniert markiert. Storno-Grund als Freitext. Storno erzeugt Reversal-Buchung in der Finanzbuchhaltung (PROJ-54). Physische Löschung finalisierter Gutschriften ist technisch blockiert (GoBD)
- Einwand-Verfahren: Partner kann innerhalb von 5 Kalendertagen nach Finalisierung einen Einwand als Freitext einreichen. Einwandtext und Einreichungszeitpunkt werden gespeichert. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — vereinbartes Widerspruchsverfahren). Aufbewahrung: zusammen mit der Gutschrift (10 Jahre)
- E-Mail-Versand: Bei Finalisierung wird eine E-Mail mit PDF-Anhang an die Partner-E-Mail gesendet (über Resend). Bei Storno: E-Mail an Partner. Bei Einwand: E-Mail an Platform-Admin. Keine dauerhafte Speicherung der E-Mail-Inhalte in NEULAND. OS
- Benachrichtigungen: 3 Notification-Typen (Gutschrift versendet, Einwand eingegangen, Gutschrift erhalten) mit Metadaten (Gutschrift-Nummer, Partner-Name, Bruttobetrag). Zustellung per Inbox
- Finanzbuchhaltungs-Integration: Bei Finalisierung wird automatisch ein Buchungseintrag in PROJ-54 erstellt (Aufwand Fremdleistungen). Bei Storno wird ein Reversal-Buchungseintrag erstellt. Buchungssätze nach SKR03 oder SKR04 (Workspace-Einstellung)
- DSGVO-Datenexport (Art. 15/20): Alle Gutschriften, Positionen und Adress-Snapshots sind im Workspace-Datenexport enthalten. PDF-Download über die Gutschriften-Seite verfügbar
- Löschung/Anonymisierung: Entwürfe sind löschbar (DELETE API mit GoBD-Guard). Finalisierte Gutschriften unterliegen der 10-Jahres-Aufbewahrungspflicht (§147 AO) — keine vorzeitige Löschung. Nach Ablauf der Aufbewahrungsfrist: automatische Anonymisierung der Adress-Snapshots und Löschung der PDF-Dokumente (monatlicher Cron)
Bankanbindung & Zahlungsabgleich
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung nach GoBD/§147 AO). Für Zahlungspartnerdaten (Drittbetroffene): Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an ordnungsgemäßer Buchführung und Zahlungsabgleich).
- Bankverbindungsdaten: IBAN (maskiert angezeigt), Kontoname, Kontotyp (Girokonto/Kreditkarte/Sparkonto), aktuelle und verfügbare Salden. Verschlüsselung der finAPI-Zugangsdaten: AES-256-GCM mit eigenem Schlüssel (FINAPI_ENCRYPTION_KEY), getrennt von anderen Verschlüsselungsschlüsseln
- Kontoumsätze: Buchungsdatum, Wertstellungsdatum, Betrag, Währung, Verwendungszweck, Primanota, Transaktionsart. GoBD-konform unveränderbar nach Import. Aufbewahrung: 8 Jahre gemäß §147 AO
- Zahlungspartnerdaten (Drittbetroffene): Name, IBAN und BIC des Überweisungssenders/-empfängers. Diese Daten werden automatisch von der Bank im Rahmen des Kontoumsatzes übermittelt. Rechtsgrundlage: berechtigtes Interesse (Art. 6 Abs. 1 lit. f DSGVO) an ordnungsgemäßer Buchführung und Zahlungsabgleich. Aufbewahrung: 8 Jahre (GoBD)
- Zahlungsabgleich: Automatische und manuelle Zuordnung von Umsätzen zu Rechnungen mit Konfidenzwert, Abgleich-Grund, Teilzahlungskennzeichen, Bestätigungsstatus und Bestätiger-User-ID. Aufbewahrung: 8 Jahre (GoBD-Audit-Trail)
- finAPI-Rohdaten (JSONB): Vollständige API-Response als unveränderlicher Originalbeleg (GoBD-Nachweispflicht)
- Bank-Login: Erfolgt ausschließlich über den PSD2-konformen finAPI Web Form im Browser des Nutzers. Bank-Zugangsdaten (PIN, TAN) werden zu keinem Zeitpunkt an NEULAND. OS übermittelt oder dort gespeichert
- Steuerberater-Zugriff: Kontoauszüge können als DATEV-kompatible CSV für verbundene Steuerberater exportiert werden. Zugriff nur über validierte Steuerberater-Verbindung
- Bei Trennung der Bankverbindung: Verschlüsselte finAPI-Zugangsdaten werden sofort gelöscht (auf NULL gesetzt). Transaktionsdaten bleiben GoBD-konform aufbewahrt (6–8 Jahre). Automatische Synchronisation wird deaktiviert
Provisionsmanagement
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Arbeitsvertrag mit Vertriebsmitarbeiter) und Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung — lohnsteuerrechtliche Dokumentation)
- Provisionssatz und Vertriebsmitarbeiter-Zuordnung am Kundenkontakt: Zur Berechnung der Vertriebsprovision bei Zahlungseingang
- Provisionsposten: Provisionssatz, provisionsfähiger Nettobetrag, Zahlungsanteil, Provisionsbetrag, Zahlungsdatum, Status (offen/in Abrechnung/ausgezahlt). Verknüpfung mit Rechnung und Kontakt. Aufbewahrung: 8 Jahre (lohnsteuerrechtlich relevant, analog §147 AO)
- Storno-Posten: Bei Änderung des Zahlungsanteils wird ein Storno-Eintrag erstellt (negative Gegenbuchung). Bereits ausgezahlte Provisionen können nicht automatisch storniert werden (manueller Eingriff erforderlich)
- Benachrichtigungen: Bei Provisionsberechnung wird der zugewiesene Vertriebsmitarbeiter benachrichtigt. Die Benachrichtigung enthält den Kontaktnamen und Provisionsbetrag. Aufbewahrung: 90 Tage (Standard-Notification-Retention)
- Bei Kontaktlöschung (Art. 17 DSGVO): Provisionsposten bleiben erhalten (GoBD-Aufbewahrungspflicht), die Kontaktzuordnung wird auf NULL gesetzt (Anonymisierung). Provisionsdaten sind im DSGVO-Datenexport (Art. 15/20) enthalten
Affiliate-Programm
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung mit genehmigten Affiliates) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Programmvermittlung und betrugsresistentem Klick-Tracking). Für die Bewerbungsphase (vor Genehmigung): Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung)
- Bewerberdaten (affiliate_applications): Vorname/Nachname oder Unternehmensname, E-Mail-Adresse, Unternehmensname (optional), Kanal-URL (Website, Social-Media-Profil), Beschreibung der Marketingaktivitäten. Aufbewahrung: Bis zur Entscheidung (Genehmigung/Ablehnung) + 90 Tage. Abgelehnte Bewerbungen werden nach 90 Tagen automatisch gelöscht
- Affiliate-Stammdaten (affiliates): Verknüpfung mit NEULAND. OS-Nutzer-ID und Workspace-ID, eindeutiger Referral-Code (system-generiert, nicht personenbezogen), Provisionssatz, Status (aktiv/pausiert/deaktiviert), Erstellungsdatum. Aufbewahrung: Dauer der Affiliate-Beziehung + 6 Jahre (steuerrechtlich, §257 HGB)
- Bankverbindung für Auszahlungen (affiliate_payouts): IBAN verschlüsselt gespeichert (AES-256-GCM mit eigenem Schlüssel AFFILIATE_IBAN_KEY, getrennt von anderen Verschlüsselungsschlüsseln). Anzeige nur maskiert. Kontoinhaber-Name. Aufbewahrung: 8 Jahre nach Auszahlung (steuerrechtliche Aufbewahrung, §257 HGB / §147 AO)
- Klick-Tracking (affiliate_referral_clicks): IP-Adresse wird als SHA-256-Hash gespeichert — keine Rückverfolgung auf die Originaladresse möglich (pseudonymisiert nach DSGVO-Standards). User-Agent-String ebenfalls als SHA-256-Hash. Zweck: Deduplizierung und Betrugsresistenz. Aufbewahrung: 90 Tage, danach automatische Löschung
- Provisions-Daten (affiliate_conversions): Zuordnung Affiliate ↔ Workspace ↔ Rechnung, Nettobetrag, Provisionsbetrag, Abrechnungszeitraum, Status (ausstehend/genehmigt/ausgezahlt/storniert). Aufbewahrung: 8 Jahre (steuerrechtlich relevant)
- Benachrichtigungen: Affiliates erhalten In-App-Benachrichtigungen bei neuen Provisionen (Betrag, Abrechnungszeitraum). Keine Übermittlung personenbezogener Kundendaten des geworbenen Workspaces
- Bestätigungs-E-Mail: Nach Bewerbungseingang wird der Name und die E-Mail-Adresse des Bewerbers über den E-Mail-Dienstleister Resend zur Zustellung einer Eingangsbestätigung übermittelt
- Referral-Cookie (nland_ref): Beim Klick auf einen Affiliate-Link wird ein Cookie mit dem Referral-Code gesetzt (kein personenbezogener Inhalt, nur technische Kennung). Lebensdauer: 90 Tage
- Löschung/Betroffenenrechte: Affiliate-Bewerbungen können durch Plattform-Admins vollständig gelöscht werden. Aktive Affiliate-Daten werden bei Kontenauflösung anonymisiert (user_id → NULL), Provisions- und Auszahlungsdaten bleiben für die steuerrechtliche Aufbewahrungsfrist erhalten. Klick-Hashes werden nach 90 Tagen automatisch gelöscht. IBAN-Daten werden nach Ablauf der steuerrechtlichen Aufbewahrungsfrist gelöscht
Empfehlungsprogramm im Kundenworkspace
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Empfehlung als Leistungsverhältnis zwischen Agentur und empfehlendem Kunden) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an Kundengewinnung durch bestehende Kunden)
- Empfehlungsdaten (referral_submissions): Unternehmensname des empfohlenen Unternehmens, Name des Ansprechpartners, E-Mail-Adresse, Telefonnummer (optional), Kontext-Notiz (optional), ausgewählte Empfehlungsthemen, Status (Eingegangen/Kontaktiert/In Gespräch/Beauftragt/Nicht zustande gekommen), Gutschrift-Betrag zum Einreichungszeitpunkt. Aufbewahrung: Bis zur Ablehnung oder Löschung durch den Nutzer (sofern keine Gutschrift ausgelöst wurde) — bei ausgelöster Gutschrift 6 Jahre (steuerrechtlich, §257 HGB)
- Gutschriften (referral_credits): Verknüpfung Empfehlung ↔ Kunden-Workspace ↔ Agentur, Gutschrift-Betrag (unveränderbar, GoBD-konform), Status (Offen/Eingelöst), Einlösedatum, verknüpfte Rechnung. Aufbewahrung: 6 Jahre nach Einlösung (steuerrechtlich, §257 HGB). Gutschriften können wegen GoBD-Compliance nicht gelöscht werden, solange sie buchhalterisch relevant sind
- Benachrichtigungen: Mitglieder des empfehlenden Kunden-Workspace erhalten In-App-Benachrichtigungen bei erfolgreicher Beauftragung (Unternehmensname, Gutschrift-Betrag). Workspace-Admins des Kunden erhalten zusätzlich eine E-Mail über den E-Mail-Dienstleister Resend
- Empfehlungsthemen (Konfiguration): Durch den Agentur-Admin konfigurierbare Themen-Labels (z.B. 'KI-Integration', 'Social Media') — enthalten keine personenbezogenen Daten
Aufgabenbeauftragung im Kundenworkspace
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — verbindliche Beauftragung als Leistungsabruf im Agentur-Kunden-Verhältnis) und Art. 6 Abs. 1 lit. c DSGVO (gesetzliche Verpflichtung) für GoBD-pflichtige Abrechnungsposten
- Beauftragungsdaten (task_orders): Aufgabenvorlagen-Snapshot (Name, Variante, Sprint-Kontingent, Preis), Briefing-Text (Freitext des Kunden), Wunschlieferdatum (optional), Priorität (Normal/Dringend), Status (Eingang/In Bearbeitung/Zur Freigabe/Abgeschlossen/Abgelehnt/Storniert), Zeitstempel (bestellt, genehmigt, storniert). IP-Adresse des Bestellenden wird als SHA-256-Hash gespeichert (pseudonymisiert — keine Rückverfolgung auf Originaladresse möglich). Zweck des IP-Hash: Audit-Trail und Fraud-Prevention. Aufbewahrung des IP-Hash: 90 Tage, danach automatische Nullung via Cleanup-Cron
- PROJ-572 Pricing-Mode (task_orders.pricing_mode): Klassifikator pauschale (Aufgabe ist Teil der laufenden Pauschale, kein separater Beleg) vs. zusatzleistung (Aufgabe wird nach Abschluss separat in Rechnung gestellt). Bei Pauschale-Überschreitung mit carryover_mode='use_it_or_lose_it' wird automatisch ein Sammel-Order mit pricing_mode='zusatzleistung' angelegt (status='approved', auto-genehmigt vom System).
- Abrechnungsposten (billing_items): Nach Kunden-Freigabe einer Beauftragung erstellte, unveränderbare Abrechnungszeilen (GoBD-konform). Enthalten: Beschreibung, Sprint-Kontingent, Sprint-Preis-Snapshot, Netto-/Brutto-Betrag, Steuersatz, Status, Abschlussdatum. Aufbewahrung: 8 Jahre (steuerrechtlich, §147 AO). Löschung technisch blockiert (GoBD-Compliance)
- KI-Briefing-Assistent: Der optionale KI-Assistent zur Briefing-Erstellung übermittelt den Briefing-Chat-Verlauf (Nutzernachrichten + Antworten) und den Vorlagen-Namen an Claude Haiku (Anthropic). Kein Chat-Verlauf wird dauerhaft in der Datenbank gespeichert — die Verarbeitung erfolgt rein in-memory während der aktiven Browser-Session. Als KI-generiert gekennzeichnet (EU AI Act). Token-Verbrauch wird anonymisiert protokolliert (Feature: briefing_assistant, workspace-bezogen)
Aufgaben-Status-Automationen & Kunden-Aktionen
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — agentur-seitig ausgelöste Kunden-Beauftragungen, Freigaben und Ablehnungen als Bestandteil des Leistungsabrufprozesses) und Art. 6 Abs. 1 lit. c DSGVO (gesetzliche Verpflichtung) für GoBD-pflichtige Abrechnungsposten nach Kunden-Freigabe
- Kunden-Aktions-Protokoll (task_customer_actions): Protokolliert jeden agentur-seitig ausgelösten Aktionsvorgang (Kunden-Beauftragung, Freigabe & Abrechnung). Enthält: Automation-Typ, Status (ausstehend/abgeschlossen/abgelehnt/storniert), Auslösezeitpunkt, Abschlusszeitpunkt, handelnder Benutzer (completed_by — User-ID, indirekt personenbezogen), Kundenantwort (response_data JSONB: Bestätigungstext oder Ablehnungsgrund als Freitext, max. 500–1.000 Zeichen). PROJ-1451 (Nachfreigabe-Kreislauf bei nachträglicher Varianten-Wahl): Wenn der Kunde über den login-freien Nachfreigabe-Link (public_token, 30 Tage befristet) antwortet, speichert response_data zusätzlich die IP-Adresse des Antwortenden (personenbezogen — revisionssicherer Nachweis analog Signing-Audit-Trail), den genutzten Kanal (responded_via: Portal vs. Public-Link), den Antwort-Zeitpunkt (responded_at) sowie die Aktion (action: bestätigt/abgelehnt). public_token und token_expires_at selbst sind reine Zugriffs-Token ohne direkten Personenbezug und werden bewusst NICHT im Workspace-Datenexport ausgegeben (analog dem etablierten Muster bei Signing-/Interview-Tokens). Verweis auf entstandenen Abrechnungsposten. Aufbewahrung: bis zur Aufgaben-Löschung (CASCADE DELETE auf task_id). response_data ist nach Abschluss write-once (keine nachträgliche Änderung — Audit-Integrität und GoBD-Konformität bei verbundenen Abrechnungsposten).
- Abrechnungsposten (billing_items, ergänzt): Nach Kunden-Freigabe einer Aufgabe ggf. erstellter Abrechnungsposten (wie PROJ-206) — zusätzlich mit task_id-Referenz. Aufbewahrung: 8 Jahre (steuerrechtlich, §147 AO). Löschung technisch blockiert (GoBD-Compliance).
- Automations-Konfiguration (PROJ-1782, vormals task_status_automations): Welcher Aufgaben-Status welche Kunden-Aktion auslöst, ist seit PROJ-1782 als KI-Mitarbeiter-Playbook (ai_worker_playbooks/ai_worker_playbook_steps) unter „KI-Projektmanagement“ konfiguriert, ausgelöst über den Status-Wechsel-Trigger (PROJ-1781). Enthält nur Workspace-Konfigurationsdaten (Ziel-Status, Automation-Typ, JSONB-Konfiguration) — keine personenbezogenen Daten. Zugriff nur für Workspace-Admins.
Kundenspezifische Aufgabenvorlagen
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Zuweisung von Aufgabenvorlagen an Kontakte/Kunden als Bestandteil der Kunden-Katalog-Konfiguration)
- Kunden-Zuweisungen (task_template_contact_assignments): Zuordnung einer Aufgabenvorlage zu einem Kontakt/Kunden. Enthält: Vorlage (task_template_id), Kontakt (contact_id), optionaler individueller Netto-Preis (custom_price_net), erstellender Benutzer (created_by — User-ID, indirekt personenbezogen). Aufbewahrung: bis zur Löschung der Vorlage oder des Kontakts (CASCADE DELETE). Zugriff: SELECT für alle Workspace-Mitglieder, Schreiboperationen nur für Admins/Manager.
Karriere-Portal & Bewerbungsmanagement
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung/Vertragserfüllung) für Bewerbungsdaten; Art. 9 Abs. 2 lit. b DSGVO (Beschäftigungskontext) sofern besondere Kategorien in Freitextfeldern oder Lebensläufen enthalten sind
- Bewerbername, E-Mail-Adresse, Telefonnummer (optional): Zur Identifikation und Kontaktaufnahme im Bewerbungsprozess
- Anschreiben (Freitext, optional): Zur Bewerbungsprüfung. Kann potenziell besondere Kategorien personenbezogener Daten enthalten (Art. 9 DSGVO)
- Lebenslauf und ergänzende Dokumente (PDF/DOCX, max. 5 MB pro Datei): Gespeichert in einem privaten Supabase-Storage-Bucket. Zugriff nur über zeitbegrenzte signierte URLs (1 Stunde Gültigkeit) für berechtigte HR-Mitarbeiter (Admin/Manager)
- Interne HR-Notizen: Nur für Workspace-Admins und -Manager sichtbar. Können potenziell besondere Kategorien enthalten
- E-Mail-Kommunikation mit Bewerbern: Betreff und Nachrichtentext werden in der Anwendung gespeichert und über den E-Mail-Dienstleister Resend zugestellt
- Bewerbungsstatus (Eingegangen, In Prüfung, Interview, Angebot, Abgelehnt): Zur Verwaltung des Bewerbungsprozesses
- Aufbewahrungsfrist: Standardmäßig 180 Tage nach Bewerbungseingang, konfigurierbar durch den Workspace-Administrator. Nach Ablauf der Frist erhalten Workspace-Administratoren eine automatische Erinnerung zur manuellen Prüfung und Löschung
- Löschung: Bewerbungsdaten, Dokumente und die gesamte Kommunikationshistorie können jederzeit durch den Workspace-Administrator vollständig gelöscht werden (einschließlich aller Dateien im Storage)
- Bestätigungs-E-Mail: Nach Bewerbungseingang wird der Name und die E-Mail-Adresse des Bewerbers an den E-Mail-Dienstleister (Resend) zur Zustellung einer Eingangsbestätigung übermittelt
- Einwilligung: Bewerber müssen vor dem Absenden der Bewerbung aktiv in die Datenverarbeitung einwilligen (Pflicht-Checkbox)
- Cross-Workspace-Aggregation: Bei bestehender Workspace-Verbindung zwischen Agentur und Kunden-Workspace können berechtigte Mitarbeiter der verbundenen Agentur aggregierte Bewerbungsdaten (Name, E-Mail-Adresse, Status, Bewerbungsdatum) in einer zentralen Übersicht einsehen. Die Daten verbleiben im Quell-Workspace und werden nicht kopiert. Durch Trennung der Workspace-Verbindung wird der Zugriff sofort entzogen.
Team-Chat & Messaging
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
- Chat-Nachrichten: Textinhalt (max. 5.000 Zeichen), Absender-ID, Zeitstempel, Raum-Zuordnung. Aufbewahrung: Bis zur Workspace-Löschung (CASCADE). Gelöschte Nachrichten werden als Soft-Delete markiert — Originaltext und Datei-Informationen werden aus der Datenbank entfernt, Metadaten (Zeitstempel, Absender) bleiben erhalten
- Chat-Räume: Raumname (bei Gruppenräumen), Typ (Direkt/Gruppe), Ersteller-ID, Archivierungsstatus, Workspace-Zuordnung. Löschung bei Workspace-Löschung (CASCADE)
- Raum-Mitgliedschaft: Nutzer-ID, Workspace-ID des Mitglieds, Zeitstempel des Beitritts und des letzten Lesezeitpunkts (für Ungelesen-Zähler). Löschung bei Raum-Löschung (CASCADE) oder manuellem Entfernen durch Raum-Ersteller/Admin
- Datei-Anhänge: Bilder, PDFs, Office-Dokumente und ZIP-Dateien (max. 25 MB pro Datei) werden in einem Supabase-Storage-Bucket gespeichert (Ordnerstruktur: raum_id/zeitstempel-zufall.endung). Dateipfade sind nicht vorhersagbar (UUID-basiert). Zugriffskontrolle erfolgt auf API-Ebene (nur Raum-Mitglieder können Nachrichten mit Datei-URLs empfangen). Löschung bei Workspace-Löschung oder beim Löschen der zugehörigen Nachricht
- Emoji-Reaktionen: Nutzer-ID, Emoji-Bezeichnung, Nachrichtenreferenz. Nur eigene Reaktionen können entfernt werden. Löschung bei Nachrichten-Löschung (CASCADE)
- Cross-Workspace-Chat: Bei bestehender Workspace-Verbindung (workspace_connections) können Nutzer aus verbundenen Workspaces in gemeinsamen Räumen kommunizieren. Bei Trennung der Verbindung werden Cross-Workspace-Räume archiviert (readonly). Bestehende Nachrichten bleiben lesbar, neue Nachrichten können nicht gesendet werden
- @Mentions in Gruppenchats: Erzeugen Inbox-Benachrichtigungen (Absendername, Nachrichtenvorschau) sowie — wenn die Companion App installiert ist — native macOS Push-Benachrichtigungen via Apple APNs (Absendername + max. 100 Zeichen Vorschau). Neue Direktnachrichten erzeugen ebenfalls beide Benachrichtigungsarten. Benachrichtigungen enthalten den Absendernamen und einen Textauszug (max. 200 Zeichen in-App / max. 100 Zeichen via APNs)
- Lesebestätigungen: Der letzte Lesezeitpunkt (last_read_at) wird anderen Raum-Mitgliedern als Lese-Avatar unter der letzten gelesenen Nachricht angezeigt. Die Anzeige kann in den Profileinstellungen deaktiviert werden (symmetrisches Opt-out: wer deaktiviert, sendet keine Lesebestätigungen und sieht auch keine). Die zugrunde liegenden Daten (last_read_at) werden unabhängig vom Toggle für die Berechnung der Ungelesen-Zähler gespeichert
- Typing-Indikator: Wird über Supabase Realtime Presence ephemerisch übermittelt (Nutzername, Nutzer-ID). Keine dauerhafte Speicherung in der Datenbank
- Native macOS Companion App (PROJ-549): Chat-Nachrichten sind zusätzlich zum Web-Chat über die NEULAND. OS Companion App (macOS) lesbar und sendbar. Die App ruft die Daten über dedizierte Companion-Endpunkte (/api/companion/chat/*) ab — Bearer-Token-Authentifizierung über den Supabase-JWT des angemeldeten Nutzers, identische RLS-/Workspace-Scoping-Semantik wie im Web. Auf dem Gerät werden Nachrichten ausschließlich im Arbeitsspeicher der App gehalten (keine lokale Datenbank, keine Datei-Persistenz für Chat-Inhalte). Live-Updates erfolgen für Standard-Räume über Supabase Realtime (Postgres-Changes auf chat_messages), für Gast-Chats über kurzes Polling (5 Sekunden) der Companion-API. Beim Klick auf eine native macOS-Push-Benachrichtigung öffnet sich das native Chat-Fenster und selektiert den entsprechenden Raum (statt wie zuvor den Browser zu öffnen). Es entsteht kein neuer Auftragsverarbeiter — die Verarbeitung erfolgt weiterhin in NEULAND. OS (Supabase + Vercel)
Telefonie & VoIP (Browser & macOS Companion App)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter Kundenkommunikation). Für Gesprächsaufzeichnung: Art. 6 Abs. 1 lit. a DSGVO (Einwilligung) in Verbindung mit §201 StGB (Verletzung der Vertraulichkeit des Wortes) — Aufzeichnung nur nach IVR-Einwilligungsansage
- Anrufprotokolle (call_logs): Rufnummer des Anrufers und des Angerufenen (E.164-Format), Anrufrichtung (eingehend/ausgehend), Status (beantwortet/verpasst), Anrufbeginn und -ende, Dauer in Sekunden, Telnyx-Session-ID (technische Zuordnung). Aufbewahrung: 12 Monate, danach automatische Löschung durch Bereinigungsprozess
- PROJ-732 Interne Notiz pro Anruf (call_logs.internal_note): Freitext bis 2.000 Zeichen, vom Agentur-Team manuell eingegeben (Beispiele: Verkaufschance Kunde will Angebot; Falsche Nummer). Sichtbar nur für Workspace-Mitglieder mit Lesezugriff auf das Call-Log. KEIN externes Sharing, KEINE Übermittlung an Drittanbieter. Wird nur per Plaintext gerendert (HTML-Escape). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Vertriebsdokumentation). Aufbewahrung: gemeinsam mit dem zugehörigen Anrufprotokoll (12 Monate via Standard-Cleanup-Cron). Löschung bei Call-Log-Löschung und Workspace-Löschung (CASCADE).
- PROJ-732 Manuelle Kontakt-Zuordnung pro Anruf (call_logs.contact_id_source): Markiert, ob die Kontakt-Zuordnung eines Anrufs automatisch (auto_phone_match — Standard), manuell durch einen Mitarbeiter (manual — gesetzt beim Edit der Stammdaten via PATCH /api/telephony/call-logs/:id) oder über Telnyx-Caller-Metadata (telnyx_caller_metadata) erfolgte. Dient als Sperr-Flag für künftige Auto-Match-Crons — manuelle Zuordnungen werden niemals überschrieben (PROJ-732 EC-10). Keine direkte personenbezogene Information, sondern technisches Audit-Markierungsfeld. Aufbewahrung: gemeinsam mit dem Call-Log.
- PROJ-732 Stammdaten-Korrekturen an Call-Logs werden zusätzlich im Audit-Trail Gesprächs-Stammdaten-Edits (siehe eigenen DATA_PROCESSING-Eintrag) festgehalten — alt/neu-Werte, Editierender, Zeitpunkt.
- Rufnummern-Zuweisungen: Telefonnummer (E.164-Format), Anzeigename, Zuordnung zu Mitarbeiter. Aufbewahrung: Solange die Zuweisung aktiv ist. Bei Deaktivierung bleibt der Eintrag mit is_active=false erhalten
- Telnyx-Konfiguration: API-Schlüssel wird mit AES-256-GCM verschlüsselt gespeichert (eigener Schlüssel TELEPHONY_ENCRYPTION_KEY). Nur Workspace-Administratoren können die Konfiguration verwalten. Der API-Schlüssel wird nie im Klartext angezeigt oder in API-Antworten zurückgegeben
- WebRTC-Token: Kurzlebiger Authentifizierungs-Token für die Browser-Telefonie (Gültigkeit: 15 Minuten). Wird nicht in der Datenbank gespeichert, sondern nur im Browser-Speicher während der aktiven Sitzung
- Automatische Anrufdokumentation: Bei beendeten Anrufen wird automatisch eine Notiz am zugehörigen CRM-Kontakt erstellt (Anrufrichtung und Dauer, keine Rufnummern im Notiztext). Zusätzlich werden Aktivitäts-Log-Einträge erstellt
- Verpasste-Anruf-Benachrichtigungen: Bei verpassten oder abgelehnten Anrufen wird eine Inbox-Benachrichtigung an den zugewiesenen Mitarbeiter erstellt. Die Benachrichtigung enthält eine teilmaskierte Rufnummer
- Caller-ID-Matching: Eingehende Rufnummern werden automatisch mit CRM-Kontakten abgeglichen (phone_company, phone_mobile). Es werden keine zusätzlichen Daten an Dritte übermittelt
- Telnyx-Webhooks: Anruf-Events (Anruf gestartet, beantwortet, beendet, abgelehnt, Aufnahme gespeichert) werden von Telnyx an einen signierten Webhook-Endpunkt gesendet (Ed25519-Signaturvalidierung + Replay-Schutz). Rufnummern in Server-Logs werden maskiert (erste 4 Zeichen + ***)
- macOS-Companion-App-Telefonie (PROJ-552): Die native macOS-App enthält eine versteckte WKWebView, die das Telnyx WebRTC JS-SDK (von cdn.jsdelivr.net) lädt und dieselbe SIP-Registrierung nutzt wie der Browser-Telefonie-Stack (gleicher Token-Mechanismus, gleiches Workspace-Telephony-Setup). Audio-Streams laufen durch den macOS-WebRTC-Stack (Mikrofon-Berechtigung wird vom Betriebssystem abgefragt, NSMicrophoneUsageDescription in Info.plist). Es werden keine Anruf-Daten lokal in der App persistiert — alle Anrufprotokolle werden weiterhin nur in call_logs auf dem Server gespeichert. Die App kommuniziert über drei neue Companion-API-Endpunkte: /api/companion/telephony/token (Bearer-JWT-Variante des bestehenden Token-Endpoints), /api/companion/telephony/contact-lookup (Rufnummer→Kontakt-Match auf bestehende contacts-Tabelle, kein neuer Daten-Storage) und /api/companion/telephony/call-answered (sendet einen Realtime-Broadcast telephony-call:<workspaceId> mit telnyx_call_id + answered_by_user_id, damit andere Geräte des Mitarbeiters das Klingeln stoppen). Die Embed-HTML-Seite /api/companion/embed/telephony enthält keine Auth-Logik und ist via CSP frame-ancestors none gegen Browser-Embedding gesperrt — der Token wird ausschließlich vom nativen Swift-Host via WKScriptMessageHandler-Bridge injectet.
- Multi-Device-Anrufannahme: Wenn ein Mitarbeiter Browser und macOS-App parallel angemeldet hat, klingeln beide bei eingehenden Anrufen. Der erste annehmende Endpoint löst (a) eine Realtime-Broadcast-Nachricht über Supabase Realtime aus, die alle anderen Endpoints des selben Workspace dazu bringt das Klingeln zu stoppen, und (b) Telnyx beendet die SIP-Sessions der nicht-annehmenden Endpoints serverseitig (First-Answer-Wins). Der Broadcast-Payload enthält nur die Telnyx-Call-ID und die User-ID des annehmenden Geräts — keine PII des Anrufers.
- Gesprächsaufzeichnung (Call Recording): Audiodateien (MP3) werden nach Anrufende von Telnyx heruntergeladen und in einem privaten Supabase-Storage-Bucket gespeichert (Pfad: workspace_id/call_log_id.mp3). Zugriff nur über zeitbegrenzte signierte URLs (24 Stunden Gültigkeit) für Workspace-Mitglieder. Aufbewahrungsdauer der Audiodateien: konfigurierbar durch Workspace-Admin (14, 30, 60 oder 90 Tage, Standard: 30 Tage). Nach Ablauf der Aufbewahrungsfrist werden Audiodateien automatisch durch einen täglichen Bereinigungsprozess gelöscht. Voraussetzung: Aufzeichnung muss durch den Workspace-Admin aktiviert werden (standardmäßig deaktiviert)
- DSGVO-Einwilligungsbestätigung (§201 StGB): Vor dem Start einer Gesprächsaufzeichnung muss der Mitarbeiter in einem Pflicht-Bestätigungsdialog bestätigen, dass der Gesprächspartner über die Aufzeichnung informiert wurde und zugestimmt hat (All-Party-Consent gemäß §201 StGB). Ohne diese Bestätigung kann die Aufnahme technisch nicht gestartet werden. Der Workspace-Administrator kann ergänzend einen IVR-Ansagetext konfigurieren (max. 500 Zeichen)
- Automatische Transkription (KI-generiert): Nach Aufnahmeende wird die Audiodatei automatisch an OpenAI (Whisper-1) zur Transkription übermittelt. Die Audiodaten werden nur transient verarbeitet (nicht dauerhaft bei OpenAI gespeichert — gemäß OpenAI API Data Usage Policy bis zu 30 Tage für Sicherheitszwecke). Das Transkript wird in der Datenbank gespeichert (Feld: call_logs.transcript) und bei Ablauf der Aufbewahrungsfrist zusammen mit der Audiodatei automatisch gelöscht. Transkripte werden als KI-generierte Inhalte gekennzeichnet. Das Transkript wird zusätzlich als Notiz am CRM-Kontakt hinterlegt. Kosten werden über das KI-Token-Tracking erfasst
- Aufnahme-Einstellungen (call_recording_settings): Workspace-spezifische Konfiguration — Aktivierung (boolean), Aufbewahrungsdauer (14/30/60/90 Tage), IVR-Ansagetext (max. 500 Zeichen). Nur Workspace-Admins können die Einstellungen ändern
- Löschung: Bei Workspace-Löschung werden alle Telefonie-Daten inklusive Aufnahmen automatisch gelöscht (CASCADE). Bei Kontakt-Löschung werden Rufnummern in zugehörigen Anrufprotokollen anonymisiert, Transkripte gelöscht und Audiodateien aus dem Storage entfernt (DSGVO Art. 17). Einzelne Anrufprotokolle können durch Workspace-Administratoren gelöscht werden — dabei wird die zugehörige Audiodatei automatisch aus dem Storage mitgelöscht
KI-Telefonassistent (PROJ-121)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an erreichbarem Kundenservice). EU AI Act Art. 50 (Kennzeichnungspflicht für KI-Systeme mit Nutzer-Interaktion) — Pflicht-Ansage bei jedem Anrufbeginn
- Pflicht-KI-Kennzeichnung (EU AI Act): Jeder Anruf, der vom KI-Telefonassistenten entgegengenommen wird, beginnt mit einer nicht überspringbaren Ansage: »Sie sprechen jetzt mit einem KI-Assistenten der Agentur [Name]. Falls Sie lieber mit einem Mitarbeiter sprechen möchten, sagen Sie bitte »Mitarbeiter« oder bleiben Sie in der Leitung.« Diese Ansage ist fest im System verankert und kann vom Workspace-Admin nicht deaktiviert werden
- Gesprächs-Transkript: Das vollständige Gesprächstranskript wird von Retell AI generiert und nach Gesprächsende über einen gesicherten Webhook an NEULAND. OS übertragen. Gespeichert in call_logs.transcript. Aufbewahrung: 12 Monate (gemeinsam mit Anrufprotokollen)
- KI-Zusammenfassung (Claude Haiku): Nach Gesprächsende wird das Transkript von Claude Haiku (Anthropic) verarbeitet und eine 3–5-Satz-Zusammenfassung generiert. Gespeichert in call_logs.ai_summary. Gekennzeichnet als KI-generierter Inhalt (EU AI Act). Aufbewahrung: gemeinsam mit Anrufprotokoll
- Function-Call-Protokoll: Alle Aktionen, die der KI-Assistent während des Gesprächs ausgelöst hat (CRM-Lookup, Kontakt-Erstellung, Rückruf-Aufgabe, Warm-Transfer-Anforderung) werden in call_logs.ai_function_calls gespeichert (JSONB-Array). Enthält Funktionsname, Parameter und Ergebnis
- Warm-Transfer-Ziele (ai_phone_transfer_targets): Workspace-Admins können Mitarbeiter als Transfer-Ziel konfigurieren (Profil-Referenz, Anzeigename, Durchwahl, Priorität). Keine Übermittlung an Dritte
- KI-Assistent-Konfiguration: System-Prompt (Name, Persona, FAQ-Inhalte, Eskalations-Keywords), Aktivierungsmodus, Geschäftszeiten und Stimmenkonfiguration werden im JSONB-Feld workspace_telephony_configs.ai_agent_config gespeichert. Retell AI API-Key und ElevenLabs API-Key werden AES-256-GCM-verschlüsselt gespeichert (gleicher TELEPHONY_ENCRYPTION_KEY wie Telnyx-Key). Nur Workspace-Admins haben Zugriff
- Drittanbieter — Retell AI (Vereinigte Staaten): Echtzeit-Sprachverarbeitung (STT → LLM → TTS + Turn-Taking) für die Dauer des Gesprächs. Retell AI verarbeitet Sprache und Gesprächsinhalt. Zertifizierungen: SOC 2 Typ II, HIPAA-eligible, GDPR DPA verfügbar. Datenspeicherung: Retell AI speichert Transkripte und Anruf-Metadaten gemäß ihrer Datenschutzrichtlinie. Für die Datenverarbeitung ist ein Datenverarbeitungsvertrag (DPA) mit Retell AI erforderlich
- Drittanbieter — ElevenLabs (Vereinigte Staaten): Text-to-Speech-Verarbeitung für die Sprachausgabe des Assistenten. ElevenLabs verarbeitet den zu sprechenden Text transient für die Sprachsynthese. Konfiguration erfolgt über Retell AI (kein direkter API-Aufruf von NEULAND. OS). Datenschutzrichtlinie von ElevenLabs gilt für die transiente Verarbeitung
- KI-Token-Tracking: Nutzung von Claude Haiku für Post-Call-Zusammenfassungen wird in ai_token_logs erfasst (Workspace-ID, Modell, Token-Anzahl, geschätzte Kosten, Feature: phone_assistant). Keine Speicherung von Gesprächsinhalten im Token-Log
- Löschung: Bei DSGVO-Löschanfrage werden Transkript und KI-Zusammenfassung in call_logs anonymisiert (Felder auf NULL gesetzt). Function-Call-Protokoll wird ebenfalls geleert. Bei Workspace-Löschung: CASCADE-Löschung aller KI-Telefonassistent-Daten. Retell AI und ElevenLabs haben eigene Löschprozesse gemäß ihrer Datenschutzrichtlinien
Video-Meetings (Daily.co — Browser & macOS Companion App)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) für Meeting-Verwaltung und -Teilnahme; Art. 6 Abs. 1 lit. a DSGVO (Einwilligung) für Aufzeichnung und KI-Transkription
- Meeting-Metadaten: Titel, Gastgeber (Profil-Referenz), optionale Kontakt-Zuordnung, Status, geplanter Zeitpunkt, Start-/Endzeit, Dauer. Aufbewahrung: bis Meeting-Löschung oder Workspace-Löschung (CASCADE). Bei Kontakt-Löschung: contact_id wird auf NULL gesetzt (SET NULL)
- Teilnehmer-Daten (meeting_participants): Interne Teilnehmer über Profil-Referenz (SET NULL bei Profil-Löschung), externe Gäste über Anzeigename (external_name, Freitext — der vom Gast in der Beitritts-Lobby eingegebene Name), bei Einladung per E-Mail zusätzlich die Gast-E-Mail-Adresse (external_email — aus meeting_invitations.recipient_email übernommen, von Daily.co via Webhook user_data gespiegelt; bleibt NULL bei reinen Link-Beitritten ohne Empfänger-E-Mail), Daily.co-Session-ID (technisch), Beitritts-/Verlassenszeit. CASCADE-Löschung bei Meeting-Löschung
- Einladungen (meeting_invitations): Empfänger-E-Mail (normalisiert), Name, UUID-Token für öffentlichen Beitrittslink, Ablaufzeit, Status. CASCADE-Löschung bei Meeting-Löschung. E-Mail-Versand über Resend
- Chat-Nachrichten (meeting_chat_messages): Während eines Video-Meetings über das Chat-Panel ausgetauschte Textnachrichten werden nach Meeting-Ende dauerhaft in der Datenbank gespeichert. Gespeicherte Daten: Absendername (Freitext — auch für externe Gäste ohne Account), optionale Profil-Referenz für interne Nutzer (SET NULL bei Profil-Löschung), Nachrichteninhalt (max. 2.000 Zeichen), Sendezeitpunkt. Der Live-Chat während des Meetings läuft über Daily.co sendAppMessage (P2P, ephemer — keine Speicherung bei Daily.co). Persistierung erfolgt ausschließlich durch den Meeting-Host nach Verlassen des Meetings. Chat-Nachrichten sind im Kommunikations-Tab des zugehörigen Projekts/Kontakts einsehbar. Aufbewahrung: bis zur Meeting-Löschung oder Workspace-Löschung (CASCADE). Im Kontakt-Datenexport (Art. 15/20) enthalten
- Video-Konferenz (Daily.co): Audio/Video-Streams werden nur während des Meetings verarbeitet (ephemer). Anzeigename des Teilnehmers und Raum-Konfiguration (UUID, Ablaufzeit, Warteraum) werden an Daily.co übermittelt. Daily.co DPA erforderlich
- Aufzeichnung (optional): MP4-Datei wird nach Meeting-Ende von Daily.co heruntergeladen und in Supabase Storage (privater Bucket meeting-recordings) gespeichert. Zugriff nur via signierte URLs (1 Stunde TTL). Aufbewahrung: workspace-konfigurierbar (Standard 30 Tage). Aufzeichnungen werden gemäß recording_expires_at-Zeitstempel als ablaufend markiert; die automatische Löschung erfolgt über einen täglichen Cleanup-Cron (03:00 UTC, PROJ-122, cleanup-meeting-recordings). Teilnehmer-Einwilligung wird in recording_consent_log (JSONB) pro Participant-ID gespeichert; recording_consent_requested_at dokumentiert den Zeitpunkt der Einwilligungsanfrage. Bei manueller Meeting-Löschung wird die Storage-Datei ebenfalls entfernt
- Transkription mit Sprecher-Erkennung (KI-generiert, Deepgram Nova-3): Die Meeting-Aufzeichnung wird zur automatischen Transkription mit Sprecher-Diarization an Deepgram (Nova-3 Modell) übermittelt. Das Ergebnis enthält strukturierte Segmente mit Sprecher-Zuordnung (basierend auf Beitrittsreihenfolge der Teilnehmer), Zeitstempeln und transkribiertem Text. Aufbewahrung: parallel zur Aufzeichnung (wird zusammen gelöscht). Deepgram verarbeitet Audio-Daten nur transient (API-Aufruf, keine dauerhafte Speicherung durch Deepgram)
- KI-Zusammenfassung (KI-generiert, Claude Haiku): Das Transkript wird anonymisiert (sanitizePii) und mit Sprecher-Zuordnung an Anthropic Claude übermittelt. Die 5-8 Satz-Zusammenfassung wird in der Datenbank gespeichert und ordnet Action Items den jeweiligen Sprechern zu. Gekennzeichnet als KI-generierter Inhalt (EU AI Act Art. 50). Aufbewahrung: unbegrenzt (enthält keine personenbezogenen Daten)
- KI-Token-Tracking: Nutzung von Claude Haiku für Meeting-Zusammenfassungen (Feature: meeting_summary) und Deepgram Nova-3 für Meeting-Transkriptionen (Feature: meeting_transcription) wird in ai_token_logs erfasst (Workspace-ID, Modell, Dauer in Sekunden bzw. Token-Anzahl, geschätzte Kosten). Keine Speicherung von Gesprächsinhalten im Token-Log
- macOS-Companion-App-Teilnahme (PROJ-553): Die native macOS-App enthält eine sichtbare WKWebView, die das @daily-co/daily-js-SDK (von cdn.jsdelivr.net) lädt und Daily-Tiles direkt darin rendert. Token-Mint läuft über drei neue Companion-Endpoints: /api/companion/meetings/token (Bearer-JWT-Variante des Web-Endpoints — mintet einen Daily-Meeting-Token mit isOwner=host===user.id), /api/companion/meetings/list (Liste aktiver Meetings als Host oder Eingeladener — Workspace-RLS-scoped) und /api/companion/meetings/notify-invite (Workspace-Mitglieder via APNs-Push einladen — Best-Effort, Nicht-Mitglieder werden silent skipped). Die Embed-HTML-Seite /api/companion/embed/meetings hat keine Server-Auth (CSP frame-ancestors 'none' sperrt Browser-Embedding) — der Token wird vom Swift-Host via WKScriptMessageHandler-Bridge injectet (Namespace window.__nlMeetingBridge mit Methoden init/disconnect/setCameraEnabled/setMicEnabled/leave). Camera- und Mikrofon-Zugriff werden vom macOS-Betriebssystem abgefragt (Info.plist NSCameraUsageDescription + NSMicrophoneUsageDescription). Es werden KEINE Meeting-Daten lokal in der App persistiert — alle Aufzeichnungen, Transkripte und KI-Zusammenfassungen werden weiterhin nur server-seitig in der NEULAND-OS-DB gespeichert.
- Meeting-Invite-Push (PROJ-553): Bei einem Meeting-Invite via Companion-API wird ein APNs-Push an die macOS-Companion-Devices der eingeladenen Workspace-Mitglieder gesendet. Push-Payload enthält: title ("<Host-Name> hat dich zu einem Meeting eingeladen"), body (Meeting-Titel oder "Meeting beitreten"), customData (kind=meeting.invite, meeting_id, host_name, room_title, workspace_id), category=meeting.invite (UNNotificationCategory mit Beitreten-/Ablehnen-Action). Übertragung über Apple-Server (USA, SCCs/DPF). Rechtsgrundlage: Art. 6 Abs. 1 lit. b und f DSGVO (Vertragserfüllung Video-Meetings + berechtigtes Interesse an Echtzeit-Benachrichtigung). Nicht-Mitglieder des Workspaces werden silent skipped (kein Push an Externe).
- Löschung: Bei Meeting-Löschung werden Teilnehmer, Einladungen, Chat-Nachrichten, Aufzeichnung (Storage) und DB-Eintrag gelöscht (CASCADE + Storage-Cleanup). Bei Workspace-Löschung: CASCADE-Löschung aller Meeting-Daten. Bei Kontakt-Löschung: contact_id auf NULL (SET NULL). Bei Profil-Löschung: user_id in meeting_participants und sender_user_id in meeting_chat_messages auf NULL (SET NULL)
- PROJ-732 Stammdaten-Korrekturen an Meetings (title, scheduled_at, contact_id, project_id, waiting_room_enabled) werden zusätzlich im Audit-Trail Gesprächs-Stammdaten-Edits (siehe eigenen DATA_PROCESSING-Eintrag) festgehalten — alt/neu-Werte, Editierender, Zeitpunkt. Änderung der geplanten Startzeit ist nach Meeting-Start blockiert (AC-M3). Bei Kontakt-Wechsel wird parallel ein Activity-Log-Eintrag am alten und neuen CRM-Kontakt erzeugt.
Kontextbezogener KI-Chat (Hilfe-Icon)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter Nutzerhilfe)
- Chat-Nachrichten (Nutzerfragen): Werden an Claude (Anthropic) zur Beantwortung übermittelt. Ephemer — keine Speicherung in der Datenbank, nur im Browser-Speicher während der aktiven Sitzung
- Seitenkontext (routeKey): Wird serverseitig gegen eine Whitelist validiert und als Kontext an den KI-Dienst übermittelt. Keine personenbezogenen Daten
- Doku-Verbesserungsvorschläge: Nutzer können optional einen Freitext-Vorschlag (max. 500 Zeichen) einreichen. Gespeichert werden: Workspace-ID, Nutzer-ID, Seiten-Identifikator, Fragetext und Vorschlagstext. Aufbewahrung: Bis der Plattform-Admin den Vorschlag als erledigt markiert. Löschung bei Workspace-Löschung (CASCADE)
- Token-Nutzungsprotokoll: Modell, Feature-Typ (contextual_help), Prompt- und Completion-Tokens, geschätzte Kosten. Aufbewahrung: bis Workspace-Löschung
Support & Feedback
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
- Support-Ticket-Inhalte
- Feedback-Texte, Screenshots und Datei-Anhänge (Aufbewahrung: 12 Monate, dann automatische Löschung). Screenshots werden über die Browser Screen Capture API (getDisplayMedia) aufgenommen und können sichtbare Bildschirminhalte einschließlich potenziell personenbezogener Daten enthalten. Der Nutzer kann den Screenshot vor dem Absenden zuschneiden (Drag-to-Select). Pro Meldung sind bis zu 3 Screenshots möglich (PROJ-1436) — der erste wird in feedback_submissions.screenshot_path gespeichert, weitere in der Zuordnungstabelle feedback_submission_screenshots (nur Speicherpfade, gleicher Storage-Bucket, gleiche 12-Monats-Löschung inkl. Storage-Objekte durch den Cleanup-Cron; Löschung der Meldung entfernt die Zuordnungen automatisch mit). Zusätzlich können Dateien (Bilder: JPEG/PNG/GIF/WebP/SVG, Videos: WebM/MP4, PDF, ZIP, Office-Dokumente: Word/Excel/PowerPoint, Text- und CSV-Dateien; max. 50 MB) vom Computer hochgeladen werden — diese können ebenfalls personenbezogene Daten enthalten. Anhänge und Screenshots sind ausschließlich für Plattform-Admins einsehbar. Feedback-Typ (Bug/Feature), Beschreibung (Vorschau, max. 100 Zeichen) und Bearbeitungsstatus sind für alle Mitglieder desselben Workspaces im Feedback-Hub sichtbar (PROJ-315 — Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO, Vertragserfüllung durch transparente Team-Kommunikation)
- Nutzer-Zuordnung (Einreicher-Name im Workspace-Hub sichtbar)
- PROJ-663 Status-Historie (entwicklung_status_history): Pro manuellem oder automatischem Status-Wechsel eines Feedback-Eintrags oder Feature-Wunsches wird ein Audit-Eintrag gespeichert. Felder: entity_type (feedback_submission/feature_request_submission), entity_id, workspace_id, from_status, to_status, changed_by_user_id (UUID des Workspace-Mitglieds — NULL bei System-Trigger), changed_by_system_label (z. B. deploy-hook, nw-complete), optionale Notiz (max. 280 Zeichen Freitext), Zeitstempel. Sichtbarkeit: alle aktiven Mitglieder des Workspaces (admin/manager/member). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Nachvollziehbarkeit von Workflow-Entscheidungen im Team). Bei User-Löschung: changed_by_user_id wird auf NULL gesetzt (ON DELETE SET NULL), der Audit-Eintrag bleibt mit anonymisierter Aktor-Referenz erhalten. Datenexport (Art. 15/20): entwicklung_status_history ist im Workspace-Datenexport enthalten. CASCADE-Löschung bei Workspace-Löschung; polymorpher Cleanup-Trigger entfernt zugehörige Audit-Einträge bei Löschung eines Feedback-Eintrags oder Feature-Wunsches
Feature-Verifikation & Release-Testing (PROJ-879)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Qualitätssicherung durch strukturierten Verifikations-Workflow für deployete Features)
- Verifikations-Anfragen (verification_requests): Pro eingereichter Prüfbitte werden gespeichert: Feature-Name (Freitext, max. 200 Zeichen), optionale PROJ-ID-Referenz (max. 20 Zeichen), optionale Symptom-Beschreibung (max. 2.000 Zeichen), Priorität (normal/urgent), Status (open/running/completed/failed), Zeitstempel, Workspace-Zuordnung und User-ID des Einreichers. Sichtbar für alle aktiven Mitglieder des Workspaces
- Datenexport (Art. 15/20 DSGVO): verification_requests sind im Workspace-Datenexport enthalten
Uptime-Monitoring & PageSpeed-Analyse
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Überwachung der Verfügbarkeit und Performance von Kunden-Websites im Auftrag der Agentur)
- Monitor-URLs (öffentlich erreichbare Website-URLs der Kunden)
- Antwortzeiten und HTTP-Statuscodes (Uptime-Checks)
- PageSpeed-Scores (Performance, Accessibility, Best Practices, SEO) für Mobile und Desktop — abgerufen über die Google PageSpeed Insights API. Es werden ausschließlich numerische Scores und Zeitstempel gespeichert, keine personenbezogenen Daten. Aufbewahrung: 90 Tage (automatische Bereinigung via pg_cron). Drittlandtransfer: Website-URL wird an Google LLC (USA) übermittelt (SCCs / Data Privacy Framework) — kein Personenbezug
- Alert-Benachrichtigungen an Workspace-Admins bei Schwellenwertunterschreitung
- PROJ-945 Conversion-Page-Monitoring (monitor_conversion_pages + monitor_conversion_page_checks): Pro Monitor erfasste Conversion-Seiten (Kontaktformular, Terminbuchung, Angebotsanfrage etc.) mit URL bzw. URL-Muster, Conversion-Typ und HTTP-Check-Verlauf (Statuscode, Antwortzeit, Zeitstempel — keine personenbezogenen Daten). Test-Requests tragen den User-Agent NeulandOS-Monitor/1.0 und werden vom eigenen Tracking ausgeschlossen. Aufbewahrung der Check-Logs: 30 Tage (automatische Bereinigung). Workspace-scoped, CASCADE-DELETE bei Monitor-/Workspace-Löschung. RLS: nur Agentur-Admin/Manager.
- PROJ-945 Formular-Funktionstest (monitor_form_test_results + workspace_monitor_test_mailbox): Optionaler taeglicher Test des Formular-Versands. Voraussetzung ist das Contao-Bundle (neuland/monitoring-bundle) mit konfiguriertem Shared Secret. Ohne Bundle wird kein Form-Submit durchgefuehrt (DSGVO-Schutz: verhindert unerwuenschte Kunden-Benachrichtigungen). Das System sendet ein synthetisches Testformular ab (Test-Payload mit klar als Monitortest markierten Werten, Test-E-Mail-Adresse der agentureigenen Test-Mailbox, kein echter Kundenbezug). Das Contao-Bundle ueberschreibt den NC-Empfaenger auf die Test-Mailbox-Adresse. Die Test-E-Mail wird nach der Pruefung sofort geloescht. Gespeichert werden nur Test-Ergebnis, HTTP-Status und ggf. eine Fehlermeldung (PII-frei, kein Payload-Klartext). IMAP-Zugangsdaten und Contao-Shared-Secret werden AES-256-GCM-verschluesselt gespeichert und nicht im Datenexport ausgegeben. Aufbewahrung der Test-Ergebnisse: 30 Tage. RLS: Test-Mailbox-Config nur Agentur-Admin.
- PROJ-945 Telefon/E-Mail-Content-Validierung (monitor_content_check_results): Bei Conversion-Pages vom Typ Telefonnummer/E-Mail-Adresse wird taeglich die oeffentliche Seite gecrawlt und geprueft, ob die dort angezeigten Telefonnummern/E-Mail-Adressen mit den im CRM hinterlegten Kontaktdaten des Kunden (contacts: email, phone_company, phone_mobile, additional_emails) uebereinstimmen. Zweck: Erkennung veralteter/falscher Kontaktangaben auf Kundenseiten. Es werden ausschliesslich oeffentlich auf der Kundenseite publizierte Geschaeftskontaktdaten verarbeitet (kein Endnutzer-Personenbezug). Gespeichert werden nur das Pruefergebnis, Anzahl erwarteter/gefundener Werte sowie abweichende Werte in MASKIERTER Form (Telefon: nur letzte 4 Ziffern; E-Mail: nur erster Buchstabe + Domain) — keine Klartext-Kontaktdaten. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an korrekten Kundenangaben). Aufbewahrung: 30 Tage (automatische Bereinigung). Workspace-scoped, CASCADE-DELETE bei Page-/Workspace-Loeschung. RLS: nur Agentur-Admin/Manager.
Push-Benachrichtigungen (Browser & Companion App)
Rechtsgrundlage: Art. 6 Abs. 1 lit. a DSGVO (Einwilligung)
- Browser: Push-Subscription-Endpoint (wird bei Account-Löschung oder Opt-out automatisch gelöscht)
- Browser: Benachrichtigungsinhalte
- Companion App (iOS/macOS): APNs Device Token (geräte- und app-spezifischer Identifier, keine Klartextdaten)
- Companion App: Plattform (ios/macos), optionaler Gerätename, letzter Kontaktzeitpunkt
- Companion App: Push-Payload enthält für generische Notifications nur 'Neue Benachrichtigung'. Für Chat-Notifications (Direktnachrichten und @Mentions) werden Absender-Name und Nachrichtenvorschau (max. 100 Zeichen) übertragen — kein vollständiger Nachrichteninhalt. Die Übertragung erfolgt über Apple-Server (USA). Nutzer können Chat-Benachrichtigungen in den Companion-App-Einstellungen deaktivieren. Klick auf eine Chat-Benachrichtigung öffnet seit PROJ-549 das native Chat-Fenster der Companion App (Browser-Fallback nur falls die Companion App noch nicht initialisiert ist) — die Verarbeitung der Nachrichteninhalte erfolgt dabei lokal im Arbeitsspeicher der App, ohne weitere Datenübertragung an Dritte.
- Companion App — Telefonie-Push (PROJ-552): Bei eingehenden Anrufen auf der Telnyx-Rufnummer eines Mitarbeiters wird ein APNs-Push an alle registrierten macOS-Companion-Devices des Mitarbeiters gesendet, damit Annehmen/Ablehnen-Aktionen direkt aus der System-Notification möglich sind. Der Push-Payload enthält die vollständige (unmaskierte) Anrufer-Rufnummer im Title und Body — dies ist erforderlich, damit der Mitarbeiter eine informierte Annahme/Ablehnen-Entscheidung treffen kann (vergleichbar mit der Anrufer-Anzeige am Telefonhörer). Bei einem Match in der Workspace-CRM (contacts-Tabelle) wird zusätzlich der Kontakt-Name angezeigt. Die customData-Sektion des Pushes transportiert technische Routing-Parameter: kind=telephony.incoming, telnyx_call_id, caller_number, optional contact_id und contact_name, workspace_id. Rechtsgrundlage: Art. 6 Abs. 1 lit. b und f DSGVO (Vertragserfüllung Telefonie + berechtigtes Interesse an Anrufer-Erkennung). Übertragung erfolgt über Apple-Server (USA, SCCs). Telefonie-Pushes nutzen die UNNotificationCategory 'telephony.incoming-call' mit Annehmen-/Ablehnen-Action und sind nicht durch den Chat-Notifications-Toggle deaktivierbar — sie folgen den allgemeinen macOS-Notification-Einstellungen für die App.
- Companion App: Device Tokens werden nach 90 Tagen Inaktivität automatisch gelöscht (täglicher Cron)
Error-Tracking & Plattformüberwachung
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse)
- Fehlermeldungen und Stack Traces
- Seiten-URL zum Zeitpunkt des Fehlers
- Browser-Informationen (User-Agent)
- Fehler-Fingerprint (SHA-256 Hash, pseudonymisiert)
Webanalyse & Tracking (Google Tag Manager)
Rechtsgrundlage: Art. 6 Abs. 1 lit. a DSGVO (Einwilligung)
- Seitenaufrufe und Navigation (URL, Seitentyp)
- Klick-Ereignisse (CTA-Klicks, FAQ-Interaktionen, Navigationsklicks)
- Scroll-Verhalten (Scroll-Meilensteine)
- Consent-Status (erteilte/widerrufene Kategorien)
- Online-Kennungen (Cookies, IP-Adresse — nur nach Einwilligung). GTM nutzt Consent Mode v2: Tracking-Daten werden erst nach expliziter Einwilligung an Google übermittelt (wait_for_update: 500ms).
Externe und hybride Module (Custom Apps)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
- Beim Öffnen eines externen oder hybriden Moduls über die Sidebar wird ein kurzlebiger SSO-Token (JWT, 60 Sekunden gültig, einmalig verwendbar) an die externe App übermittelt. Bei hybriden Modulen erfolgt dies über einen separaten Button in der internen Verwaltungsoberfläche.
- Der Token enthält: Nutzer-ID, E-Mail-Adresse, Anzeigename, Workspace-Rolle, Workspace-ID und Modul-Schlüssel.
- Die externe App speichert diese Daten in einem technisch notwendigen Session-Cookie (8 Stunden Gültigkeit) auf ihrer eigenen Domain.
- Welche externen und hybriden Module aktiviert sind, wird vom Workspace-Administrator konfiguriert. Nur registrierte und für den Workspace freigegebene Module erhalten Zugriff.
- Token-Hashes (SHA-256) werden in NEULAND. OS gespeichert und nach spätestens einem Tag automatisch gelöscht.
- Für hybride Module kann eine Entwicklungs-URL (development_url) konfiguriert werden. Diese wird ausschließlich in der lokalen Entwicklungsumgebung (NODE_ENV=development) verwendet und nie in der Produktionsumgebung. In der Entwicklungsumgebung wird die Sidebar-Weiterleitung auf diese URL umgeleitet und die CORS-Konfiguration um diese Domain erweitert, um den Datenaustausch zwischen Plattform und externer App während der Entwicklung zu ermöglichen.
Lizenzverwaltung & Abrechnung (selbstständige Workspaces)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung nach GoBD/AO)
- Rechnungs-E-Mail-Adresse (billing_email): Wird bei der Workspace-Trennung vom Kunden-Admin angegeben und für den monatlichen Rechnungsversand verwendet. Aufbewahrung: Bis Stornierung der Lizenz + 8 Jahre (GoBD-Aufbewahrungsfrist für Rechnungen)
- Lizenzanfrage-Status: Anfragedatum, Aktivierungsdatum, Stornierungsdatum, Abrechnungsmodell (monatlich/jährlich), Grundlizenzpreis (Snapshot zum Zeitpunkt der Aktivierung). Aufbewahrung: Wie Rechnungsdaten (8 Jahre nach GoBD)
- Admin-Notizen: Interne Plattform-Admin-Notizen zur Lizenzanfrage (nicht für Kunden sichtbar). Aufbewahrung: Wie Lizenzanfrage
- Trennungsbegründung: Optionaler Freitext bei der Workspace-Trennung. Aufbewahrung: Solange die Workspace-Verbindung existiert
- KI-Nutzungskosten: Aggregierte Token-Kosten pro Monat und Workspace (aus ai_token_logs, keine personenbezogenen Daten). Werden als Rechnungsposition auf der monatlichen Lizenzrechnung ausgewiesen
- Automatisierte monatliche Rechnungserstellung: Am 1. jeden Monats werden für alle aktiven selbstständigen Kunden-Workspaces Lizenzrechnungen erstellt (Grundlizenz + KI-Kosten). Rechnungen starten als Entwurf (GoBD-konform, RE-Nummer erst beim Versand)
- Überfälligkeits-Tracking: Datum der ersten Überfälligkeit (overdue_since). Bei überfälligen Rechnungen (>30 Tage) werden Workspace-Admins per Inbox-Benachrichtigung informiert (max. 1 Benachrichtigung pro 7 Tage). Bei kritischer Überfälligkeit kann der Plattform-Admin den Workspace pausieren
- Löschung: Bei Stornierung der Lizenz wird der Status auf 'storniert' gesetzt (Soft-Delete). Rechnungsdaten unterliegen der GoBD-Aufbewahrungspflicht (8 Jahre) und können nicht vor Ablauf dieser Frist gelöscht werden. Bei Workspace-Löschung werden Lizenzanfragen per CASCADE gelöscht
Lizenzverwaltung & Abrechnung (Agentur-Workspaces)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung nach GoBD/AO)
- Automatische Trial-Phase: Bei Erstellung eines Agentur-Workspace wird automatisch eine 14-tägige Testphase gestartet (Dauer konfigurierbar durch Plattform-Admin). Während der Testphase ist die Plattform uneingeschränkt nutzbar. Gespeichert wird das Ablaufdatum der Testphase (trial_ends_at)
- Per-Seat-Abrechnung: Die monatlichen Kosten berechnen sich aus der Anzahl aktiver Workspace-Mitglieder (Seats) multipliziert mit dem konfigurierten Seat-Preis. Es gilt eine Mindest-Seat-Anzahl. Zum Abrechnungszeitpunkt wird ein Preis-Snapshot gespeichert (seat_price_snapshot, min_seats_snapshot), damit die historische Berechnung nachvollziehbar bleibt
- Abrechnungsmodell: Agentur-Admins wählen zwischen monatlicher und jährlicher Abrechnung. Bei Jahresabos wird ein konfigurierbarer Rabatt gewährt. Das Abrechnungsmodell (subscription_type) und das nächste Abrechnungsdatum (next_billing_date) werden gespeichert
- Rechnungs-E-Mail-Adresse (billing_email): Wird bei der Lizenzaktivierung vom Agentur-Admin angegeben und für den Rechnungsversand verwendet. Aufbewahrung: Bis Lizenz-Stornierung + 8 Jahre (GoBD)
- Automatisierte Rechnungserstellung: Am 1. jeden Monats werden für alle aktiven Agentur-Workspaces Lizenzrechnungen erstellt (Seat-Kosten + optional KI-Nutzungskosten). Rechnungen starten als Entwurf (GoBD-konform, RE-Nummer erst beim Versand). Bank-Daten des Workspace werden als Snapshot in der Rechnung gespeichert
- Trial-Ablauf-Benachrichtigungen: Vor Ablauf der Testphase erhalten Workspace-Admins eine In-App-Benachrichtigung. Bei Ablauf ohne Lizenzaktivierung wird der Workspace nach einer Karenzzeit (3 Tage) pausiert. Benachrichtigungen enthalten den Workspace-Namen und das Ablaufdatum
- Plattform-Operator-Key: Ein einzelner Agentur-Workspace kann vom Plattform-Admin als dauerhaft kostenfreier Operator-Workspace markiert werden (für den Plattformbetreiber selbst). Dieser Workspace wird von Abrechnungs- und Trial-Ablauf-Prozessen ausgenommen
- Löschung: Bei Workspace-Löschung wird die zugehörige Lizenz per CASCADE gelöscht. Bereits erstellte Rechnungen unterliegen der GoBD-Aufbewahrungspflicht (8 Jahre) und werden nach Ablauf der Frist automatisch anonymisiert
SEPA-Lastschriftmandat
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung nach Zahlungsdiensterichtlinie PSD2)
- IBAN: Wird bei der Mandatserteilung erfasst und mit AES-256-GCM verschlüsselt gespeichert. Nur Plattform-Administratoren können die verschlüsselte IBAN bei Bedarf entschlüsseln. In der Benutzeroberfläche wird ausschließlich eine maskierte Version angezeigt (z. B. DE89 •••• •••• •••• •••• 03)
- BIC: Optionale Bankleitzahl (öffentlich verfügbare Bankkennung), unverschlüsselt gespeichert. Bei Widerruf und Anonymisierung wird der Wert gelöscht
- Kontoinhaber: Name des Kontoinhabers, verschlüsselt gespeichert
- Mandatsreferenz: Eindeutige Kennung des Mandats (Format: MNDT-XXXXXXXX), nicht verschlüsselt
- Gläubiger-ID: Identifikationsnummer des Zahlungsempfängers, aus den Plattformeinstellungen geladen
- Widerrufs-Token: Kryptographisch sicherer Token für den öffentlichen Widerrufs-Link (wird per E-Mail an den Mandatsgeber versendet)
- Widerrufs-Informationen: Bei Widerruf werden Zeitpunkt und Name des Widerrufenden gespeichert
- Bestätigungs-E-Mail: Bei Mandatserteilung wird eine Bestätigung mit maskierter IBAN, Mandatsreferenz und Widerrufs-Link an die hinterlegte E-Mail-Adresse gesendet. Bei Widerruf wird eine separate Widerrufs-Bestätigung versendet
- Aufbewahrung aktiver Mandate: Solange das Mandat aktiv ist (unbefristet). Aktive Mandate können jederzeit vom Mandatsgeber über den Widerrufs-Link oder vom Plattform-Administrator widerrufen werden
- Aufbewahrung widerrufener Mandate: 14 Monate nach dem Widerrufsdatum. Nach Ablauf dieser Frist werden die personenbezogenen Daten (IBAN, BIC, Kontoinhaber) automatisch durch einen jährlichen Bereinigungsprozess anonymisiert. Nicht-personenbezogene Metadaten (Mandatsreferenz, Widerrufs-Zeitpunkt) bleiben für Audit-Zwecke erhalten
- Löschung bei Workspace-Löschung: Bei Löschung des zugehörigen Workspace werden alle SEPA-Mandate des Workspace anonymisiert (verschlüsselte Felder werden gelöscht, Status auf 'widerrufen' gesetzt)
- Mandatsanforderungen (sepa_mandate_requests): Bei der SEPA-Mandatsanforderung aus dem CRM werden Empfänger-E-Mail-Adresse, Empfängername und optional eine persönliche Notiz (max. 200 Zeichen) gespeichert. Ein tokenbasierter Signing-Link (UUID, 48 Stunden gültig) wird per E-Mail versendet. Nach Erteilung des Mandats wird der Zeitpunkt der Verwendung gespeichert. Aufbewahrung: 14 Monate nach Verwendung oder Ablauf des Tokens. Danach automatische Löschung durch den bestehenden SEPA-Bereinigungsprozess
- Auftragsstart-Wizard (PROJ-540): Beim Start des Auftragsstart-Wizards für ein bestätigtes Angebot prüft der Workspace-Backend-Endpunkt /api/quotes/:id/wizard-state ob für den verknüpften Kontakt ein aktives Mandat existiert. Übermittelte Daten an den Workspace-Frontend: ausschließlich Status (vorhanden/nicht vorhanden), Mandatsreferenz und Mandatserteilungs-Datum — niemals IBAN-Klartext oder verschlüsselte IBAN. Der Lookup nutzt einen Service-Role-Client; die Mandate-RLS bleibt unverändert (Plattform-Administrator-only)
Zahlungsausgang & Mahnwesen
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung nach §147 AO, §257 HGB, GoBD). Für Zahlungsauslösung über finAPI PIS: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) i. V. m. PSD2-Zahlungsdiensterichtlinie.
- Zahlungsaufträge (SEPA-Überweisungen und SEPA-Lastschriften): Empfängername, IBAN (AES-256-GCM verschlüsselt, gleicher Schlüssel wie finAPI-Daten), BIC, Betrag, Währung, Verwendungszweck, Ausführungsdatum, Status. Verknüpfung mit Kontakt, Rechnung, Buchungssatz und DMS-Dokument (optional). Aufbewahrung: 8 Jahre ab Ausführung (§147 Abs. 1 Nr. 1 AO — Buchungsbelege). Nach Ablauf: PII-Anonymisierung (Empfängername, IBAN, BIC, Verwendungszweck)
- Freigabe-Workflow (4-Augen-Prinzip): Konfigurierbare Freigabe-Regeln pro Workspace (Schwellwert, erforderliche Rolle). Freigabe-Einträge: Entscheider-User-ID, Entscheidung, Kommentar, Zeitstempel. Aufbewahrung: 8 Jahre (GoBD-Audit-Trail)
- Zahlungsauslösung über finAPI PIS: Bei Freigabe wird der Zahlungsauftrag über den finAPI Payment Initiation Service (PIS) an die Bank übermittelt. Übermittelte Daten: Empfänger-IBAN, Betrag, Verwendungszweck, Ausführungsdatum. Der Nutzer autorisiert die Zahlung über das PSD2-konforme finAPI Web Form (SCA — Strong Customer Authentication). Bank-Zugangsdaten werden nie an NEULAND. OS übermittelt
- Mahnwesen (3 Stufen): Automatische Erstellung von Mahnungen bei überfälligen Rechnungen. Mahnung enthält: Mahnnummer (GoBD-konform fortlaufend), Kontaktreferenz, Rechnungsreferenz, Mahngebühr, Verzugszinsen, Gesamtbetrag. Automatischer Versand für Stufe 1 und 2 konfigurierbar (Stufe 3 nie automatisch). Aufbewahrung: 6 Jahre ab Erstellung (§257 Abs. 1 Nr. 2 HGB — Geschäftsbriefe). Nach Ablauf: Kontaktreferenz wird anonymisiert
- E-Mail-Versand: Zahlungserinnerungen (Stufe 1) und Mahnungen (Stufe 2) werden über den E-Mail-Dienstleister Resend zugestellt. Enthaltene Daten: Kontaktname, Rechnungsnummer, Beträge, Fälligkeitsdaten, Workspace-Name
- Benachrichtigungen: Bei Mahnstufe 3 werden Workspace-Administratoren benachrichtigt (Inkasso-Entscheidung erforderlich). Bei Zahlungsfreigabe-Anfragen werden berechtigte Freigeber benachrichtigt
- DSGVO-Datenexport (Art. 15): Zahlungsaufträge und Mahnungen werden im Kontakt-Datenexport berücksichtigt. IBANs werden im Export nicht entschlüsselt angezeigt
- PROJ-905 Eingangsrechnungs-Automatik (incoming_invoices): Lieferantenrechnungen, die per E-Mail/DMS in als Eingangsrechnungs-Eingang markierte DMS-Ordner gelangen, werden per KI (Anthropic Claude Haiku 4.5) aus dem vorhandenen OCR-Text strukturiert ausgelesen. Verarbeitete Lieferanten-/Rechnungsdaten: Lieferantenname, IBAN (AES-256-GCM verschlüsselt, gleicher Schlüssel wie finAPI), BIC, Rechnungsnummer, Rechnungs- und Fälligkeitsdatum, Netto-/MwSt-/Bruttobetrag, Zahlungsart, Skonto. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Zahlungsabwicklung) und lit. f DSGVO (berechtigtes Interesse an effizienter Rechnungsbearbeitung). Bei Zahlungsart Überweisung wird automatisch ein SEPA-Zahlungsauftrag im Entwurfsstatus erzeugt, der ausschließlich nach menschlicher Freigabe (4-Augen-Workflow) über finAPI PIS ausgeführt wird — keine vollautomatische Zahlung. KI-Verarbeitung extern bei Anthropic (Auftragsverarbeiter, siehe PROCESSORS-Eintrag). RLS: nur Workspace-Admins und -Manager. Workspace-scoped, CASCADE-DELETE bei DMS-Dokument- oder Workspace-Löschung. Aufbewahrung: 8 Jahre als Buchungsbeleg (§147 AO), danach PII-Anonymisierung von Lieferantenname und IBAN. DSGVO-Datenexport: Geschäftsfelder enthalten, IBAN nicht entschlüsselt
Kennwortverwaltung (Zero-Knowledge-Tresor)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Bereitstellung des Passwort-Managers als Plattform-Funktion)
- Vault-Inhalte (vollständig verschlüsselt): Alle Kennwörter, Anmeldedaten, API-Keys, Zwei-Faktor-Authentifizierungsgeheimnisse (TOTP-Secrets) und sonstige Tresor-Inhalte werden ausschließlich client-seitig mit AES-256-GCM und einem PBKDF2-Schlüssel (600.000 Iterationen, SHA-256) verschlüsselt. Der Server empfängt und speichert ausschließlich verschlüsselte Ciphertext-Blobs — keinerlei Klartextdaten. Auch NEULAND. OS hat keinen Zugriff auf den Inhalt der Tresore (Zero-Knowledge-Architektur). Aufbewahrung: Bis zum Löschen durch den Nutzer oder bis zur Workspace-Löschung. QR-Code-Import und TOTP-Code-Generierung laufen ausschließlich im Browser — es werden keine QR-Code-Bilder oder Geheimnisse an externe Server übertragen
- Master-Passwort: Wird niemals übertragen oder gespeichert. Es verbleibt ausschließlich im Arbeitsspeicher des Browsers und wird zur lokalen Schlüsselableitung genutzt. Nach dem Auto-Lock (konfigurierbar: 1–480 Minuten) wird es aus dem Arbeitsspeicher entfernt
- Recovery-Key: Ein 52-Zeichen langer Wiederherstellungsschlüssel (32 Bytes zufällig, Base58-kodiert) wird beim ersten Vault-Setup einmalig angezeigt. Serverseitig wird ausschließlich ein PBKDF2-Hash des Recovery-Keys gespeichert (100.000 Iterationen). Der Klartext-Recovery-Key verlässt den Browser nicht
- Audit-Log: Für jeden Vault werden Zugriffsaktionen protokolliert (Vault-ID, Nutzer-ID, Aktionstyp wie 'item_viewed', 'item_created', 'member_added', Zeitstempel). Kein Klartext-Inhalt wird im Audit-Log gespeichert. IP-Adressen werden als HMAC-SHA256-Hash pseudonymisiert (irreversibel, Schlüssel serverseitig). Aufbewahrung: 90 Tage, danach automatische Löschung durch den täglichen Bereinigungsprozess
- Share-Links: Zeitlich begrenzte Freigabe-Links werden tokenbasiert erstellt (256-Bit-Zufallstoken). Der Entschlüsselungsschlüssel wird ausschließlich im URL-Fragment (#key=...) übertragen und gelangt nie zum Server. Aufgezeichnet werden: Erstellungszeitpunkt, Ablaufdatum (max. 30 Tage), Aufrufzähler (max. 100 Aufrufe). Nach Ablauf werden Share-Links automatisch deaktiviert
- Tresor-Mitgliedschaften: Zuordnung von Nutzern zu Tresoren mit Berechtigungsstufe (Betrachter, Bearbeiter, Admin). Nur vom Tresor-Admin einsehbar. Aufbewahrung bis zur Tresor-Löschung oder manuellem Entfernen. PROJ-1325 Autofill-Präferenz: Jeder Member kann pro Tresor festlegen, ob Einträge in Chrome-Erweiterung und Companion App als Autofill-Vorschlag erscheinen (Spalte autofill_excluded in vault_memberships, Boolean, Default false = eingeschlossen). Kein PII — reine UX-Präferenz. Automatische Löschung bei Tresor-Verlassen oder Tresor-Löschung (CASCADE). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Bedienkomfort/Datenschutz)
- Zwischenablage-Timeout: Aus dem Vault kopierte Werte werden nach 30 Sekunden automatisch aus der Zwischenablage gelöscht. Diese Funktion läuft ausschließlich client-seitig — es werden keine Zwischenablage-Inhalte übertragen
- PROJ-1735 Passwort-Generator (Chrome-Erweiterung): Neuer 'Generator'-Tab im Erweiterungs-Popup erzeugt Passwörter rein client-seitig (Web Crypto API), ohne Netzwerk- oder Server-Kommunikation. Einstellungen (Länge, Zeichensatz-Auswahl) werden im Browser-LocalStorage der Erweiterung gespeichert (Schlüssel neuland.popup.generator.v1) — ausschließlich Konfigurationswerte, niemals das generierte Passwort selbst. Zwischenablage-Auto-Clear nach 30 Sekunden läuft über einen Chrome-Extension-Alarm (chrome.alarms) und ein flüchtiges Offscreen-Dokument: In chrome.storage.session (reiner Arbeitsspeicher, wird bei Browser-Neustart automatisch geleert) wird ausschließlich ein SHA-256-Hash des kopierten Passworts abgelegt — nie der Klartext —, um vor dem Leeren zu prüfen ob die Zwischenablage seither unverändert ist. Kein PII — reine Client-Funktionalität ohne Personenbezug. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Bedienkomfort), localStorage-Eintrag nach §25 Abs. 2 Nr. 2 TDDDG technisch unbedingt erforderlich (keine Einwilligung nötig, analog zu PROJ-548)
- PROJ-548 Nutzungs-Metadaten (Zuletzt-genutzt-Sortierung): Im Browser-LocalStorage des Nutzers werden ausschließlich Eintrag-IDs (UUIDs) und Zeitstempel der letzten Interaktion gespeichert (Schlüssel: vault.mru.v1, max. 30 Einträge, 14-Tage-Fenster). Zweck: Sortierung der zuletzt genutzten Einträge im Schnellzugriff. Kein Server-Sync. Keine Klartextdaten (weder Titel, Benutzername, URL, Kennwort noch Tags). Item-IDs ohne Vault-Key sind nicht zu Inhalten auflösbar. Der Nutzer kann diese Daten jederzeit über die Browser-Storage-Verwaltung löschen. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Bedienkomfort)
- PROJ-622 Datei-Anhänge (vault_item_attachments): Pro Vault-Eintrag können max. 5 Datei-Anhänge angehängt werden (max. 5 MB pro Datei). Erlaubte Dateitypen: Zertifikate (.pfx, .p12, .pem, .cer, .crt) und Schlüssel-Dateien (.key, .ppk, .priv) — Magic-Byte-Whitelist verhindert Upload anderer Formate. Datei-Inhalt + Dateiname werden ausschließlich client-seitig mit dem Item-Key (AES-256-GCM, eigene IVs) verschlüsselt. Server speichert nur Ciphertext im privaten Storage-Bucket 'vault-attachments' — keine Klartext-Inhalte, keine lesbaren Dateinamen (Storage-Pfad: {vault_id}/{item_id}/{attachment_id}.enc). Auch NEULAND. OS hat keinen Zugriff (Zero-Knowledge-Architektur). Download via Signed-URL (60s Gültigkeit). Workspace-scoped, CASCADE-DELETE bei Item-/Workspace-Löschung
- PROJ-870 Kunden-/Partner-Workspace-Zuordnung: Tresore vom Typ 'Kunden-Workspace' oder 'Partner-Workspace' können einem verbundenen Workspace zugeordnet werden (Spalte vaults.connected_workspace_id, FK auf workspaces — keine neue personenbezogene Datenkategorie). Auswählbar sind ausschließlich bereits aktive Workspace-Verbindungen (Tabelle workspace_connections, Status aktiv) des eigenen Agentur-Workspaces. Auf Basis dieser Zuordnung kann ein Agentur-Admin/Manager gezielt einzelne Mitglieder des verbundenen Kunden-/Partner-Workspaces zum Tresor einladen. Empfänger-Kategorie: Die verschlüsselten Tresor-Inhalte werden dadurch für die eingeladenen Mitglieder des verbundenen Workspaces zugänglich — die Weitergabe erfolgt Zero-Knowledge über pro Mitglied ECDH-verschlüsselte Vault-Keys (kein Klartext-Schlüssel verlässt den Browser; NEULAND. OS erhält weiterhin keinen Zugriff auf Klartextinhalte). Der Zugriff ist rein mitgliedschaftsbasiert (vault_memberships) — die bloße Workspace-Zuordnung gewährt ohne explizite Einladung keinen Zugriff. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO. Aufbewahrung: bis zum Entfernen der Mitgliedschaft, zur Tresor-Löschung oder Workspace-Löschung (CASCADE)
- PROJ-1202 Multi-Tresor-Zuordnung (vault_item_vaults): Ein Vault-Item kann zusätzlich zu seinem Heimat-Tresor in weitere sekundäre Tresore geteilt werden (echtes Teilen, keine Kopien). Die Tabelle vault_item_vaults speichert pro Sekundär-Tresor: (1) den mit dem Sekundär-Tresor-Schlüssel client-seitig re-verschlüsselten Item-Schlüssel (encrypted_item_key — Ciphertext, kein Klartext), (2) den re-verschlüsselten Item-Titel (encrypted_title — Ciphertext), (3) shared_by_user_id (UUID des teilenden Nutzers, SET NULL bei Nutzer-Löschung). Der Server empfängt und speichert ausschließlich Ciphertext — Zero-Knowledge-Architektur wie bei allen Vault-Daten. Sekundäre Mitglieder sind read-only (EC-4). Löschung: CASCADE bei Item-Löschung (vault_item_id ON DELETE CASCADE) und bei Tresor-Löschung (vault_id ON DELETE CASCADE). Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO
- PROJ-1785 Tresor-Archivierung (vaults.archived_at): Tresor-Admins können ganze Tresore archivieren (reine Sichtbarkeits-Änderung, kein Lock) und jederzeit wiederherstellen — bewusst ohne Auswirkung auf Mitgliedschaften, Einträge, Autofill oder Sharing (Unterschied zum permanenten Hart-Löschen über is_deleted). Die Spalte archived_at (Zeitstempel) ist keine neue personenbezogene Datenkategorie — sie beschreibt den Sichtbarkeitszustand des Tresor-Containers, nicht eine Person. Jede Archivierungs-/Wiederherstellungsaktion wird im bestehenden Audit-Log protokolliert (Aktionstyp vault_archived/vault_unarchived, 90 Tage Aufbewahrung wie alle anderen Audit-Log-Einträge). Zugriff ausschließlich für Tresor-Admins (RLS-Policy vaults_update_admin + App-Layer-Check, Defense-in-Depth)
- Löschung: Vault-Einträge werden soft-deleted (deleted_at Zeitstempel). Eine vollständige Löschung erfolgt bei Workspace-Löschung (CASCADE). Der Nutzer kann einzelne Einträge, Tresore oder seine Tresor-Mitgliedschaft jederzeit löschen. Datei-Anhänge (PROJ-622) werden bei Item-Löschung mit CASCADE-DELETE entfernt — DB-Eintrag + Storage-Objekt. PROJ-870 Hinweis zur Workspace-Zuordnung: Wird eine Workspace-Verbindung getrennt oder die Zuordnung eines Kunden-/Partner-Tresors gewechselt, entzieht dies bereits eingeladenen Mitgliedern den Zugriff NICHT automatisch (bewusste MVP-Einschränkung). Die Tresor-Mitgliedschaft bleibt bestehen, bis der Tresor-Admin sie manuell entfernt — bis dahin behalten eingeladene Mitglieder Zugriff auf die verschlüsselten Inhalte
Chrome AutoFill Bridge (PROJ-534, macOS Companion App)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Bereitstellung des Passwort-Managers als Plattform-Funktion, gleiche Rechtsgrundlage wie Kennwortverwaltung/PROJ-123, dessen Nutzung diese Funktion erweitert)
- Hintergrund: Google Chrome unterstützt auf macOS die systemweite Anmeldedaten-Autovervollständigung (ASCredentialProvider) nicht mehr. Damit Chrome-Nutzer weiterhin Einträge aus ihrem NEULAND. OS Tresor automatisch ausfüllen können, kommuniziert eine private Chrome-Erweiterung über einen lokal auf dem Mac laufenden Native-Messaging-Host (Bridge-Binary, Teil des Companion-App-Bundles) mit der laufenden Companion-App.
- Lokale IPC statt Internet-Übertragung: Die Kommunikation läuft ausschließlich über einen Unix-Domain-Socket im macOS App-Group-Container des Nutzers (`group.com.neuland-agentur.os.vault`), zugriffsbeschränkt auf 0600-Dateiberechtigung. Es werden zu keinem Zeitpunkt Daten über das Internet oder an NEULAND. OS-Server übertragen — die gesamte Verarbeitung bleibt lokal auf dem Mac des Nutzers.
- Verarbeitete Daten: Beim Ausfüllen eines Login-Formulars in Chrome fordert die Erweiterung über die Bridge Vorschläge aus dem entsperrten Tresor an (URL-Matching gegen die aktuelle Tab-Adresse) und erhält bei Auswahl durch den Nutzer Benutzername, Kennwort und optional den aktuellen TOTP-Code des gewählten Eintrags zurück, die das Content-Script in die Formularfelder einträgt. Keine neue personenbezogene Datenkategorie gegenüber der bestehenden Kennwortverwaltung (PROJ-123/254) — Vault-Inhalte bleiben durchgehend Zero-Knowledge-verschlüsselt (AES-256-GCM), auch NEULAND. OS selbst hat keinen Zugriff auf Klartextinhalte.
- Native-Messaging-Manifest: Nur die eine, über einen festen Erweiterungs-Schlüssel deterministisch identifizierte private Chrome-Erweiterung darf mit dem Bridge-Host sprechen (`allowed_origins` ohne Wildcard). Die Erweiterung ist nicht im Chrome Web Store veröffentlicht und nur über das Companion-App-Bundle verteilbar.
- Kein neuer Auftragsverarbeiter: Google Chrome fungiert hierbei als reiner lokaler Client auf dem Gerät des Nutzers, nicht als Auftragsverarbeiter im Sinne von Art. 28 DSGVO — es gibt keinen Datenfluss an Google. Die `PROCESSORS`-Liste bleibt unverändert.
- Aufbewahrung/Löschung: Keine eigenständige Datenspeicherung durch dieses Feature — es greift lesend auf den bereits bestehenden, client-seitig verschlüsselten Vault zu (Löschkonzept siehe Kennwortverwaltungs-Eintrag oben). Rein clientseitige Konfigurationswerte der Erweiterung (z.B. Passwort-Generator-Einstellungen, siehe PROJ-1735-Eintrag oben) sind separat dokumentiert.
- Bekannte offene Lücke (Stand 30.07.2026): Ein dediziertes Audit-Log für einzelne Chrome-AutoFill-Ausfüllvorgänge (Zeitstempel, Domain, Eintragsname) ist noch nicht implementiert — anders als beim bestehenden webseitigen Vault-Audit-Log (siehe oben, 90 Tage Aufbewahrung) gibt es aktuell keine entsprechende lokale Protokollierung in der Companion-App. Kein Datenschutzrisiko (es werden dadurch keine zusätzlichen Daten verarbeitet), aber eine offene Nachvollziehbarkeits-Lücke — Nachtrag als natives neuland-ios-Feature vorgesehen, Umfang von Marcel zu entscheiden.
Terminbuchungssystem (öffentliche Buchungsseiten)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung — der Buchende initiiert die Terminvereinbarung) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter Terminplanung für den Workspace-Betreiber)
- Buchungsdaten des Gastes: Vorname, Nachname, E-Mail-Adresse, Telefonnummer (Pflichtfeld), persönliche Notiz (optional, Freitext max. 500 Zeichen). Zweck: Terminbestätigung, Kommunikation und Vorbereitung. Aufbewahrung: 90 Tage nach Terminzeitpunkt, danach automatische Anonymisierung durch täglichen Bereinigungsprozess (03:30 UTC). Bei Anonymisierung werden alle personenbezogenen Felder durch '[anonymisiert]' ersetzt und optionale Felder auf NULL gesetzt
- Einwilligungsnachweis (privacy_consent / privacy_consent_at): Der Buchende muss vor dem Absenden der Buchung aktiv in die Datenverarbeitung einwilligen (Pflicht-Checkbox mit Link zur Datenschutzerklärung des Workspace-Betreibers). Die Einwilligung wird serverseitig erzwungen (Buchung ohne Einwilligung wird abgelehnt) und der Einwilligungs-Zeitpunkt wird zur Erfüllung der Rechenschaftspflicht (Art. 7 i. V. m. Art. 5 Abs. 2 DSGVO) als Zeitstempel privacy_consent_at in der Buchung gespeichert. Aufbewahrung: Gemeinsam mit der Buchung (90 Tage). Hinweis: Buchungen, die vor Einführung dieser Persistierung (PROJ-1159) erstellt wurden, tragen privacy_consent_at = NULL — die Einwilligung war auch bei diesen serverseitig Pflicht
- Stornierungstoken (cancel_token): UUID-basierter Link zur eigenständigen Stornierung durch den Buchenden ohne Login. Wird per E-Mail zugestellt. Nicht erratbar (kryptographisch zufällige UUID). Gültigkeit: 7 Tage nach dem gebuchten Terminende — danach wird der Stornierungslink serverseitig abgelehnt. Vollständige Löschung: Bei Anonymisierung der Buchung (90 Tage nach Terminzeitpunkt)
- Flex-Terminvorschläge: Bei Flex-Buchungen schlägt der Gast bis zu 3 konkrete Zeitfenster vor. Pro Vorschlag wird ein separater Bestätigungstoken (confirm_token) generiert, der dem zuständigen Mitarbeiter per E-Mail zugestellt wird. Aufbewahrung: Gemeinsam mit der Buchung (90 Tage). Ablauf konfigurierbar (flex_expiry_days, Standard: 3 Tage)
- E-Mail-Versand über Resend: Bei Buchung, Bestätigung, Flex-Anfrage, Flex-Bestätigung und Stornierung werden E-Mails an den Gast und/oder den zuständigen Mitarbeiter gesendet. Übermittelte Daten: Name, E-Mail-Adresse, Termindetails (Titel, Datum, Uhrzeit, Dauer, Standort). E-Mails werden nicht im System gespeichert — nur der Status 'email_failed' bei Zustellungsfehlern
- Video-Raum (Daily.co): Bei Buchung mit Standorttyp 'Video' wird automatisch ein Daily.co-Raum erstellt. Es werden keine personenbezogenen Daten an Daily.co übermittelt — nur ein zufälliger Raumname und ein Ablaufzeitpunkt. Der Video-Link wird in der Bestätigungs-E-Mail an den Gast und Mitarbeiter versendet
- Google Calendar-Integration (optional): Wenn vom Workspace-Admin konfiguriert, wird bei Buchungsbestätigung automatisch ein Termin im Google Calendar des Mitarbeiters erstellt. Im Event-Titel wird der Buchungsseiten-Titel und der Gastname angezeigt. Die Gast-E-Mail-Adresse wird als Teilnehmer hinterlegt. Bei Stornierung wird der Kalendereintrag automatisch gelöscht. Verfügbarkeitsprüfung (lesend, PROJ-1480): Zusätzlich wird der Google-Kalender des Mitarbeiters live abgefragt (Google Calendar API, keine dauerhafte Speicherung der gelesenen Termindaten) um zu prüfen, ob der gewünschte Zeitraum bereits belegt ist — sowohl bei der Slot-Anzeige als auch unmittelbar vor dem Buchungs-Commit. Aus den gelesenen Kalender-Einträgen werden ausschließlich Start-/Endzeit und Absage-Status ausgewertet, keine Inhalte (Titel, Teilnehmer, Beschreibung) verarbeitet oder gespeichert
- Buchungsseiten-Konfiguration: Titel, Beschreibung, Termintyp, Standorttyp, Dauer, Pufferzeit, Vorlaufzeit, Buchungshorizont, Verfügbarkeitsregeln (JSONB). Keine personenbezogenen Daten. Aufbewahrung: Bis zur Löschung durch den Ersteller oder Workspace-Löschung (CASCADE)
- PROJ-1783 KI-Mitarbeiter-Werkzeug generate_booking_link (NEUE Erstellungs-Quelle, keine neue Datenkategorie): Ein KI-Mitarbeiter kann über ein Playbook-Werkzeug eigenständig eine Buchungsseite für ein Projekt/eine Aufgabe erzeugen — durchläuft dieselbe Erzeugungslogik und dieselben Gast-Datenkategorien wie eine manuell erstellte Buchungsseite, ohne die menschen-spezifische booking_pages_enabled-Berechtigungsprüfung (die gilt nur für interaktive Nutzung durch Menschen; der KI-Zugriff wird stattdessen über die pro-Worker konfigurierbaren Tool-Berechtigungen gesteuert). created_by wird auf einen echten Menschen gesetzt (den Konfigurator des KI-Mitarbeiters, ersatzweise einen aktiven Workspace-Admin) — nie auf den KI-Mitarbeiter selbst, da created_by eine Pflicht-Spalte mit FK auf auth.users ist. Zusätzlich erhält booking_pages zwei neue, nullable, nicht-personenbezogene interne Verknüpfungsspalten: project_id und task_id (FK auf projects/tasks, ON DELETE SET NULL) — bei allen zuvor bestehenden, nicht über dieses Werkzeug erzeugten Buchungsseiten bleiben beide NULL
- PROJ-1783 Projekt-Verlaufs-Eintrag bei Terminabschluss (activity_log, entity_type='project', event_type='booking_scheduled', NICHT KI-Worker-attribuiert): Nur bei Buchungsseiten mit gesetztem project_id (siehe oben) wird nach erfolgreichem Buchungsabschluss durch den Gast ein Eintrag im Projekt-Verlauf angelegt (actor_id=NULL, da die Buchung eine externe Gast-Handlung ist, kein interner Aktor). metadata enthält booking_id (interne UUID-Referenz, keine Gast-PII direkt im Log-Eintrag — Name/E-Mail bleiben ausschließlich in der referenzierten bookings-Zeile mit deren eigener 90-Tage-Anonymisierung), start_time (Termin-Zeitpunkt) und optional task_id. Sichtbar für alle Projekt-/Workspace-Mitglieder mit bestehendem Lesezugriff auf den Projekt-Verlauf (dieselbe RLS-geschützte Sichtbarkeit wie alle anderen activity_log-Einträge, keine neue Exposition). Kaskadiert bei Workspace-Löschung (activity_log.workspace_id); bleibt bei Projekt-Löschung technisch bestehen, da entity_id keine FK-Constraint auf die polymorphe Zieltabelle hat (Revisionssicherheit, analog anderen activity_log-Einträgen). Über den bestehenden activity_log-Datenexport (Art. 15/20, R-241) abgedeckt
- Mitarbeiter-Zuordnung & persönliche Buchungslinks: Buchungsseiten können einem oder mehreren Workspace-Mitgliedern zugewiesen werden. Die Zuordnung enthält Nutzer-ID, Buchungsseiten-ID und ein individuelles member_token (kryptographisch zufällige UUID). Über die öffentliche URL /book/[member_token] können Gäste direkt bei einem bestimmten Mitarbeiter buchen. Das Token enthält keine personenbezogenen Daten. Aufbewahrung: Bis zur Entfernung der Mitarbeiter-Zuordnung oder Workspace-Löschung (CASCADE)
- Inbox-Benachrichtigungen: Bei neuen Buchungen, Flex-Anfragen und Stornierungen durch den Gast werden In-App-Benachrichtigungen an den zuständigen Mitarbeiter erstellt. Die Benachrichtigung enthält den Gastnamen und Termindetails
- IP-Adresse: Wird bei öffentlichen Buchungs-Endpunkten ausschließlich für Rate-Limiting verarbeitet (in-memory, keine Persistierung). Kein IP-Hashing, kein Tracking
- Löschung/Anonymisierung: Nach 90 Tagen werden alle personenbezogenen Gastdaten automatisch anonymisiert (täglicher Cron, Batch-Verarbeitung à 500 Einträge). Ein anonymized_at-Zeitstempel wird gesetzt. Statistikdaten (Anzahl Buchungen, Termintyp, Dauer) bleiben für Reporting erhalten. Bei Workspace-Löschung werden alle Buchungsdaten vollständig gelöscht (CASCADE)
- DSGVO-Datenexport (Art. 15/20): Buchungsseiten, Buchungen mit allen PII-Feldern und Flex-Vorschläge sind im Workspace-Datenexport enthalten. Sicherheitsrelevante Tokens (cancel_token, confirm_token) werden nicht exportiert
- Weiterer Anzeigeort — Inbox-Kanal 'Termine' (PROJ-2106): Die dem zugewiesenen Mitarbeiter zugeordneten, anstehenden Buchungen (Gastname, Gastkontakt, Notiz, Video-Raum) werden zusätzlich in einem rollierenden 7-Tage-Fenster im Inbox-Kanal 'Termine' angezeigt. Kein neuer Empfängerkreis (weiterhin nur der über assigned_member_id zugewiesene Mitarbeiter), kein neuer Speicherort, keine neue Drittanbieter-Übertragung — reine Lese-Ansicht derselben bookings-Zeile, unveränderte 90-Tage-Anonymisierung. Aus der Inbox heraus sind Termine read-only (kein Löschen/Erledigt-Markieren), Verwaltung bleibt über die Buchungsseite bzw. Google Kalender
Social-Media-Publishing (Redaktionsplan-Veröffentlichung)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Bereitstellung der Social-Media-Verwaltung als Plattform-Funktion) und Art. 6 Abs. 1 lit. a DSGVO (Einwilligung — OAuth-Autorisierung durch den Account-Inhaber bei der Plattform-Verbindung)
- Social-Media-Konten (social_accounts): Plattform-Kennung (Facebook, Instagram, LinkedIn, YouTube, Google Business, X/Twitter, TikTok), Account-Name, Account-Typ (Seite/Profil/Kanal/Standort), Account-Avatar-URL, Plattform-Account-ID. OAuth-Zugangstokens (Access-Token, Refresh-Token) werden mit AES-256-GCM verschlüsselt gespeichert (eigener Schlüssel SOCIAL_ENCRYPTION_KEY). Token werden nie im Klartext in API-Antworten oder Logs zurückgegeben. Token-Ablaufdatum wird für proaktive Erneuerung gespeichert. Token-Herkunft (auth_method, PROJ-1476): Der Page-Zugriffstoken kann alternativ zum OAuth-Login aus dem Meta-System-User-Token der Werbekonten-Verbindung (workspace_ads_manager_connections, eigener Schlüssel META_SYSTEM_USER_ENCRYPTION_KEY) abgeleitet werden — beide Bereiche (Werbekonten und Social Publishing) nutzen dann dieselbe Token-Quelle; der abgeleitete Page-Token wird identisch verschlüsselt gespeichert. Aufbewahrung: Bis zur manuellen Trennung durch den Workspace-Admin oder Workspace-Löschung (CASCADE)
- Social-Media-Posts (social_posts): Textinhalt des Posts (max. 63.206 Zeichen je nach Plattform), Plattform-spezifische Daten (JSONB — z. B. Hashtags, Erwähnungen, Standort), geplanter Veröffentlichungszeitpunkt, tatsächlicher Veröffentlichungszeitpunkt, Plattform-Post-ID und -URL nach Veröffentlichung, Status (Entwurf/Geplant/Veröffentlicht/Fehlgeschlagen/Abgebrochen), Fehlermeldung bei fehlgeschlagener Veröffentlichung (max. 2.000 Zeichen), Retry-Zähler. Verknüpfung mit Redaktionsplan-Eintrag, Social-Account und Kontakt. Aufbewahrung: Bis zur manuellen Löschung durch den Nutzer oder Workspace-Löschung (CASCADE)
- Instagram-Detailfelder (PROJ-1460, Teil von social_posts.platform_specific_data): Geotag (Meta-Standort-ID), Kollaborateure und markierte Personen (Instagram-Usernamen — personenbezogene Daten Dritter, vom Nutzer selbst zur Veröffentlichung eingegeben und direkt an Instagram/Meta übermittelt; keine gesonderte Speicherung oder Weiterverarbeitung durch NEULAND. OS über den Post-Datensatz hinaus). Erst-Kommentar-Text: wird nach erfolgreicher Post-Veröffentlichung über einen zusätzlichen API-Aufruf als eigenständiger Kommentar auf Instagram, Facebook oder LinkedIn veröffentlicht (kein Fixieren/Anheften — von den Plattform-APIs nicht unterstützt). Aufbewahrung: wie social_posts (CASCADE)
- Post-Medien (social_post_media): Bilddateien, Videos, GIFs und Dokumente werden in einem öffentlichen Supabase-Storage-Bucket (social-media) mit nicht erratbaren UUID-Pfaden gespeichert. Der öffentliche Zugang ist technisch erforderlich, da Social-Media-Plattformen (Meta, YouTube, etc.) die Medien-URLs direkt abrufen müssen. Maximale Dateigröße: 100 MB. Zugelassene MIME-Typen: Bilder (JPEG, PNG, GIF, WebP), Videos (MP4, MOV, AVI, WebM), Dokumente (PDF). Metadaten: Dateityp, Abmessungen, Dauer (bei Video), Dateigröße, Alt-Text, Sortierreihenfolge. Hinweis zu EXIF-/GPS-Metadaten: Hochgeladene Bilddateien können eingebettete EXIF-Daten enthalten (z. B. GPS-Koordinaten, Kameradaten, Aufnahmedatum). NEULAND. OS entfernt EXIF-Daten nicht serverseitig — die meisten Social-Media-Plattformen (Meta, LinkedIn, TikTok) entfernen EXIF-Daten automatisch beim Upload. Nutzer sollten sensible Metadaten vor dem Upload entfernen, insbesondere bei Fotos mit Standortdaten. Zugriff auf die Verwaltungs-API nur für Workspace-Mitglieder über RLS-geschützte Endpunkte. Löschung bei Post-Löschung (CASCADE) oder Workspace-Löschung
- Plattform-Veröffentlichung: Bei der Veröffentlichung werden Post-Inhalt, Mediendateien und plattform-spezifische Daten an die jeweilige Social-Media-Plattform übermittelt. Die Plattformen (Meta/Facebook, Meta/Instagram, LinkedIn, YouTube/Google, X/Twitter, ByteDance/TikTok) sind eigenständige Verantwortliche gemäß Art. 26 DSGVO — es handelt sich nicht um Auftragsverarbeiter. Für die Datenverarbeitung auf den Plattformen gelten deren jeweilige Datenschutzrichtlinien. NEULAND. OS übermittelt nur die Daten, die der Nutzer explizit zur Veröffentlichung vorgesehen hat
- CMS-Export: Blog-/News-/Termin-/Landingpage-Inhalte können als Social-Media-Post exportiert werden. Dabei werden Titel, Beschreibung und Beitragsbild aus der CMS-Seite übernommen. Es werden keine zusätzlichen personenbezogenen Daten erhoben
- Automatische Token-Erneuerung: Ein täglicher Hintergrundprozess prüft ablaufende OAuth-Tokens und erneuert sie automatisch über die jeweilige Plattform-API. Bei fehlgeschlagener Erneuerung wird der Account-Status auf 'Erneuerung erforderlich' gesetzt und der Ersteller per Inbox-Benachrichtigung informiert. Kein manuelles Eingreifen erforderlich — der Token-Refresh erfolgt im Hintergrund
- Geplante Veröffentlichung: Ein Hintergrundprozess (alle 5 Minuten) veröffentlicht geplante Posts zum vorgesehenen Zeitpunkt. Bei Fehlern: Automatischer Retry mit exponentiellem Backoff (10, 20, 40 Minuten). Nach 3 fehlgeschlagenen Versuchen: Status 'Fehlgeschlagen' und Benachrichtigung an den Ersteller
- Benachrichtigungen: Bei erfolgreicher Veröffentlichung aller Posts eines Redaktionsplan-Eintrags sowie bei endgültigem Fehlschlag werden Inbox-Benachrichtigungen erstellt. Enthaltene Daten: Plattformname, Fehlermeldung (gekürzt auf 200 Zeichen), Anzahl der Posts. Bei automatischer Aufgabenerstellung aus Frequenz-Konfiguration (Cron editorial-task-scheduler) wird der zugewiesene Nutzer per Inbox-Benachrichtigung informiert. Wiedervorlage-Erinnerungen werden N Arbeitstage vor der nächsten Ausführung gesendet
- Redaktionsplan-Erweiterung (PROJ-278): Redaktionsplan-Einträge können ein Kampagnenkonzept als Freitext (campaign_concept, max. 10.000 Zeichen) enthalten. Bei Frequenz-basierter Aufgabenerstellung werden automatisch Tasks im verknüpften Projekt erstellt. Verarbeitete Daten: Titel, Zuweisungs-ID (assigned_to), Aufgabenvorlage, Projekt-ID. Keine zusätzlichen personenbezogenen Daten über die bestehende Redaktionsplan-Verarbeitung hinaus
- DSGVO-Datenexport (Art. 15/20): Social-Accounts (ohne verschlüsselte Tokens), Social-Posts und Redaktionsplan-Einträge (inkl. campaign_concept) werden im Workspace-Datenexport berücksichtigt
- Löschung: Bei Kontakt-Löschung bleiben verknüpfte Social-Accounts und Posts bestehen (contact_id wird auf NULL gesetzt). Bei Workspace-Löschung werden alle Social-Publishing-Daten vollständig gelöscht (CASCADE). Einzelne Posts und Accounts können jederzeit durch Workspace-Admins und -Manager gelöscht werden
Redaktionsplan-Erweiterung (Frequenz-Automatisierung & Kampagnen-Konzept)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Bereitstellung der Redaktionsplanung als Plattform-Funktion)
- Kampagnen-Konzept (editorial_plan_entries.campaign_concept): Freitext-Feld für die inhaltliche Planung von Redaktionsplan-Einträgen (Ziel, Botschaft, Umsetzungsidee). Kann personenbezogene Daten enthalten, z.B. Kundennamen, Ansprechpartner oder zielgruppenspezifische Informationen. Maximal 10.000 Zeichen. Aufbewahrung: Bis zur Löschung des Eintrags durch den Nutzer oder CASCADE bei Workspace-Löschung
- Frequenz-Automatisierung: Täglicher Hintergrundprozess (06:00 UTC) erstellt automatisch Aufgaben aus Redaktionsplan-Einträgen basierend auf konfigurierbarer Frequenz (einmalig bis jährlich). Verarbeitete Daten: assigned_to (User-ID des zuständigen Mitarbeiters), task_template_id, execution_count. Benachrichtigungen (editorial_task_scheduled, editorial_review_reminder) enthalten Entry-Titel und Task-Titel
- UTM-Tracking-Konfiguration (editorial_plan_entries.tracking_utm_source/medium): Optionale UTM-Konfigurationsfelder für den Tracking-Link-Generator. Definieren welche UTM-Werte für Beiträge dieses Eintrags verwendet werden sollen (z.B. utm_source='facebook', utm_medium='organic'). Technische Konfigurationsdaten, keine personenbezogenen Daten. PROJ-305
- DSGVO-Datenexport (Art. 15/20): editorial_plan_entries inkl. campaign_concept, assigned_to, contact_id, tracking_utm_source, tracking_utm_medium, campaign_id, post_text und alle weiteren Felder sind im Workspace-Datenexport enthalten
- Kampagnen-System (PROJ-332): Kampagnen (campaigns-Tabelle) sind kontakt-spezifische Content-Planungseinheiten. Verarbeitete Daten: Kampagnenname, Konzept-HTML (description_html — Freitext, kann Kundennamen, Ansprechpartner oder strategische Informationen enthalten, max. 50.000 Zeichen), Kanal-Konfiguration, Frequenz, Startdatum, KI-Assistenten-Zuordnung. Aufbewahrung: Bis zur Löschung durch den Nutzer oder CASCADE bei Kontakt-/Workspace-Löschung. DSGVO-Datenexport: campaigns-Tabelle ist im Workspace-Datenexport enthalten. Sub-Entities (campaign_variants, PROJ-561): Pro Kampagne können bis zu 6 Varianten (A/B-Tests, Messaging-Angles) angelegt werden mit Name, Konzept-HTML (description_html — Freitext, Workspace-spezifisch, max. 50.000 Zeichen), Messaging-Angle (max. 500 Zeichen) und optionalem Channel-Format-Override (channel_asset_formats JSONB). Aufbewahrung: CASCADE-DELETE bei Kampagnen-Löschung. Im Workspace-Datenexport enthalten
- Kampagnen Beitragstext (editorial_plan_entries.post_text): Freitext-Feld für den konkreten Social-Media-Beitragstext (max. 5.000 Zeichen). Kann personenbezogene Daten enthalten (z.B. Testimonials, Kundenzitate). Aufbewahrung: Bis zur Löschung des Eintrags oder CASCADE bei Workspace-Löschung
Social Inbox & Engagement-Management (Kommentar-/Bewertungsverwaltung)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Verwaltung von Social-Media-Engagement als Dienstleistung) und Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Bereitstellung der Kommentar-Verwaltung als Plattform-Funktion)
- Social-Kommentare (social_comments): Öffentlich zugängliche Kommentare und Bewertungen von den angebundenen Social-Media-Plattformen werden automatisch alle 15 Minuten abgerufen und in einem einheitlichen Format gespeichert. Erfasste Daten: Autorenname, Autoren-Handle (optional), Autoren-Profilbild-URL (optional), Plattform-Benutzer-ID des Autors, Kommentartext, Sternebewertung (1–5, nur bei Google-Bewertungen), Likes- und Antwortenzähler, Plattform-Zeitstempel. Diese Daten sind auf den jeweiligen Plattformen öffentlich einsehbar. Aufbewahrung: 90 Tage aktiv, danach automatische Archivierung. Nach 365 Tagen: vollständige Löschung (Hard Delete). Kommentare mit offenen Antwort-Entwürfen werden nicht archiviert
- Antworten (social_comment_replies): Antworten auf Kommentare, die von Workspace-Mitgliedern verfasst werden. Erfasste Daten: Antworttext, ID des antwortenden Mitglieds, Plattform-Antwort-ID (nach Veröffentlichung), Status (Entwurf/Senden/Gesendet/Fehlgeschlagen). Antworten werden über die jeweilige Plattform-API veröffentlicht. Aufbewahrung: Bis zur Löschung des zugehörigen Kommentars (CASCADE)
- Interne Bearbeitungsnotizen: Workspace-Mitglieder können interne Notizen an Kommentare anhängen und Kommentare Teammitgliedern zuweisen. Diese Daten sind ausschließlich für das Team sichtbar und werden NICHT im Kunden-Portal angezeigt
- Dritterhebung (Art. 14 DSGVO): Die Kommentardaten werden nicht direkt bei den betroffenen Personen (Kommentar-Autoren) erhoben, sondern über die öffentlichen APIs der jeweiligen Social-Media-Plattformen abgerufen. Die Rechtsgrundlage ist das berechtigte Interesse (Art. 6 Abs. 1 lit. f) an der effizienten Verwaltung von Social-Media-Interaktionen im Rahmen der Agentur-Dienstleistung. Eine individuelle Information der Kommentar-Autoren ist nicht erforderlich, da es sich um öffentlich zugängliche Daten handelt (Art. 14 Abs. 5 lit. b DSGVO)
- Plattform-Abruf: Kommentare und Bewertungen werden über die APIs der Plattformen Meta (Facebook, Instagram), LinkedIn, YouTube (Google), Google Business Profile (Standort-Bewertungen mit Sternebewertung 1–5, Autorenname und Antwort-Funktion; Local Posts mit Typ: Neuigkeit/Event/Angebot; Multi-Standort-Verwaltung), X/Twitter und TikTok abgerufen. Die Plattformen sind eigenständige Verantwortliche gemäß Art. 26 DSGVO. Der Abruf erfolgt im Rahmen der OAuth-Autorisierung des Account-Inhabers
- Kunden-Portal: Kunden können im Portal Kommentare und Bewertungen zu ihren Social-Media-Konten einsehen (nur Lesen). Interne Notizen, Zuweisungen und als Spam/Archiviert markierte Kommentare werden im Portal NICHT angezeigt
- DSGVO-Datenexport (Art. 15/20): Social-Kommentare und zugehörige Antworten werden im Kontakt-Datenexport berücksichtigt, sofern sie einem Kontakt zugeordnet sind. Exportierte Felder: Plattform, Autorenname, Kommentartext, Bewertung, Status, Plattform-Zeitstempel, Antworttexte
- Löschung: Bei Kontakt-Löschung wird die Kontakt-Zuordnung entfernt (contact_id wird auf NULL gesetzt). Bei Account-Disconnect werden alle zugehörigen Kommentare vollständig gelöscht (CASCADE). Bei Workspace-Löschung werden alle Kommentardaten vollständig gelöscht (CASCADE). Automatische Bereinigung: Archivierung nach 90 Tagen, Hard Delete nach 365 Tagen (täglicher Hintergrundprozess um 02:00 UTC)
- IP-Adressen: Werden bei API-Endpunkten ausschließlich für Rate-Limiting verarbeitet (in-memory, keine Persistierung)
Web-Recherche-Assistent (KI-gestützte Unternehmensrecherche)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an B2B-Akquise). Die Datenerhebung beschränkt sich auf öffentlich zugängliche Pflichtdaten gemäß §5 DDG (Impressumspflicht) und freiwillig veröffentlichte Kontaktdaten auf Unternehmenswebsites
- Suchkriterien: Branche, Region und optionale Zusatzkriterien werden server-seitig an SerpAPI (USA) übermittelt. Keine personenbezogenen Daten des ausführenden Nutzers werden an SerpAPI gesendet (nur die IP-Adresse des Servers). SerpAPI-Key ist AES-256-GCM verschlüsselt (SERPAPI_ENCRYPTION_KEY)
- Suchergebnisse (raw_results): Google-Suchergebnisse (Titel, URL, Snippet) werden in der research_runs-Tabelle als JSONB gespeichert. Snippets können vereinzelt Personennamen enthalten, die in öffentlichen Suchergebnissen erscheinen
- KI-Qualifizierung: Suchergebnisse werden vor der KI-Verarbeitung durch Claude Haiku mittels sanitizePii() anonymisiert. Die KI bewertet nur öffentliche Firmendaten (Name, Branche, Region) — keine personenbezogenen Daten
- Gescrapete Unternehmensdaten: Von öffentlichen Unternehmenswebsites (Impressum, Kontaktseite, Team-Seite) werden erhoben: Firmenname, Geschäftsadresse, allgemeine Geschäfts-E-Mail und -Telefon, Ansprechpartner (Vor-/Nachname, Position, personalisierte E-Mail, Direkttelefon — max. 10 pro Unternehmen). Ausschließlich öffentlich zugängliche Daten — kein LinkedIn-Scraping, keine privaten Daten
- Dritterhebung (Art. 14 DSGVO): Die Ansprechpartner-Daten werden nicht bei den Betroffenen direkt erhoben, sondern von deren Unternehmenswebsites. Eine individuelle Information ist nicht erforderlich, da es sich um öffentlich zugängliche Daten handelt (Art. 14 Abs. 5 lit. b DSGVO). Bei Widerspruch kann der Betroffene die Löschung beim Verantwortlichen beantragen
- Speicherung in research_runs: Alle Recherche-Läufe werden protokolliert (Rechenschaftspflicht Art. 5 Abs. 2 DSGVO). Gespeichert werden: Suchkriterien, qualifizierte Ergebnisse inkl. Ansprechpartner, Zeitstempel, ausführender Nutzer. RLS-geschützt (Workspace-isoliert, nur eigener Nutzer kann erstellen/bearbeiten). Aufbewahrung: 180 Tage, danach werden personenbezogene Daten in contact_persons anonymisiert (Firmenname und Qualifizierung bleiben für Audit-Trail erhalten). Ausnahme (PROJ-1429): Der automatisierte Bid4it-Künstler-Anreicherungsschritt teilt sich das server-seitige SerpAPI-Tageskontingent und schreibt dafür ebenfalls einen research_runs-Eintrag (`criteria.source = "bid4it_artist_enrichment"`, keine Ansprechpartner-Daten). Da dieser Schritt cron-/sync-gesteuert läuft und `user_id` FK-NOT-NULL ist, wird der Eintrag technisch einem aktiven Workspace-Admin zugeordnet, der die Suche nicht selbst ausgelöst hat — kein personenbezogenes Verhaltensprofil dieses Admins, rein technische Attribution für die Kontingent-Buchführung
- CRM-Import: Qualifizierte Unternehmen können manuell ins CRM importiert werden (lead_source: "ki_recherchiert"). Importierte Kontakte und Ansprechpartner unterliegen den regulären CRM-Lösch- und Exportrechten
- DSGVO-Datenexport (Art. 15/20): Importierte Kontakte werden im regulären Kontakt-Datenexport berücksichtigt. Zusätzlich werden research_runs-Referenzen exportiert, wenn der exportierte Kontakt durch eine Recherche importiert wurde (Herkunftsinformation: Recherche-Kriterien, Qualifizierungsgrund, Zeitpunkt)
Mitarbeiterdokumenten-System (HR-Dokumente)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Arbeitsvertrag) und Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung — §257 HGB Aufbewahrungspflicht für Arbeitsverträge und personalrelevante Dokumente, 10 Jahre). Für den digitalen Signing-Prozess: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an rechtssicherer Dokumentation der Kenntnisnahme/Unterzeichnung)
- HR-Dokumentvorlagen (hr_document_templates): Titel, Dokumenttyp (Arbeitsvertrag, Nachtrag, Zeugnis, Abmahnung, Kündigung, Sonstiges), Markdown-Inhalt (Freitext — kann Platzhalter für personenbezogene Daten enthalten), Ersteller-ID, Aktivierungsstatus. Keine personenbezogenen Mitarbeiterdaten in der Vorlage selbst. Aufbewahrung: Bis zur Deaktivierung/Löschung durch den Workspace-Admin oder Workspace-Löschung (CASCADE)
- HR-Dokumente (hr_documents): Titel, Dokumenttyp, Status (Entwurf/Versandt/Unterzeichnet/Abgelehnt/Archiviert), Sichtbarkeit (intern/mitarbeiter/alle), Markdown-Inhalt (personalisiert — kann Mitarbeiterdaten wie Name, Gehalt, Vertragsbedingungen enthalten), Signing-Konfiguration (ob Unterschrift erforderlich), Zugeordneter Mitarbeiter (member_id, SET NULL bei Profil-Löschung). Aufbewahrung: §257 HGB — 10 Jahre für Arbeitsverträge und personalrelevante Dokumente. Soft-Delete (deleted_at) — physische Löschung erst nach Ablauf der Aufbewahrungsfrist
- Digitale Unterzeichnung: Bei Dokumenten mit Unterschriftspflicht wird ein kryptographisch sicherer Signing-Token (UUID) generiert und per E-Mail (über Resend) an die hinterlegte Mitarbeiter-E-Mail gesendet. Der Token hat eine konfigurierbare Gültigkeitsdauer (Standard: 7 Tage). Nach Unterzeichnung wird der Token sofort invalidiert (auf NULL gesetzt). Maximal 5 E-Mail-Versendungen pro Dokument (Re-Send-Limit)
- Signing-Metadaten: Bei der digitalen Unterzeichnung werden gespeichert: Name des Unterzeichnenden (Freitext-Eingabe), Unterzeichnungszeitpunkt, IP-Adresse pseudonymisiert als SHA-256-Hash mit Salt (nicht rückverfolgbar, Salt aus Umgebungsvariable IP_HASH_SALT). Zweck: Rechtssichere Nachweisbarkeit der Unterzeichnung. Aufbewahrung: Gemeinsam mit dem Dokument (§257 HGB, 10 Jahre)
- User-Agent (Browser-Informationen): Bei der digitalen Unterzeichnung wird der User-Agent-String des Browsers im Audit-Log gespeichert (gekürzt auf max. 500 Zeichen). Enthält: Browser-Name/-Version, Betriebssystem, Geräteinformationen. Zweck: Forensische Nachvollziehbarkeit und Betrugsprävention bei strittigen Unterzeichnungen. Aufbewahrung: Gemeinsam mit dem Audit-Log-Eintrag (§257 HGB, 10 Jahre). Im DSGVO-Datenexport als „Browser-Informationen gespeichert" pseudonymisiert ausgegeben
- Audit-Log (hr_document_signing_log): Alle signierungsrelevanten Aktionen werden protokolliert: Aktion (Token generiert, E-Mail versendet, E-Mail erneut versendet, Token abgelaufen, Unterzeichnet), Zeitstempel, ausführender Nutzer (bei Admin-Aktionen) oder IP-Hash (bei öffentlichen Signing-Aktionen), User-Agent (bei Unterzeichnung). Aufbewahrung: §257 HGB, 10 Jahre
- Dokumenten-Dateien: Generierte oder hochgeladene PDF-Dateien werden in einem privaten Supabase-Storage-Bucket (hr-documents) gespeichert. Zugriff nur über zeitbegrenzte signierte URLs (1 Stunde Gültigkeit) für berechtigte Workspace-Mitglieder. Storage-Pfad: workspace_id/document_id/dateiname. Aufbewahrung: §257 HGB, 10 Jahre. Bei Soft-Delete werden Storage-Dateien zunächst beibehalten — physische Löschung durch Bereinigungsprozess nach Ablauf der Aufbewahrungsfrist
- E-Mail-Versand: Bei Versand des Signing-Links wird eine E-Mail über Resend an die Mitarbeiter-E-Mail gesendet. Enthaltene Daten: Mitarbeitername, Dokumenttitel, Dokumenttyp, Workspace-Name, Signing-Link, Ablaufdatum. E-Mail-Inhalte werden nicht dauerhaft in NEULAND. OS gespeichert
- Benachrichtigungen: 3 Notification-Typen (hr_document_received für Mitarbeiter bei neuem Dokument, hr_document_signed für Admin bei Unterzeichnung, hr_document_expiring für Admin bei ablaufendem Token). Metadaten: Dokumenttitel, Dokumenttyp, Mitarbeitername. Aufbewahrung: 90 Tage (Standard-Notification-Retention)
- Öffentliche Signing-Seite (/hr-dokument/unterzeichnen/[token]): Zugriff ohne Login über den Signing-Token. Angezeigt werden: Workspace-Name und -Logo, Dokumenttitel und -typ, Dokumentinhalt (Markdown), Ablaufdatum. Datenschutzhinweis auf der Seite informiert über: Speicherung von Name und Zeitpunkt der Unterzeichnung, pseudonymisierte IP-Adresse (SHA-256) im Audit-Log, Verweis auf die Datenschutzerklärung
- DSGVO-Datenexport (Art. 15/20): HR-Dokumente (Titel, Typ, Status, Unterzeichnungsdaten), HR-Dokumentvorlagen (Titel, Typ) und Signing-Audit-Log (Aktionen, Zeitstempel — IP-Hash als „SHA-256-Hash gespeichert (pseudonymisiert)", User-Agent als „Browser-Informationen gespeichert") sind im Workspace-Datenexport enthalten
- Löschung/Anonymisierung: Entwürfe können vollständig gelöscht werden (Soft-Delete). Versandte und unterzeichnete Dokumente unterliegen der Aufbewahrungspflicht (§257 HGB, 10 Jahre) — nur Soft-Delete, keine physische Löschung vor Ablauf. Bei Profil-Löschung eines Mitarbeiters: member_id wird auf NULL gesetzt (SET NULL statt CASCADE — verhindert Datenverlust bei Aufbewahrungspflicht). Bei Workspace-Löschung: CASCADE-Löschung aller HR-Dokumente, Vorlagen, Audit-Logs und Storage-Dateien
VSOP-Beteiligungsprogramm (Virtuelle Unternehmensbeteiligung)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Durchführung des Beschäftigungsverhältnisses)
- Programmkonfiguration: Stammkapital, VGA-Volumen, Ausgabepreis, Laufzeit, Kategorie-Definitionen — gespeichert in vsop_programs (1 pro Workspace). Aufbewahrung: Bis Programmende + 10 Jahre (§257 HGB)
- Zuteilungen: Mitarbeiter-Verknüpfung (profiles.id), Kategorie, VGA-Anzahl, Vesting-Parameter (Beginn, Periode, Cliff), Ausgabepreis, Status, Leaver-Daten — gespeichert in vsop_allocations. Aufbewahrung: 10 Jahre nach Programmende (§257 HGB)
- Signing-Token: UUID-basierter Token mit 30 Tagen Gültigkeit, gespeichert als Klartext in vsop_allocations.signing_token. Nach Unterzeichnung sofort auf NULL gesetzt (invalidiert)
- Digitale Unterzeichnung (vsop_signings): Name des Unterzeichnenden (Freitext), Unterzeichnungszeitpunkt (UTC), IP-Adresse als SHA-256-Hash mit Salt (nicht rückverfolgbar), User-Agent als SHA-256-Hash, PDF-Speicherpfad. Aufbewahrung: 10 Jahre (§257 HGB)
- PDF-Dokumente: Zuteilungsschreiben mit eingebettetem Signing-Nachweis, gespeichert im privaten Storage-Bucket vsop-documents. Zugriff nur über signierte URLs mit 24 Stunden Gültigkeit
- E-Mail-Versand: Signing-Einladung und Bestätigungs-E-Mail über Resend. Enthaltene Daten: Mitarbeitername, VGA-Anzahl, Kategorie, Signing-Link mit Token, Ablaufdatum
- Benachrichtigungen: 2 Notification-Typen (vsop_allocation_sent an Mitarbeiter, vsop_allocation_signed an Admins). Metadaten: VGA-Anzahl, Kategorie, Mitarbeitername
- Vesting-Berechnung: Rein deterministische Berechnung basierend auf Datumsfeldern (keine zusätzliche Datenspeicherung). Berechnung erfolgt on-demand bei Seitenaufruf
- DSGVO-Datenexport (Art. 15/20): VSOP-Zuteilungen und Signing-Nachweise sind im Workspace-Datenexport enthalten
Entwicklungs-Token-Tracking (Claude Code Sessions)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung — GoBD-Dokumentation von Entwicklungskosten)
- Entwickler-E-Mail-Adresse: Wird vom Entwickler lokal in der workspace-mapping.json konfiguriert und bei Session-Upload an die API übermittelt. Zweck: Zuordnung der Entwicklungskosten zu einem Entwickler im Dashboard. Aufbewahrung: 6 Jahre (GoBD — Geschäftsunterlagen)
- Session-Metadaten: Session-ID (von Claude Code vergeben), Arbeitsverzeichnis (cwd), Git-Branch, Session-Start und -Ende. Keine personenbezogenen Daten Dritter enthalten
- Token-Verbrauch pro Modell (model_usage): Anzahl der Input-/Output-/Cache-Tokens je verwendetem KI-Modell (z. B. Claude Opus, Claude Haiku). Rein technische Nutzungsdaten. Aufbewahrung: 6 Jahre (GoBD)
- Kosten-Berechnung: Automatische Berechnung der Kosten in USD und EUR basierend auf den Token-Verbrauchsdaten und dem bestehenden Preissystem (pricing.ts). Wechselkurs via EZB-Tagesrate
- Workspace-Zuordnung: Optionale Verknüpfung der Session mit einem Kunden-Workspace. Kann bei Session-Start via macOS-Dialog gewählt oder nachträglich durch den Plattform-Admin zugeordnet werden
- Session-Beschreibung (reason, PROJ-165): Optionaler Freitext (max. 500 Zeichen), den der Entwickler beim Session-Start in einem macOS-Dialog eingeben kann (z. B. 'PROJ-165 Backend'. 20-Sekunden-Timeout — bei Ablauf bleibt das Feld leer. Wird im Admin-Dashboard als Kurztext angezeigt und kann dort vom Plattform-Admin nachträglich bearbeitet werden, solange die Session nicht abgerechnet ist. Abgerechnete Sessions sind gesperrt (GoBD). Im Kunden-Portal werden Sessions mit Beschreibung als 'Durchgeführte Arbeiten' angezeigt (Datum + Beschreibung), sofern der portal_visible-Toggle aktiv ist. Enthält typischerweise keine personenbezogenen Daten. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung). Aufbewahrung: wie Session (6 Jahre GoBD)
- Lokale Tracking-Dateien: Während einer aktiven Session werden Token-Daten inkrementell in einer lokalen Datei auf der Entwicklermaschine gespeichert (~/.claude/token-tracking/<session_id>.json, < 10 KB). Nach erfolgreichem Upload an die API wird die lokale Datei gelöscht. Die Dateien verlassen die Entwicklermaschine nur via API-Upload
- Authentifizierung: Der API-Upload verwendet ein statisches Bearer-Token (NEULAND_DEV_TOKEN), da die Hook-Scripts keine Browser-Session haben. Der Token wird nie in Logs oder API-Responses angezeigt
- Benachrichtigungen: Bei nicht zugeordneten Sessions (älter als 24 Stunden) werden Plattform-Admins per Inbox-Benachrichtigung informiert (max. 1 Benachrichtigung pro Tag). Enthaltene Daten: Anzahl der nicht zugeordneten Sessions
- Zugriffskontrolle: Die Tabelle development_token_sessions ist durch Row Level Security geschützt — nur Plattform-Admins können Sessions einsehen. Schreibzugriff erfolgt ausschließlich über Admin-API-Routen (Service-Role-Client). Nur Plattform-Admins können das Dashboard einsehen und Workspace-Zuordnungen vornehmen
- Token-basierte Abrechnung: Die Agentur kann Entwicklungs-Sessions als Rechnungspositionen abrechnen. Dazu werden aggregierte Token-Verbrauchsdaten (aufgeschlüsselt nach KI-Modell) einem Rechnungsbeleg zugeordnet. Ein konfigurierbarer Aufschlagsfaktor (Standard: 3×) und optional modell-spezifische Aufschläge werden in den Workspace-Einstellungen gespeichert (token_billing_settings). Zuordnungen von Sessions zu Rechnungspositionen sind GoBD-konform unveränderbar (token_billing_assignments, Aufbewahrung: 10 Jahre gemäß §147 AO). Doppelabrechnung wird durch einen UNIQUE-Constraint auf Datenbankebene verhindert
- Kunden-Portal-Transparenz: Die Agentur kann die Token-Kosten-Übersicht für Kunden im Portal sichtbar schalten (portal_visible-Toggle). Kunden sehen dann aggregierte Kosten pro Zeitraum und Modell — keine einzelnen Sessions, keine Entwickler-E-Mail-Adressen. Die Sichtbarkeit kann jederzeit deaktiviert werden
In-App Dev Console & Developer-Hub (PROJ-313 + PROJ-360 + PROJ-361 + PROJ-362 + PROJ-637 + PROJ-806)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an der effizienten Fehlerbehebung und Feature-Umsetzung durch delegierte Entwicklungs-Sessions)
- Dev-Session-Metadaten (Tabelle dev_sessions): Session-ID, Workspace-ID, Starter (User-ID), Status (queued/running/waiting_input/deploying/completed/failed/cancelled), aktueller Skill, Commit-Hash, Fehlermeldung, Zeitstempel. Polymorphe Quellen-Verknüpfung (source_type + source_id): 'bug_report', 'feature_request' oder 'skill_session' (PROJ-361, in der ursprünglichen Fassung ohne source_id; seit PROJ-1426/PROJ-1460 setzen die automatisch gestartete Merge-Konflikt-Lösungs- bzw. CI-Fehlschlag-Bugfix-Session zusätzlich source_id auf die referenzierte github_pr_ci_checks.id — rein technische Verknüpfung zur PR-Check-Zeile, kein Personenbezug); seit PROJ-1426 zusätzlich 'post_merge_automation' (automatisch nach einem Dev-Inbox-Merge angelegte Monitoring+Retro-Sitzung, ohne source_id, briefing enthält nur PR-Nummer/PROJ-ID/Skill-Anweisungstext — keine Endkunden- oder sonstigen Personendaten); seit PROJ-1450 zusätzlich 'contao_ssh_access' (Ein-Klick-Ghostty-Session mit Claude-Code-Kontext beim SSH-Zugriff auf eine Kundensite, source_id referenziert contao_ssh_grants.id; briefing enthält Site-URL/Environment/Contao-/PHP-Version sowie SSH-Verbindungsdaten Host/Port/Subuser — keine privaten Schlüssel/Secrets); seit PROJ-1743 zusätzlich 'server_admin_access' (Ad-hoc-Ghostty-Session zu einer freigegebenen Server-Advisor-Empfehlung mit Admin-SSH-Zugriff auf Server-Ebene, source_id referenziert server_advisor_findings.id; briefing enthält Server-Alias, Titel/Begründung/Auswirkung der Empfehlung sowie die SSH-Verbindungsdaten Host/Port/Admin-User — keine privaten Schlüssel/Secrets; ohne Git-/PR-Bezug). Zugriffskontrolle für diese beiden source_type-Werte per RLS auf admin/manager/is_developer sowie den Session-Eigentümer (started_by) eingeschränkt (PROJ-1450-DSFA F-1), abweichend von der sonst workspace-weiten Sichtbarkeit für alle anderen source_type-Werte. Aufbewahrung: 30 Tage, danach automatische Löschung (bestehender PROJ-313 Cleanup-Cron)
- Session-Nachrichten (Tabelle dev_session_messages): Chronologischer Chat-Verlauf pro Session. Rollen: system (Kontext-Briefing), claude (KI-Antworten), user (Nutzer-Replies auf Rückfragen). Inhalte können personenbeziehbar sein, da das Kontext-Briefing den Originaltext von Bug Reports (Fehlermeldung, Stack Trace, Seiten-URL) oder Feature-Wünschen (Titel, Beschreibung) enthält. Diese Daten werden nicht dupliziert, sondern referenzieren die bereits in bug_reports/feature_request_submissions gespeicherten Inhalte. Aufbewahrung: wie dev_sessions
- Skill-Sessions (PROJ-361): Manuell gestartete Dev-Sessions, bei denen der Developer einen Skill (z.B. /requirements, /architecture, /backend, /frontend, /bugfix, /qa, /dsgvo, /security, /deploy, /retro, /audit, /simplify) auswählt und ein Freitext-Briefing (max. 2.000 Zeichen) eingibt. Gespeichert werden: skill_key (Skill-Name), briefing (Freitext, vom Developer frei eingegeben — kann potentiell personenbezogene Daten enthalten, z.B. Kundennamen, interne Projekthinweise), proj_id_context (optional, PROJ-ID als Scope-Hinweis), changed_files ('git show --stat HEAD'-Output nach Commit), auto_push (Boolean, für Skill-Sessions immer false → kein automatisches Deployment). Aufbewahrung: 30 Tage, danach automatische Löschung
- Bridge-Architektur: Die Dev-Session-Engine wird lokal auf der Entwicklermaschine via Claude Code Agent ausgeführt. Eine Bridge-Registration (bridge_registrations) dokumentiert den Heartbeat-Status. Keine Cloud-Verarbeitung außerhalb der bestehenden Anthropic-Auftragsverarbeitung (siehe Auftragsverarbeiter-Tabelle). Die Bridge pollt neue Sessions und schreibt Nachrichten zurück — sie persistiert keine Daten auf der Entwicklermaschine
- Zugriffskontrolle (PROJ-360, erweitert PROJ-1360): Der Developer-Hub /{slug}/entwicklung ist für Workspace-Mitglieder mit Rolle admin/manager, dem is_developer-Flag, ODER einer Abteilungs-Freigabe des Moduls „Entwicklung“ (department_modules, vom Workspace-Admin je Abteilung vergeben) zugänglich. Die is_developer-Berechtigung wird workspace-spezifisch pro Mitglied vergeben und vom Workspace-Admin im Team-Sheet aktiviert. Alle API-Routen unter /api/entwicklung/* validieren Workspace-Mitgliedschaft zusätzlich zur Rolle/Flag/Abteilungs-Freigabe. Plattform-Admins greifen über /admin/coding-ops (Monitoring-Übersicht) und /{slug}/entwicklung (vollständige Verwaltung) zu
- Workspace-Scope-Isolation: Dev-Sessions, Bug-Reports, Feature-Wünsche und Skill-Sessions sind im Developer-Hub strikt auf den eigenen Workspace begrenzt. Cross-Workspace-Zugriff findet nur im Plattform-Admin-Bereich statt. Die Bridge-Session ist plattformweit eindeutig (max. 1 gleichzeitig aktive Session), damit das lokale Claude Code nicht parallel mehrere Aufträge erhält
- Kontext-Briefing-Erstellung: Beim Session-Start aus einem Bug Report wird ein System-Briefing erzeugt, das die Fehlermeldung, Seite, Severity, KI-Lösungsvorschlag und (optional, max. 500 Zeichen) den Stack Trace enthält. Beim Start aus einem Feature-Wunsch enthält das Briefing Titel, Kategorie und Beschreibung. Bei Skill-Sessions (PROJ-361) enthält das Briefing den vom Developer frei eingegebenen Text (max. 2.000 Zeichen) sowie optional einen PROJ-ID-Kontext. Das Briefing wird als erste System-Nachricht in dev_session_messages gespeichert
- Bidirektionaler Chat: Wenn Claude Code während der Session-Ausführung eine Rückfrage stellt (AskUserQuestion), wechselt die Session in den Status waiting_input. Der Session-Starter erhält eine Inbox-Notification (Typ dev_session_awaiting_input) und kann über die API-Route POST /api/entwicklung/dev-sessions/[id]/reply antworten. Die Antwort wird als user-Nachricht gespeichert und die Session läuft weiter. Timeout: Bug-Fix-Sessions pausieren nach 10 Minuten ohne Antwort, Skill-Sessions nach 30 Minuten (PROJ-361)
- EU AI Act-Kennzeichnung (Art. 50): Claude Code wird im Chat-Panel durch einen expliziten Avatar und den Rollenwert 'claude' als KI-System gekennzeichnet. Es werden keine automatisierten Entscheidungen über natürliche Personen getroffen — alle Code-Änderungen werden durch den Developer bzw. Workspace-Admin über den Dev-Session-Flow ausgelöst und durch Commit/Push freigegeben. Bei Skill-Sessions (PROJ-361) erfolgt kein automatisches Deployment — nur ein lokaler Commit; Push und Deploy liegen ausschließlich beim Developer
- Keine neuen Auftragsverarbeiter durch PROJ-360/PROJ-361: Die KI-Verarbeitung der Sessions durch Anthropic Claude ist bereits über den bestehenden Anthropic-PBC-Eintrag in der Auftragsverarbeiter-Tabelle abgedeckt. Die Bridge läuft ausschließlich lokal auf der Entwicklermaschine
- DSGVO-Datenexport (Art. 15/20): Dev Sessions (inklusive aller PROJ-361-Felder: skill_key, briefing, proj_id_context, changed_files, auto_push), Session-Nachrichten und das is_developer-Flag sind im Workspace-Datenexport (/api/workspaces/data-export) enthalten. Bei User-Löschung werden Sessions des Starters via CASCADE entfernt, das is_developer-Flag wird mit dem workspace_members-Datensatz gelöscht
- Benachrichtigungen (dev_session_awaiting_input): Der Benachrichtigungs-Inhalt enthält die Session-ID, einen kurzen Quell-Titel und die verbleibende Timeout-Zeit — keine Originaltexte aus dem Bug Report oder Feature-Wunsch. Bei Skill-Sessions wird zusätzlich der Skill-Name ('/requirements' etc.) als sprechender Kontext im Nachrichtentext genutzt. Interne Metadata-Keys (source_title, remaining_minutes, session_id, skill) werden in der Inbox nicht als Rohdaten angezeigt
- Bild-Anhänge in Sessions (PROJ-362): Screenshots und Bilder (PNG, JPEG, WebP) können als Anhänge in Briefings und Chat-Nachrichten hochgeladen werden. Max. 5 Bilder pro Nachricht, max. 10 MB pro Bild. Gespeichert im Supabase Storage Bucket 'dev-session-attachments' mit Pfad {workspace_id}/{session_id}/{uuid}.{ext}. Metadaten (Dateipfad, Dateiname, Dateigröße, MIME-Typ) werden als JSONB in dev_session_messages.attachments gespeichert. Zugriffskontrolle: Storage-RLS-Policies beschränken den Zugriff auf Workspace-Mitglieder mit Developer-Berechtigung (is_developer oder Rolle admin/manager), Folder-Scoping auf eigene workspace_id. Upload-Route validiert Dateiinhalt per Magic-Byte-Check (nicht nur MIME-Header). Bilder werden über die Bridge an Claude Code zur multimodalen Verarbeitung weitergeleitet (signierte URLs mit 1 Stunde Gültigkeit). Aufbewahrung: 30 Tage, danach automatische Löschung der Storage-Dateien via Erweiterung des Tracking-Cleanup-Crons. DSGVO-Datenexport: Anhang-Metadaten sind im Workspace-Datenexport über dev_session_messages.attachments enthalten
- Lokal-Worker-Pfad (PROJ-637, dev_sessions.execution_target='local'): Erweitert die bestehende Dev-Session-Engine um einen alternativen Ausführungs-Pfad direkt auf dem Arbeits-Laptop des Developers (statt der dedizierten Mac-Mini-Bridge). Pro dev_session werden zwei neue Felder gespeichert: execution_target ('bridge'|'local') und requested_from (Audit-Trail 'web'|'macos'|'ios'|'autonomous') — keine zusätzlichen personenbezogenen Inhalte. Für Lokal-Worker wird zusätzlich pro registriertem Mac eine Zeile in der Tabelle local_worker_registrations angelegt: device_name (frei wählbarer Bezeichner wie 'MacBook Pro von Marcel' — kann personenbeziehbar sein), user_id (FK auth.users, ON DELETE CASCADE), workspace_id (FK workspaces, ON DELETE CASCADE), secret_hash (SHA-256 des Bearer-Worker-Tokens — kein Klartext, nicht reversibel), last_heartbeat_at, is_online, created_at. Aufbewahrung: Solange der Worker registriert ist; bei User- oder Workspace-Löschung CASCADE. Zugriffskontrolle: RLS-Policy 'local_worker_registrations_authenticated_select' beschränkt Lesezugriff auf eigene Worker (user_id = auth.uid()), service_role bleibt unbeschränkt. RLS-Policy 'dev_sessions_authenticated_select' erlaubt aktiven Workspace-Members Lesezugriff auf dev_sessions ihres Workspaces (workspace_members.is_active = true) — notwendig für die Realtime-Subscribe der macOS-/iOS-Apps. Schreiboperationen weiterhin nur über Service-Role-API-Routen. Keine neuen Auftragsverarbeiter: Der Lokal-Worker führt Claude Code lokal aus, exakt wie die Bridge. Anthropic bleibt bestehender Auftragsverarbeiter. DSGVO-Datenexport: dev_sessions inkl. execution_target und requested_from sowie local_worker_registrations sind im Workspace-Datenexport enthalten (secret_hash wird NICHT exportiert — Security). PROJ-1430 (Mehrrechner-Betrieb): dev_sessions.assigned_worker_id (UUID-FK auf local_worker_registrations, nullable, ON DELETE SET NULL) speichert, welchem registrierten Rechner eine lokal auszuführende Session zugewiesen ist. Die Zuweisung wird serverseitig aus dem Worker-Token abgeleitet (SHA-256-Hash-Lookup), nie aus Client-Angaben. Indirekt personenbeziehbar nur über den bereits erfassten Gerätenamen der referenzierten Registrierung — keine neuen Inhaltsdaten, kein neuer Auftragsverarbeiter. Im Workspace-Datenexport enthalten; bei Löschung der Rechner-Registrierung wird das Feld automatisch geleert (SET NULL)
- Initial-Anhang-Pipeline für Lokal-Sessions (PROJ-806): Wenn ein Developer im macOS-/iOS-App-Bereich 'Entwicklung' eine Lokal-Session aus einem Bug-Report oder einem Feedback-Widget-Eintrag startet, werden die ursprünglich vom Reporter angehängten Dateien (Screenshot aus bug_reports.screenshot_path, PROJ-1520: zusätzliche Anhänge — Bilder/PDF/Text — aus bug_report_attachments, Screenshot/Screen-Recording/generische Datei aus feedback_submissions.screenshot_path/video_path/attachment_path) VOR dem Claude-Code-Start vom nw-launcher (Bash-Script in scripts/worker/nw-launcher + Node-CLI scripts/worker/nw) per signierter Storage-URL (5 Minuten TTL) auf den Mac des Developers heruntergeladen nach ~/.neuland/dev-sessions/{session_id}/attachments/{kind}-{shortid}-{name}.{ext} mit Datei-Berechtigung 0600 und Ordner-Berechtigung 0700. Die lokalen Pfade werden in der initialen System-Nachricht der dev_session als Markdown-Block referenziert (ersetzt {{ATTACHMENTS_BLOCK}}-Platzhalter), damit Claude die Bilder direkt multimodal mit dem Read-Tool öffnen kann. Die JSONB-Spalte dev_session_messages.attachments wird pro Item um die Felder 'kind' (screenshot|video|attachment) und 'bucket' (Original-Bucket bug-report-screenshots / feedback-screenshots / feedback-recordings / feedback-attachments) erweitert — kompatibel zum bestehenden PROJ-362-Item-Schema. Die Original-Dateien verbleiben in ihrem ursprünglichen Storage-Bucket (kein Datenkopier-Vorgang). Feature_request_submissions hat strukturell keine Anhang-Spalten und ist daher von dieser Pipeline nicht betroffen. Keine neuen Auftragsverarbeiter: Lokale Datei-Verarbeitung auf dem Developer-Mac + bestehende Anthropic-Verarbeitung. Aufbewahrung lokaler tmp-Dateien: 7 Tage automatischer Cleanup beim nächsten nw-launcher-Lauf (mtime-basiert, kein separater LaunchAgent). Falls eine Session länger als 7 Tage offen ist und der Cleanup die Dateien entfernt: Re-Open der Session triggert den Download-Code-Pfad erneut (idempotent). Storage-Origin bleibt primäre Quelle — wenn der Reporter seine Original-Datei aus dem Storage löscht (DSGVO Art. 17), kann der Re-Download nicht mehr stattfinden; bereits heruntergeladene tmp-Dateien auf Dev-Macs werden NICHT aktiv gelöscht (akzeptables Risiko durch 7-Tage-Fenster). DSGVO-Datenexport: Die Anhang-Metadaten sind im Workspace-Datenexport bereits über dev_session_messages.attachments enthalten (PROJ-362-Erweiterung). Die lokalen Mac-tmp-Dateien sind nicht Teil des serverseitigen Datenexports, da sie auf dem Endgerät des Developers liegen
- Automatische Projekt-Zuordnung und Auto-Beschreibung (PROJ-1164): Eine neue Tabelle dev_session_project_rules speichert konfigurierbare Zuordnungsregeln (Arbeitsverzeichnis-Muster zu Projekt-ID, Priorität, aktiv-Flag) — keine personenbezogenen Daten; RLS aktiviert ohne Policy, Zugriff nur über Service-Role bzw. Plattform-Admin. Beim Session-Upload wird die Session anhand des cwd-Musters automatisch genau einem Projekt zugeordnet (bei keinem oder mehrdeutigem Treffer bleibt sie fail-closed offen), optional über einen Projekt-Picker im Session-Start-Hook. Eine neue Spalte development_token_sessions.reason_is_manual schützt manuell gesetzte Beschreibungen vor Überschreiben. Die Session-Beschreibung (reason) kann jetzt hook-seitig automatisch aus den Git-Commit-Betreffzeilen des Session-Zeitfensters erzeugt werden (max. 500 Zeichen). Diese Betreffzeilen können interne Projekt- oder Feature-Bezüge enthalten, jedoch keine End-Nutzer-PII; sie bleiben wie alle Session-Daten durch RLS Plattform-Admin-intern und werden nicht an Dritte übermittelt. Das Auslesen der Commits erfolgt ausschließlich lokal auf der Entwicklermaschine — keine neuen Auftragsverarbeiter. DSGVO-Datenexport: dev_session_project_rules ist reine Admin-Konfiguration ohne personenbezogene Daten
- Owner-Anzeige pro Session (PROJ-1479): Die API-Antworten von GET /api/entwicklung/dev-sessions (Liste + Detail) und GET /api/admin/github-pr-checks lösen das bereits erfasste dev_sessions.started_by (User-ID) jetzt zusätzlich zu einem Anzeigenamen auf (profiles.display_name, derselbe Batch-Lookup-Mechanismus wie an anderen Stellen der App) — keine neue Datenkategorie, nur eine für Workspace-Mitglieder mit Developer-Zugriff bereits sichtbare Kennung wird lesbar dargestellt. Bei requested_from='autonomous' (system-/automatisch-gestartete Sessions) wird zusätzlich, sofern über die bestehende proj_id_context-Verknüpfung auflösbar, der Anzeigename der Person angezeigt, die zuletzt inhaltlich an derselben PROJ-ID gearbeitet hat (dieselbe Personengruppe, keine neue Empfängerkategorie). Keine Ausweitung der bestehenden Workspace-Scope-Isolation oder RLS — die Owner-Felder werden ausschließlich für ohnehin schon zugriffsberechtigte Workspace-Mitglieder berechnet. Keine neuen Auftragsverarbeiter, keine neue Speicherung (reine Response-Anreicherung zur Laufzeit, nichts wird persistiert). DSGVO-Datenexport: unverändert, da started_by bereits Teil des Workspace-Datenexports ist (siehe oben) und der Anzeigename kein zusätzliches gespeichertes Datum ist
- Cross-User-Duplikat-Schutz + Rechner-NULL-Fallback-Notification (PROJ-1846): Der bestehende Duplikat-Check für lokale Feature-Wunsch-/Skill-Sessions (execution_target='local', source_id gesetzt) wurde von (started_by, source_id) auf source_id allein erweitert — eine aktive lokale Session blockiert jetzt jeden weiteren Start-Versuch für dieselbe Quelle, unabhängig vom auslösenden User. Die 409-Fehlerantwort reichert den bereits bestehenden Owner-Namen (PROJ-1479) sowie den Rechner-Besitzer-Namen (assigned_worker_id → local_worker_registrations → profiles.display_name, bereits seit PROJ-1642 an anderer Stelle berechnet) im Fehlertext an — keine neue Datenkategorie, nur eine bereits für Workspace-Mitglieder mit Developer-Zugriff sichtbare Kennung wird zusätzlich im Fehlertext dargestellt. Race-Sicherheit: neuer partieller UNIQUE-Index idx_dev_sessions_active_local_source auf (workspace_id, source_id) — reine Datenbank-Struktur, kein Personenbezug. Neuer Notification-Typ dev_session_worker_unresolved: Kann für eine automatisch (system-)ausgelöste Monitoring/Retro-Session (post_merge_automation) kein zugehöriger Rechner ermittelt werden, erhält ausschließlich Marcel (Plattform-Betreiber, identisches Empfänger-Muster wie github_pr_check_failed/PROJ-1418) eine Benachrichtigung mit PROJ-ID und PR-Nummer — der bestehende Broadcast-Fallback (jeder online registrierte Rechner darf die Session claimen) bleibt unverändert als Sicherheitsnetz bestehen. Keine neuen Auftragsverarbeiter, keine neue Speicherung über die bereits dokumentierten notifications- und dev_sessions-Tabellen hinaus. DSGVO-Datenexport: unverändert, da alle beteiligten Felder (started_by, assigned_worker_id, notifications) bereits Teil des Workspace- bzw. Admin-Datenexports sind
- Verantwortlichkeit pro Vision (PROJ-2004): Die mit PROJ-1753 eingeführten Visionen (dev_roadmap_items, item_type='vision') bekommen ein Feld owner_user_id (FK auth.users, nur bei Visionen befüllt) — die für das Thema verantwortliche Person, analog zum bereits dokumentierten Owner-Muster aus PROJ-1479 oben, hier aber als persistiertes Zuordnungsfeld statt einer reinen Laufzeit-Anreicherung. Nur aktive Workspace-Mitglieder wählbar (Query-Zeit-Prüfung gegen workspace_members.is_active), Pflichtfeld nur bei Neuanlage einer Vision — bestehende Visionen ohne Owner bleiben gültig. Zusätzlich bekommen bug_reports, feature_request_submissions, feature_briefs und feedback_submissions je ein Feld roadmap_item_id (FK dev_roadmap_items, ON DELETE SET NULL), über das ein Bug-Report/Feature-Wunsch/Briefing manuell genau einer Vision zugeordnet werden kann (Schreibzugriff nur admin/manager). Bei Zuordnung erhält die verantwortliche Person eine In-App-Benachrichtigung (Notification-Typ dev_roadmap_item_assigned) mit Deep-Link zum zugeordneten Item. Keine neuen Auftragsverarbeiter, keine neue PII-Kategorie — owner_user_id/roadmap_item_id folgen demselben Referenz-Muster wie das bereits dokumentierte created_by/started_by. DSGVO-Datenexport: roadmap_item_id ist in den bereits exportierten Tabellen bug_reports/feature_request_submissions/feature_briefs proaktiv mit aufgenommen worden (R-1774); dev_roadmap_items war seit PROJ-1753 bereits im Workspace-Datenexport enthalten (F-1 damals behoben), owner_user_id wurde im Zuge dieser DSGVO-Prüfung ergänzt (R-535-Fund, direkt behoben). PROJ-2058 (12.08.2026): Das Owner-Feld owner_user_id wird jetzt auch auf Arbeitspaketen und Paket-Parents (item_type='dev_feature') geführt — der DB-CHECK dev_roadmap_items_owner_only_vision wurde dazu von 'nur vision' auf 'vision oder dev_feature' gelockert. Es bleibt dieselbe interne Personengruppe (die für ein Feature-Paket verantwortliche Person) und dasselbe Referenz-Muster wie created_by/started_by — keine neue Datenkategorie, kein neuer Empfänger. Ein einmaliger Backfill leitete den Owner für Bestands-Features aus dev_sessions.started_by (Fallback created_by) ab; nicht ableitbare Features bleiben ohne Owner. owner_user_id ist über den bereits bestehenden dev_roadmap_items-Datenexport abgedeckt
- macOS-Ziele-API (PROJ-1951, AP7 von PROJ-1944): Zwei neue Endpunkte GET /api/admin/dev-goals und POST /api/admin/dev-goals/:package_proj_id/start-session lesen ausschließlich bereits erfasste dev_roadmap_items-Metadaten (proj_id, title, status, parent_id, feature_kind — reine Feature-/Prozess-Verwaltungsdaten, kein Personenbezug) und leiten daraus Fortschritt (%) sowie eine deterministische Vorschau-Adresse ab; keine neue Datenkategorie. dev_sessions bekommt einen neuen source_type-Wert 'roadmap_package' (Start über die macOS-App für ein Arbeitspaket, source_id referenziert das gestartete dev_roadmap_items-Kind, briefing enthält nur PROJ-ID/Titel/Basis-Branch-Text — keine Kundendaten) sowie eine neue nullable Spalte base_branch (text, z.B. 'integration/PROJ-1944' — rein technischer Ziel-Branch-Name, kein Personenbezug). Zugriffskontrolle identisch zu bestehenden Session-Start-Routen: getCompanionAuth + Admin/Manager-Rolle bzw. Plattform-Admin (Positivliste, R-1939). DSGVO-Datenexport: source_type='roadmap_package' ist über die bestehende generische source_type-Spalte bereits mit erfasst; base_branch fehlt aktuell in der Export-Allowlist (Finding F-1 im DSGVO-Bericht PROJ-1951, Niedrig-Priorität, kein PII-Feld, kein Deploy-Blocker). Keine neuen Auftragsverarbeiter. PROJ-2058 (12.08.2026): Der neue Kind-Status 'integrated' (fertig auf dem Sammel-Branch, noch nicht auf main) und eine nullable Spalte integration_branch (technischer Collector-Branch-Name, kein Personenbezug) wurden ergänzt. Die dev-goals-Antwort löst nun zusätzlich den owner_user_id von Ziel UND Arbeitspaketen zu Anzeigename/Avatar/Aktiv-Status auf (profiles + workspace_members, derselbe Batch-Lookup wie PROJ-1479/PROJ-2004) und liefert integration_branch samt abgeleiteter GitHub-/Preview-URL sowie den rohen lifecycle_status je Arbeitspaket. Die Owner-Auflösung ist eine bereits für zugriffsberechtigte Workspace-Mitglieder sichtbare interne Kennung — kein neuer Empfänger, keine zusätzlich gespeicherte Datenkategorie (reine Laufzeit-Anreicherung); Scope-Isolation und Aktiv-Check unverändert
App-Shop-System (eCommerce-Modul)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung für Shop-Betreiber), Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse für Shop-Verwaltung)
- Shop-Verbindungs-Credentials: Supabase-URL, Anon Key und Service Role Key zur externen Shop-Datenbank des Workspace-Operators. Werden AES-256-GCM-verschlüsselt in der NEULAND. OS-Datenbank gespeichert (Tabelle shop_connections). Der Klartext der Keys ist nur serverseitig im Rahmen von API-Anfragen zugänglich
- Webhook-Secret: Ein HMAC-SHA256-Schlüssel zur Validierung eingehender Webhook-Events aus dem externen Shop. Ebenfalls verschlüsselt gespeichert
- Shop-Kundendaten (in externer Supabase): Name, E-Mail-Adresse, Telefonnummer, Lieferadressen, Bestellhistorie, Zahlungsstatus. Diese Daten werden NICHT in der NEULAND. OS-Datenbank gespeichert — sie verbleiben ausschließlich in der vom Workspace-Operator betriebenen externen Supabase-Instanz. NEULAND. OS fungiert als Verwaltungsoberfläche (Proxy-Zugriff via API-Routen)
- Shop-Konfiguration (in externer Supabase): Shop-Name, Domain, Theme-Einstellungen, Rechnungseinstellungen, Stripe Publishable Key (kein Secret Key in NEULAND. OS). Der Stripe Secret Key verbleibt ausschließlich in der externen Shop-Datenbank
- Verarbeitungszweck: Die verschlüsselten Credentials ermöglichen es NEULAND. OS, im Auftrag des Workspace-Operators lesend und schreibend auf die externe Shop-Datenbank zuzugreifen (Bestellverwaltung, Produktpflege, Kundenverwaltung, Statistiken)
- Shop-Belegsystem — Angebote, Rechnungen, Gutschriften (in externer Supabase, PROJ-197): Belegdaten (Positionen, Beträge, Steuersätze, Belegnummern, Status), Kunden-Snapshot (Name, Firma, Anschrift zum Zeitpunkt der Belegstellung — unveränderbar für GoBD-Compliance), Absender-Snapshot (Firmenname, Anschrift, USt-IdNr des Shop-Betreibers). Bei Digital Signing von Angeboten: Name des Unterzeichners (signing_name), SHA-256-Hash der IP-Adresse mit Salt (signing_ip_hash — pseudonymisiert, kein Rückschluss auf Klartext-IP möglich), Zeitstempel der Unterzeichnung (signed_at), User-Agent des Browsers. Der IP-Hash wird nach 90 Tagen automatisch gelöscht (DSGVO-Cleanup-Cron). Signing-Tokens werden nach 30 Tagen bei abgelaufenen/stornierten Angeboten gelöscht. Aufbewahrungsfristen: Rechnungen 8 Jahre (§147 AO), Angebote und Gutschriften 6 Jahre (§147 AO, verkürzt seit 01.01.2025 durch BEG IV). E-Mail-Versand von Belegen erfolgt über Resend — Empfänger-E-Mail und Belegdaten werden dabei an Resend als Auftragsverarbeiter übermittelt
- Shop-E-Mail-Vorlagen (in externer Supabase): Konfigurierbare E-Mail-Templates pro Belegtyp (Angebot, Rechnung, Gutschrift, Mahnung, Signing-Bestätigung) und Kundenbindungstyp (Bewertungsanfrage, Erinnerung, Geburtstag, Inaktivitäts-E-Mail, Erste-Bestellung-Danke) mit Betreff und HTML-Body. Enthalten Platzhalter ({{kunde}}, {{belegnummer}}, {{betrag}}, {{produktname}}, {{bewertungslink}}), die beim Versand durch Belegdaten bzw. Kundendaten ersetzt werden. Templates enthalten keine personenbezogenen Daten — diese werden erst beim Versand eingefügt
- Kundenbewertungen (in externer Supabase, PROJ-198): Produktbewertungen enthalten Sternebewertung (1–5), optionalen Titel/Text, Pro-/Contra-Punkte, Verifikationsstatus (verifizierter Kauf), Moderationsstatus und optionale Admin-Antwort. Verknüpft mit Kunden-ID und Produkt-ID. Bei Löschung des Kunden (DSGVO Art. 17) wird die Kunden-ID auf NULL gesetzt — die Bewertung bleibt anonym bestehen. Kunden können ihre eigene Bewertung über den Bewertungs-Token selbstständig löschen (Hard Delete via DELETE /api/shop/public/reviews/[token])
- Bewertungsanfrage-Tokens (in externer Supabase): UUID-basierte Einmal-Tokens zur öffentlichen Bewertungsabgabe ohne Login. Enthalten Referenzen auf Kunde, Bestellung und Produkt. Abgelaufene und abgeschlossene Tokens werden durch einen täglichen Cleanup-Cron automatisch gelöscht (30 Tage Aufbewahrung nach Abschluss, sofortige Löschung nach Ablauf)
- Kundenbindungs-Events (in externer Supabase): Protokolliert gesendete Kundenbindungs-E-Mails (Typ, Zeitpunkt, Kunden-Referenz). Dient zur Duplikat-Vermeidung und Häufigkeitskontrolle. Wird bei Löschung des Kunden automatisch gelöscht (CASCADE)
- Shop-CRM & Kundenberatung (in externer Supabase, PROJ-195): Erweiterte Kundenstammdaten (Kundentyp B2B/B2C/Prospect, Firmenname, USt-IdNr, Kundennummer, Freitext-Tags, Kurznotizen, zugeordneter Berater, Lifetime Value). B2B-Kontaktpersonen (Name, Rolle/Position, E-Mail, Telefon) pro Kunde. Aktivitäts-Timeline (chronologischer Log aller Kundeninteraktionen: Notizen, E-Mails, Anrufe, Meetings, Angebotsversand, Bestellungen, System-Events — Betreff, Inhalt, Ersteller, Zeitstempel). Support-Tickets (Betreff, Status, Priorität, Kategorie, zugeordneter Berater) mit Thread-basierten Ticket-Nachrichten (Absender-Typ Agent/Kunde/System, Nachrichtentext, Anhänge). Anruf-Protokolle (Richtung ein/ausgehend, Telefonnummer, Dauer, optionale Aufnahme-URL nur mit DSGVO-Einwilligung via IVR-Consent PROJ-120, optionales Transkript, Gesprächsnotizen, Berater-ID). Anruf-Aufnahmen werden nach 90 Tagen automatisch gelöscht (Cleanup-Cron). CRM-Konfiguration (eingehende E-Mail-Adresse, Standard-Berater, Auto-Ticket-Erstellung, Resend Inbound Webhook-Secret AES-256-GCM-verschlüsselt)
- Eingehende Shop-E-Mails (in externer Supabase, PROJ-195): E-Mails an eine konfigurierbare Adresse (z. B. beratung@shop.de) werden via Resend Inbound Webhook empfangen und in der Shop-Datenbank gespeichert. Gespeicherte Daten: Absender-E-Mail und Name, Empfänger-E-Mail, Betreff, Nur-Text-Body (HTML wird vor Speicherung via stripHtmlTags() bereinigt — kein Roh-HTML gespeichert), Anhänge (JSONB-Metadaten), Resend Message-ID, Zuordnungsstatus (neu/zugeordnet/archiviert). Automatische Kundenzuordnung via Absender-E-Mail-Matching gegen Kunden- und Kontaktpersonen-E-Mails. Nicht zuordenbare E-Mails landen in einer Unzugeordnet-Inbox zur manuellen Zuordnung durch Berater
- Retouren-System (in externer Supabase, PROJ-196): Retourendaten umfassen Retourennummer, Bestellreferenz, Kundenreferenz, Retourengrund (Auswahl + optionaler Freitext max. 2.000 Zeichen), Status (7-stufige State Machine: eingereicht → genehmigt/abgelehnt → Rücksendung → erhalten → erstattet → abgeschlossen), Erstattungsbetrag/-methode, Tracking-Nummer, Fotos der Retoure (im privaten Storage-Bucket 'return-photos', max. 5 MB, nur image/jpeg/png/webp). Retouren-Positionen (Artikel, Menge, Artikelzustand). Status-Historie (Von-/Bis-Status, Bearbeiter, optionaler Kommentar). Retouren-Nachrichten (Kommunikation zwischen Berater und Kunde: Absendertyp, Nachrichtentext). Retouren-Policies (Konfiguration: Rückgabefrist, Gründe mit Foto-Pflicht und Auto-Approval-Flag, Versandhinweise). Alle Retourendaten verbleiben ausschließlich in der externen Shop-Supabase des Workspace-Operators
- Shop-E-Mail-Infrastruktur (in externer Supabase, PROJ-385): Pro Shop konfigurierbare Absender-Daten (shop_config.email_from_address, email_from_name, email_reply_to) und ein AES-256-GCM-verschlüsselter Resend API-Key (shop_config.resend_api_key_encrypted) ermöglichen workspace-spezifischen E-Mail-Versand mit eigener Absender-Identität statt generischer NEULAND.-Absender-Adresse. Versendet werden Transactional-E-Mails (Bestellbestätigung, Versandbenachrichtigung, Storno-Bestätigung, Retoure-eingereicht/-genehmigt/-abgelehnt/-erstattet, Angebot angenommen — Shopbetreiber-Benachrichtigung, Konto-Löschungsbestätigung, Willkommen, Passwort-Reset — Rechtsgrundlage Art. 6 Abs. 1 lit. b DSGVO, Vertragserfüllung) sowie Bewertungsanfragen (Art. 6 Abs. 1 lit. f DSGVO, berechtigtes Interesse an Produktfeedback — nur bei customers.marketing_opt_out=false und customers.review_opt_out=false, mit Abmeldelink in jeder Marketing-E-Mail). Übermittelte Daten an Resend: Empfänger-E-Mail-Adresse, Absender (shop_config.email_from_address), Betreff, HTML- und Text-Body mit eingesetzten Platzhaltern (z.B. Name, Bestellnummer, Beträge, Tracking-URL). Resend ist US-Auftragsverarbeiter mit Standardvertragsklauseln (SCCs) gemäß EU-Kommissionsbeschluss 2021/914 — siehe Auftragsverarbeiter-Liste
- Shop-E-Mail-Log (shop_email_log in externer Supabase, PROJ-385): Jeder E-Mail-Versand wird anonymisiert protokolliert. Gespeicherte Felder: workspace_id, Template-Typ (z.B. order_confirmation), SHA-256-Hash der Empfänger-E-Mail (to_email_hash — keine Klartext-E-Mail), anonymisierte Vorschau (to_email_preview, Format 'k***@example.com'), Status (sent/failed), Resend-Message-ID, Fehlermeldung (bei Status failed), Zeitstempel. Zweck: Versand-Nachvollziehbarkeit, Retry-Kontrolle, Fehleranalyse. Die Klartext-E-Mail wird NICHT gespeichert (DSGVO Art. 5 Abs. 1 lit. c — Datensparsamkeit). Aufbewahrung: 90 Tage, danach automatischer Hard-Delete durch täglichen Cleanup-Cron (shop-email-log-cleanup)
- Shop E-Mail-Verifikations-Tokens (customer_email_verifications in externer Supabase, PROJ-392): Bei Shop-Kundenregistrierung und E-Mail-Adressänderung wird ein 32-Byte-Zufallstoken erzeugt, SHA-256-gehasht gespeichert und per E-Mail an die zu bestätigende Adresse versandt (Klartext-Token ausschließlich im E-Mail-Link, nie in der DB). Gespeicherte Felder: token_hash (SHA-256-Hex), customer_id, new_email (Ziel-Adresse), purpose (registration/email_change), expires_at (24h TTL), consumed_at (Einlösung), created_at. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Verifikation ist Voraussetzung für Kundenkonto-Aktivierung). Aufbewahrung: Tokens sind 24 Stunden gültig. Unbestätigte Accounts (email_confirmed_at IS NULL) werden 30 Tage nach Registrierung automatisch gelöscht (täglicher Cron unverified-cleanup, mit Reminder-Mail am Tag 25 via unverified-reminder-Cron). Bei Account-Löschung oder Customer-Löschung werden zugehörige Token-Einträge per CASCADE entfernt (Art. 5 Abs. 1 lit. c — Datensparsamkeit). Die Klartext-Token-Werte erscheinen niemals in Logs oder DB-Zeilen. Drei neue E-Mail-Templates (email_verification, email_verification_reminder, email_change_warning) erweitern die PROJ-385-Template-Infrastruktur — gleicher Versand-Flow, gleiche DSGVO-Behandlung (siehe Shop-E-Mail-Log-Eintrag oben)
SSOT-Präsentations-Links (öffentliche Marketing-Präsentation)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Agentur teilt Marketing-Strategie mit Kunden im Rahmen der Dienstleistung)
- Präsentations-Links (ssot_presentation_links): Pro generiertem Link werden gespeichert: UUID v4-Token (öffentlicher Identifikator, 2^122 Möglichkeiten — nicht erratbar), Workspace-ID, Kontakt-ID, ausgewählte Inhaltssektionen (JSONB-Array: z. B. marketing_goals, personas, usps), Datenschnappschuss (data_snapshot JSONB: Marketingziele, Zielgruppen/Personas, USPs, Keywords, Kanalstrategie, Redaktionsplan des aktuellen Monats, Bedarfsgruppen, Kontaktname, Workspace-Name und -Logo), optionaler PIN-Hash (PBKDF2, 100.000 Iterationen, SHA-256, zufälliger 16-Byte-Salt — Klartext-PIN wird nie gespeichert), Ablaufdatum (optional), Aktivierungsstatus, anonymer Aufrufzähler (view_count — keine IP-Speicherung), Ersteller-ID (workspace_member). Aufbewahrung: Bis zur manuellen Löschung durch ein Workspace-Mitglied oder bis zur Löschung des Kontakts (CASCADE) bzw. Workspaces (CASCADE)
- Kontaktname im Snapshot: Der Name des Kunden-Kontakts wird beim Generieren des Links in den Datenschnappschuss aufgenommen und auf der öffentlichen Präsentationsseite als Titel angezeigt. Bei Einzelunternehmern kann dies ein persönlicher Name sein (personenbezogenes Datum). Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO — die Präsentation wird im Rahmen der Agentur-Dienstleistung für den Kunden erstellt
- Öffentliche Präsentationsseite (/ssot/[token]): Die Seite ist ohne Login aufrufbar. Angezeigt werden ausschließlich die im Snapshot gespeicherten Inhaltsdaten sowie — bei aktivierter Sektion 'Wirkungsnachweis' (PROJ-351) — Live-Aggregationen aus bestehenden Datenquellen (Keyword-Anzahl, Bedarfsgruppen-Fortschritt, PageSpeed-Scores, Sichtbarkeitsindex, Redaktionsplan-Einträge) und manuell gepflegte KPI-Ist-Werte (Impressionen, Klicks, Leads, Vertragswerte). Diese Daten enthalten keine personenbezogenen Informationen. noindex-Meta-Tag verhindert Indexierung durch Suchmaschinen. Keine Cookies, kein Tracking
- IP-Adresse (Rate Limiting): Die IP-Adresse von Besuchern der öffentlichen Präsentation wird temporär (< 1 Stunde) in Redis für Rate Limiting verwendet (max. 60 Aufrufe/Minute allgemein, max. 5 PIN-Versuche/Stunde). Die IP wird NICHT in der Datenbank gespeichert. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Missbrauchsschutz)
- DSGVO-Datenexport (Art. 15/20): ssot_presentation_links (Token, Sektionen, Aktivierungsstatus, Ablaufdatum, Aufrufzähler, PIN-Indikator, Erstellungsdatum) sind im Kontakt-Datenexport enthalten. pin_hash wird nicht exportiert
- Marketingziel-Versionshistorie auf dem Public-Link (PROJ-1449): Bei aktivierter Sektion 'Marketingziele' kann pro Ziel ein Änderungsverlauf abgerufen werden (GET /public/:token/goal-history) — Zeitpunkt, geänderte Felder (alt→neu, aus ssot_history previous_data/new_data berechnet), optionale Änderungsbegründung (ssot_history.reason, Freitext max. 1.000 Zeichen, durch Agentur-Mitarbeitende verfasst) sowie der Anzeigename (display_name) der ändernden Person. Der Anzeigename von Agentur-Mitarbeitenden ist damit auf dem token-/PIN-geschützten Public-Link sichtbar (bewusste Entscheidung, dokumentiert in PROJ-1449); User-ID und E-Mail-Adresse werden NICHT ausgeliefert. Die Historie (inkl. reason) ist Teil des Kontakt-Datenexports (ssot_history, ohne user_id). Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Nachvollziehbarkeit der Strategie-Änderungen als Teil der Dienstleistung)
FuE-Präsentations-Links (öffentliche Fördermittel-Dokumentation)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Plattform-Betreiber teilt FuE-Vorhabensbeschreibung mit Fördermittelberater im Rahmen des Förderantrags)
- Präsentations-Links (fue_presentation_links): Pro generiertem Link werden gespeichert: UUID v4-Token (öffentlicher Identifikator, 2^122 Möglichkeiten — nicht erratbar), Datenschnappschuss (data_snapshot JSONB: Projekt-Metadaten inkl. Ansprechpartner-Namen und Berater-Name, Marktsituation, bestehende Tools, technische Defizite, Forschungslücken, Innovationen, Arbeitspakete, Kostenaufstellung), optionaler PIN-Hash (PBKDF2, 100.000 Iterationen, SHA-256, zufälliger 16-Byte-Salt — Klartext-PIN wird nie gespeichert), Ablaufdatum (optional), Aktivierungsstatus, anonymer Aufrufzähler (view_count — keine IP-Speicherung), Ersteller-ID (auth.users, ON DELETE SET NULL). Aufbewahrung: Bis zur manuellen Löschung durch Plattform-Admin
- Personennamen im Snapshot: Die Ansprechpartner-Namen (meta.contacts) und der Berater-Name (meta.consultant) stammen aus statischen TypeScript-Konstanten (fue-vorhabensbeschreibung.ts) und sind öffentlich bekannte Geschäftskontakte (Impressum, Handelsregister). Bei Einzelunternehmern können dies personenbezogene Daten sein. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO — die Dokumentation wird im Rahmen des Förderantrags erstellt
- Öffentliche Präsentationsseite (/foerdermittel/[token]): Die Seite ist ohne Login aufrufbar. Angezeigt werden ausschließlich die im Snapshot gespeicherten Inhaltsdaten (5 Bereiche: Vorschau, Stand der Technik, Innovationen, Arbeitspakete, Kosten). noindex-Meta-Tag verhindert Indexierung durch Suchmaschinen. Keine Cookies, kein Tracking
- IP-Adresse (Rate Limiting): Die IP-Adresse von Besuchern der öffentlichen Präsentation wird temporär (< 1 Stunde) in Redis für Rate Limiting verwendet (max. 60 Aufrufe/Minute allgemein, max. 5 PIN-Versuche/Stunde, max. 1 View-Zählung/Stunde). Die IP wird NICHT in der Datenbank gespeichert. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Missbrauchsschutz)
- PROJ-939 Bank-Investitionsplanung (link_type + bank_config): Zusätzlich zum Förderantrags-Link kann ein Plattform-Admin pro Vorhaben einen Bank-Link erzeugen (link_type = bank_investitionsplanung). Dabei wird ein bank_config-Objekt (JSONB) gespeichert: Eigenmittel, erwartete Förderung, gesuchte Darlehenssumme (geschäftliche Finanzplan-Daten der Agentur selbst — kein personenbezogenes Drittdatum) sowie eine optionale, frei formulierte bank-taugliche Kurzbeschreibung (project_summary). Ein zusätzlicher Personenbezug entsteht hierdurch nicht; etwaige Personennamen stammen weiterhin ausschließlich aus dem data_snapshot (meta.contacts/consultant, siehe oben). Die öffentliche Bank-Seite (/investitionsplanung/[token]) ist ohne Login aufrufbar, zeigt Vorhaben, Investitionsvolumen, Zeit-/Projektplan und Finanzierungsplan, trägt ein noindex-Meta-Tag und nutzt dieselbe PIN-, Ablauf- und Rate-Limit-Mechanik wie der Förder-Link. Keine Cookies, kein Tracking
Erweitertes Kosten-Tracking (API-Kosten)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — transparente Dokumentation externer API-Kosten im Rahmen der Agenturdienstleistung). Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an betrieblicher Kostentransparenz und Abrechnungsfähigkeit)
- API-Kosten-Einträge (api_cost_entries): Jede Nutzung externer Daten-APIs wird als Einzeleintrag gespeichert — Workspace-ID, optionale Kontakt-ID (Kunden-Attribution), Provider-Name (DataForSEO, SerpAPI, ElevenLabs, Deepgram, Google Ads), Feature-Kontext (z. B. 'keyword_enrichment', 'web_search', 'keyword_regional_search_volume'), Einheiten, Stückpreis zum Zeitpunkt des Abrufs (Snapshot-Prinzip), Gesamtkosten (berechnet), Kostenträger (Agentur oder Kunde), optionale Meta-Daten (nur technische IDs wie analysis_id, location_code, location_name — keine personenbezogenen Daten). Aufbewahrung: Unbefristet für GoBD-konforme Kostendokumentation
- Kontakt-Zuordnung: Bei Keyword-Anreicherungen (DataForSEO und Google Ads) wird die contact_id des betreffenden Kunden im Kosten-Eintrag gespeichert, damit die Agentur API-Kosten pro Kunde aufschlüsseln kann. Bei Kontaktlöschung wird die contact_id auf NULL gesetzt (ON DELETE SET NULL) — der Kosten-Eintrag bleibt anonym erhalten
- Preiskonfiguration (api_cost_config): Vom Platform-Admin konfigurierbare Stückpreise pro Provider (z. B. 0,001 € pro Keyword). Keine personenbezogenen Daten — nur Provider-Name, Preis, Beschreibung und Bearbeiter-ID
- Meta-Feld: Enthält ausschließlich technische Referenz-IDs (z. B. analysis_id als UUID). Keine Keyword-Texte, keine E-Mail-Adressen, keine Namen oder andere PII
- PROJ-1601 Rechnungsübernahme + Kostenträger-Klassifizierung: Die 'Kostenträger'-Zuordnung (cost_bearer: Agentur/Kunde) wird seit PROJ-1601 automatisch beim Logging gesetzt (Kunde, sobald eine contact_id vorliegt — sonst Agentur) statt wie zuvor immer 'Agentur'. Zusätzlich können Admin/Manager im Kosten-Log per Mehrfachauswahl bestehende 'Agentur'-Einträge nachträglich manuell als 'Kunde' markieren (neue Route PATCH /api/workspaces/api-cost/mark-billable). Als 'Kunde' markierte, noch nicht abgerechnete Einträge (api_cost_billing_settings-Aufschlag berücksichtigt) können über einen 3-Schritt-Dialog gebündelt als Rechnungsposition (invoice_items, item_type='api_costs') zu einer Entwurfs-Rechnung hinzugefügt werden. Neue Spalte invoiced_in_invoice_id (FK → invoices, ON DELETE SET NULL) markiert den Übernahme-Status — keine neuen personenbezogenen Datenkategorien, nur ein neuer interner Verwendungszweck (Abrechnung) für bereits bestehende, bereits dokumentierte Kostendaten. Die neue invoice_items.api_cost_metadata (JSONB) enthält Zeitraum, Provider-Aufschlüsselung, Aufschlagsfaktor und bei manuellem Override die User-ID der ausführenden Person (override_audit) — analog zum bestehenden token_metadata-Muster bei Entwicklungs-Tokens-Rechnungspositionen; invoice_items ist nicht Teil des Kontakt-Datenexports (Art. 15/20), identisch zum bereits bestehenden token_metadata-Verhalten.
Benachrichtigungs-Schaltzentrale
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Konfiguration der Benachrichtigungskanäle als Bestandteil der Workspace-Verwaltung). Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an personalisierbaren Benachrichtigungseinstellungen für Mitarbeiter)
- Workspace-Benachrichtigungsregeln (workspace_notification_rules): Workspace-spezifische Konfiguration der Benachrichtigungskanäle (Inbox/E-Mail an/aus), Erzwingungsstatus, Verzögerung in Minuten, Bedingungsregeln (JSONB — enthält nur Feldnamen und Wertvergleiche, keine personenbezogenen Daten), Empfänger-Override (Rollen-Bezeichnungen und Gruppen-IDs), E-Mail-Template-Override, Bearbeiter-ID (changed_by). Aufbewahrung: Bis zur Löschung des Workspace (CASCADE)
- Cron-Job-Konfiguration (workspace_cron_configs): Workspace-spezifische Intervalle und Aktivierungsstatus von automatisierten Hintergrundprozessen, letzte Ausführungszeit und -ergebnis. Keine personenbezogenen Daten — reine Prozesskonfiguration. Aufbewahrung: Bis zur Löschung des Workspace (CASCADE)
- Persönliche Benachrichtigungs-Präferenzen (user_notification_preferences): Pro-User-Konfiguration welche Benachrichtigungskanäle (Inbox/E-Mail) für welche Aktionstypen aktiv sind. Enthält: User-ID, Workspace-ID, Aktionsschlüssel, Kanal-Toggles (inbox_enabled, email_enabled). PROJ-508 erweitert um channel_mode (NULL = Standard, oder einer von: inbox, email, push, email_and_push, disabled) für granulare User-Level-Konfiguration pro Aktionstyp. PROJ-1634 erweitert um Typ-Defaults default_category_id (Verweis auf eigene Inbox-Kategorie aus PROJ-1630, ON DELETE SET NULL), default_priority (Niedrig/Normal/Hoch, nullable) und default_pinned (boolean) — rein nutzereigene Konfigurationswerte, kein Personenbezug zu Dritten. PROJ-1632 erweitert um digest_mode (Einzel/Täglich) und digest_time (Uhrzeit) für die Digest-Zustellsteuerung pro Aktionstyp. PROJ-573 erweitert um push_enabled (Push-Kanal als eigener Schalter). PROJ-1756 erweitert um self_triggered_only (NULL = Systemstandard, TRUE = nur bei selbst ausgelösten Vorgängen benachrichtigen); PROJ-1861 macht dieses Feld erstmals auch außerhalb des Einrichtungs-Assistenten änderbar (Regel-Dialog am Inbox-Eintrag) und nimmt push_enabled sowie self_triggered_only in den Datenexport nach Art. 15/20 auf. Aufbewahrung: Bis zur Account-Löschung (CASCADE auf auth.users) oder Workspace-Löschung (CASCADE auf workspaces)
- Digest-Zustellstatus auf Benachrichtigungen (notifications.digest_delivered_at, PROJ-1632): Zeitstempel, ab wann eine auf Digest gestellte Benachrichtigung gebündelt zugestellt wurde (NULL = noch nicht zugestellt, wird vom stündlichen Cron generic-digest-delivery gesetzt). Reine Prozess-Steuerung, kein zusätzlicher Personenbezug über die ohnehin bereits dokumentierte notifications-Zeile hinaus. Aufbewahrung: folgt dem Lebenszyklus der zugehörigen notifications-Zeile
- Persönliche Domain-spezifische Kanal-Overrides (user_notification_domain_overrides, PROJ-508): Pro-User-Override des Benachrichtigungskanals für bestimmte Domains (z.B. „kritische Domain → immer per E-Mail“). Enthält ausschließlich technische Konfigurationsdaten: User-ID, Workspace-ID, Domainname (lowercase, normalisiert), Kanal-Modus (email/push/email_and_push/disabled), Erstellungszeitpunkt. Keine personenbezogenen Daten über Dritte. Aufbewahrung: Bis zur Account-Löschung (CASCADE auf auth.users) oder Workspace-Löschung (CASCADE auf workspaces)
- Empfänger-Gruppen (notification_recipient_groups): Benannte Gruppen mit Listen von Workspace-Mitglied-IDs (UUID-Array). Enthält: Gruppenname, Mitglieder-IDs. Aufbewahrung: Bis zur Löschung des Workspace (CASCADE)
- Verzögerungs-Queue (notification_delay_queue): Temporäre Einträge für verzögert zu sendende Benachrichtigungen. Enthält: Aktionsschlüssel, Entity-Typ und -ID, Empfänger-User-ID, Payload (JSONB mit Benachrichtigungstitel und -nachricht), geplanter Ausführungszeitpunkt, Verarbeitungs-/Stornierungszeitpunkt. Aufbewahrung: Verarbeitete Einträge werden nicht automatisch gelöscht — bei Workspace-Löschung per CASCADE entfernt
- Inbox-Regeln (notification_inbox_rules, PROJ-1882): Eine vom Nutzer selbst gepflegte Auswahl (genau ein Datensatz pro Nutzer), deren eintreffende System-Benachrichtigungen automatisch als gelesen markiert werden. Enthält: User-ID, Kriterien (Listen von Benachrichtigungstyp-Schlüsseln und/oder Kategorie-Schlüsseln aus dem System-Katalog — keine Freitexte, keine Daten über Dritte), Zeitstempel. Die Auswahl gilt global für den Nutzer über alle Workspaces und wirkt ausschließlich auf den Gelesen-Status in der Inbox — die Zustellung über andere Kanäle (Push, E-Mail-Digest, user_notification_preferences) bleibt unberührt. Eine Datenbank-Prüfregel wendet die Auswahl beim Entstehen jeder neuen Benachrichtigung an; beim Speichern/Erweitern der Auswahl werden bestehende ungelesene Treffer einmalig rückwirkend markiert. Aufbewahrung: Bis zur Leerung/Änderung durch den Nutzer oder Account-Löschung (CASCADE auf auth.users)
- Automatisch-gelesen-Kennzeichen (notifications.auto_read, PROJ-1882): Boolean-Flag auf der bestehenden Benachrichtigungs-Zeile — true, wenn der Gelesen-Status durch eine Inbox-Regel statt manuell gesetzt wurde (dezente Kennzeichnung in der Liste). Manuelles Umschalten des Gelesen-Status setzt das Flag zurück. Kein zusätzlicher Personenbezug über die ohnehin dokumentierte notifications-Zeile hinaus; folgt deren Lebenszyklus
- Typ-Kategorie-Katalog (notification_type_categories, PROJ-1882): Datenbank-Spiegel des Programmcode-Katalogs FILTER_TYPE_MAP (Zuordnung Benachrichtigungstyp → Kategorie), damit Kategorie-Regeln auf Datenbank-Ebene ausgewertet werden können. Reine Katalogdaten ohne jeden Personenbezug
SEO-Sichtbarkeitsindex-Monitoring (PROJ-217, PROJ-218, PROJ-1845)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — wöchentliches SEO-Ranking-Monitoring als Bestandteil der Agenturdienstleistung; seit PROJ-1845 technisch als stündlich abgearbeiteter wöchentlicher Erfassungszyklus umgesetzt). Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Wettbewerbsanalyse und Sichtbarkeitsvergleich)
- Keyword-Rankings (keyword_rankings): Pro Keyword und Domain wird die aktuelle Google-Ranking-Position gespeichert — Keyword-ID (Referenz auf keywords-Tabelle), Workspace-ID, Domain (Unternehmens- oder Wettbewerbsdomain ohne Personenbezug), Domain-Typ (own/competitor), Ranking-Position (Ganzzahl 1–100 oder NULL für nicht gerankt), URL des rankenden Ergebnisses (optionale Ziel-URL, keine personenbezogenen Daten), Zeitstempel des Checks. Aufbewahrung: 365 Tage (automatischer Cleanup-Cron dienstags 03:30 UTC)
- Domain-Sichtbarkeitshistorie (domain_visibility_history): Snapshot des Gesamt-Domain-Sichtbarkeitsindex je abgeschlossenem Erfassungszyklus (fachlich wöchentlich, PROJ-1845) via DataForSEO Labs — Kontakt-ID (Referenz auf contacts-Tabelle, ON DELETE CASCADE), Workspace-ID, Domain (Unternehmens- oder Wettbewerbsdomain), Domain-Typ (own/competitor), Sichtbarkeitsindex (berechneter Wert aus CTR-Kurve × Suchvolumen), organischer Sichtbarkeitswert (DataForSEO Labs), geschätzter organischer Traffic, Anzahl gerankter Keywords, Anzahl tatsächlich geprüfter Keywords, Zeitstempel des Checks, Zyklus-Kennung (check_cycle_id, PROJ-1845). Keine personenbezogenen Daten — alle Werte beziehen sich auf Unternehmensdomains. Aufbewahrung: 730 Tage (automatischer Cleanup-Cron dienstags 03:30 UTC)
- Erfassungszyklus-Fortschritt (ranking_check_cycles + ranking_check_cycle_units, PROJ-1845): Reine Betriebs-/Fortschrittsdaten des Ranking-Abrufs — je Zyklus ein Datensatz (Workspace-ID, Zustand, Start-/Abschlusszeitpunkt) und je Arbeitspaket ein Datensatz (Kunde-Referenz, Zielmarkt-Referenz, Standortschlüssel, Positionsnummer, Fortschritts-Merker als Liste erfasster Keyword-IDs, Versuchszähler, letzter Fehlertext, Zeitstempel, Abschluss-Zeitpunkt des Kunden im Zyklus). Keine personenbezogenen Daten — ausschließlich technische Referenzen und Laufzustand. Aufbewahrung: abgeschlossene Zyklen werden nach 400 Tagen automatisch durch den Cron gelöscht (Arbeitspakete per CASCADE); keyword_rankings/domain_visibility_history behalten ihre Zeilen (Zyklus-Kennung wird auf NULL gesetzt). Bei Kontaktlöschung: Arbeitspakete per CASCADE gelöscht. Bei Workspace-Löschung: beide Tabellen per CASCADE gelöscht. Datenexport (Art. 15/20): beide Tabellen sind im Workspace-Datenexport (GET /api/workspaces/data-export) enthalten (R-241)
- SEO-Konfiguration an Kontakten (contacts-Tabelle, neue Felder): primary_domain (Primärdomain des Kunden), competitor_domains (bis zu 3 Wettbewerbsdomains, JSONB-Array), seo_tracking_enabled (Aktivierungsschalter), seo_last_check_at und seo_last_manual_check_at (Zeitstempel der letzten automatischen/manuellen Prüfung). Domainangaben beziehen sich auf Unternehmenswebsites — kein Personenbezug
- Zielmarkt-Konfiguration (contact_target_markets, PROJ-218 + PROJ-268 + PROJ-381): Pro Kontakt können mehrere Zielmärkte konfiguriert werden — Suchmaschine (google/bing), Standortcode (DataForSEO Location Code, z.B. 2276 für Deutschland), Standortname, Sprachcode (z.B. 'de'), Sprachname, Sortierreihenfolge, Location-Typ (country/region/city/coordinates — PROJ-268). Bei GPS-Zielmärkten (location_type='coordinates') zusätzlich: Breitengrad, Längengrad und Suchradius in km (10/25/50/100). PROJ-381: Bei Multi-Country-Märkten zusätzlich location_codes (Liste mehrerer DataForSEO-Standortcodes für aggregierte Suchvolumina/Rankings über mehrere Länder hinweg, z.B. DACH = [2276, 2040, 2756]) und display_name (optionaler Anzeigename wie 'DACH', 'Benelux', 'EU Englisch', max. 50 Zeichen). GPS-Koordinaten beziehen sich auf Geschäftsstandorte oder Einzugsgebiete des Kunden — kein Personenbezug. Der Reverse-Geocoding-Ortsname (z.B. 'München') wird als location_name gespeichert. Diese Parameter steuern, für welche Länder/Regionen/Städte/GPS-Radien Keyword-Anreicherungen und Ranking-Checks bei DataForSEO abgefragt werden. Keine personenbezogenen Daten — ausschließlich Geschäftskonfiguration. Bei Kontaktlöschung: CASCADE-Löschung. Bei Zielmarkt-Löschung: Keywords/Rankings behalten ihre historischen Daten (target_market_id wird auf NULL gesetzt via ON DELETE SET NULL)
- Regionen-Presets (market_region_presets, PROJ-381): Wiederverwendbare Vorlagen für Multi-Country-Zielmärkte — Name (z.B. 'DACH', max. 50 Zeichen), country_codes (Liste von ISO-Ländercodes wie ['DE','AT','CH']), suggested_language (optionaler Sprach-Vorschlag wie 'de'/'en'), sort_order. System-Presets (workspace_id IS NULL) sind plattformweit lesbar (DACH, Benelux, Nordics, EU Englisch). Workspace-eigene Presets sind nur für Workspace-Mitglieder lesbar und nur durch Admins änderbar. Keine personenbezogenen Daten — ausschließlich Konfigurations-Vorlagen. Bei Workspace-Löschung: CASCADE-Löschung der workspace-eigenen Presets
- AI-Overview-Zitat-Monitoring (ai_overview_citations, PROJ-1566): Historisiert pro Keyword, ob die eigene Domain in Googles AI-Overview-Antwort zitiert wird — Keyword-ID (Referenz auf keywords-Tabelle), Workspace-ID, Domain (Unternehmensdomain ohne Personenbezug), ai_overview_present (Boolean, ob überhaupt ein AI-Overview erschien), cited (Boolean, ob die eigene Domain zitiert wurde), Zeitstempel des Checks. Zweistufige Kadenz: wöchentlicher Sweep über alle getrackten Keywords, tägliches Monitoring nur bei bereits bestätigtem Zitat-Treffer. Keine personenbezogenen Daten — ausschließlich Domain-/Keyword-bezogene Sichtbarkeitswerte. Aufbewahrung: 365 Tage (automatischer Cleanup-Cron dienstags 03:30 UTC, analog keyword_rankings)
- DSGVO-Datenexport (Art. 15/20): keyword_rankings, ai_overview_citations (PROJ-1566), domain_visibility_history und contact_target_markets (inkl. PROJ-381 location_codes + display_name) des Kontakts sind im Kontakt-Datenexport enthalten (GET /api/contacts/[id]/data-export)
Content Intelligence — Foundation + Dashboard UI + Workflow Phasen 01/02/03/04 + Human Validation Gate (PROJ-782 + PROJ-783 + PROJ-784 + PROJ-785 + PROJ-786 + PROJ-952)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Content-Strategie-Analysen als Teil der Agenturdienstleistung). Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an datengetriebener Content-Optimierung pro Kunde)
- Workspace-Settings (content_intelligence_settings): Workspace-weite Konfigurationen als Key-Value — verschlüsselter Gemini-API-Key (AES-256-GCM, setting_key='gemini_api_key'), Scoring-Schwellenwerte (tas_gap_threshold, bif_weight_threshold, bif_critical_threshold), TAS/BIF-Faktor-Gewichtungen (15 Werte für Workflow-Modus-Bestimmung), Modell-Auswahl pro Phase (4 Selects + 1 Fallback). Keine personenbezogenen Daten — ausschließlich technische Konfiguration. RLS: SELECT für Mitglieder, INSERT/UPDATE nur Admins
- Prompt-Templates (content_intelligence_prompts): Versionierte KI-Prompt-Templates für die 4 Workflow-Phasen (topic_blueprint, cluster_analysis, content_plan, conversion_strategy). Pro Workspace + prompt_key + version eine Zeile, is_active=true für die aktive Version. Inhalte sind interne Arbeitsanweisungen mit {{Platzhaltern}} — keine personenbezogenen Daten. Bei Reset auf System-Default wird die Default-Version (in code/constants) als neue Version eingefügt
- Content Intelligence Jobs (content_intelligence_jobs, PROJ-784 deployed 2026-05-26): Pro Job-Lauf eine Zeile mit Target-Keyword, Target-URL (Kunden-Webseiten-URL), Sprache/Region, Workflow-Modus, KPI-Werte (TAS-SEO/GEO, BIF, priority_score), phase_checkpoint (JSONB mit Zwischenergebnissen aller 4 Phasen — kann SSOT-Auszug + URL-Check-Status enthalten), api_export_json (finaler Export-JSON für den Textgenerator — kann SSOT-Marketingziele und Persona-Beschreibungen enthalten), error_log. SSOT-Daten enthalten in seltenen Fällen Namen von Geschäftsführern/Ansprechpartnern wenn entsprechende SSOT-Items hinterlegt sind. Aufbewahrung dauerhaft als Teil der Agenturarbeit pro Kunde — manuelle Löschung über die UI
- Rohdaten-Snapshot (content_intelligence_raw_data, PROJ-784 deployed 2026-05-26, erweitert PROJ-1387): Pro Job die DataForSEO-API-Antworten (SERP-Daten, OnPage-Analyse, Search Intent, PAA-Questions, Related-Searches, Search-Volume, seit PROJ-1387 zusätzlich Googles AI-Overview-Text via load_async_ai_overview) als JSONB. Inhalte sind öffentliche Google-Suchergebnisse und Wettbewerber-Domain-Daten — keine personenbezogenen Daten von Endnutzern. Aufbewahrung dauerhaft mit Job
- KI-Scoring + Content-Plan (content_intelligence_scoring + content_intelligence_content_plans + content_intelligence_validation, Phase 02 aktiv seit PROJ-784, Phase 03 aktiv seit PROJ-785, Phase 04 aktiv seit PROJ-786 — alle deployed 2026-05-26): Berechnete TAS/BIF-Einzelfaktoren, Gemini-generierte Topic Blueprints, Content-Pläne (Seiten-Vorschläge mit Keywords, Wortzahl-Zielen), Conversion-Strategien (Persona, CTAs) — alle Daten beziehen sich auf Geschäftskontext der Kunden, kein direkter Endnutzer-Personenbezug. Validierungs-Status (relevance/conversion/grounding) als JSONB
- Human Validation Gate (PROJ-952, content_intelligence_jobs.phase_checkpoint.validation_decisions): Zwischen Phase 03 und Phase 04 stoppt der Job auf Status awaiting_human_validation. Ein Redakteur/Manager bewertet pro vorgeschlagener Seite die Relevanz (ja/nein/modifizieren), wählt den Seitentyp und entscheidet über H2-Keyword-Erweiterungen. Diese Entscheidungen werden im bereits bestehenden phase_checkpoint-JSONB der Job-Zeile gespeichert (Feld validation_decisions: pages-Liste + decided_at + decided_by). decided_by ist die User-ID des entscheidenden internen Mitarbeiters (Bearbeitungs-Metadatum, kein Endkunden-Personenbezug). Der Keyword-Abgleich (GET /jobs/:id/keyword-matches) liest ausschließlich bereits im Workspace vorhandene keywords/keyword_analyses-Daten (kein neuer Datenfluss, kein externer Service). Beim Erreichen des Gates wird eine Inbox-Notification 'content_intelligence_validation_requested' an Workspace-Admins/Manager gesendet (enthält Job-ID + Target-Keyword, keine Endkunden-PII). Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertrag — Qualitätssicherung der Content-Strategie). Aufbewahrung + Löschung: identisch zur Job-Zeile (CASCADE, siehe deletionConcept). Export: als Teil von content_intelligence_jobs.phase_checkpoint im Workspace-Datenexport enthalten
- Datenexport (Art. 15/20): Alle 8 Tabellen sind im Workspace-Datenexport (GET /api/workspaces/data-export) als content_intelligence-Sektion enthalten (R-241). Sensitive Settings (gemini_api_key) werden im Export als '[verschlüsselt — wird nicht exportiert]' markiert und nicht als Klartext ausgegeben
- Drittlandtransfer: PROJ-785 überträgt SSOT-Auszüge + SERP-Daten + HTML-Wettbewerber-Inhalte an Google Gemini (USA, SCCs / DPF) — siehe PROCESSORS-Eintrag 'Google LLC (Generative Language API / Gemini)'. DataForSEO (Litauen, EU) wird in PROJ-784 für SERP/OnPage/Keyword-Daten genutzt — kein Drittlandtransfer.
- Workflow Phase 04 — Conversion Gate + API-Export (PROJ-786, runPhase04, pg_cron ci-phase04-tick alle 30s, deployed 2026-05-26): Nach phase_03_done werden 5 Sub-Phasen sequenziell ausgeführt. Phase 04a: Automatische Relevanz-Validierung (GEO-Score/SEO-Score/Marketing-Status) — Pure-Function ohne externe Aufrufe, validation_type='relevance' in content_intelligence_validation. Phase 04b: Optional Human-Validation-Gate — wenn Gemini-Key nicht konfiguriert, pausiert Worker auf phase_03_done bis User via POST /jobs/:id/validation/approve oder /reject (Pflicht-Kommentar min 20 Zeichen) entscheidet. Phase 04c: Conversion-Strategie via Gemini sequenziell pro geplanter Seite (max_tokens=600/Seite, 500ms-Pause). Pro Seite Output: marketing_goal, persona, persona_pain_points, tone_of_voice, 3 CTAs (soft/medium/end_box), lead_magnet. SSOT-Marketingziele + Zielgruppen-Beschreibungen als Input — können in seltenen Fällen Personennamen enthalten. Phase 04d: Grounding-Check — Pure-Function Substring-Match aller Fakten-Kandidaten (must_cover_topics + Cluster-Beschreibungen + Entity-Descriptions) gegen alle SSOT-Items (Live, staging_set_id IS NULL). Verified/Unverified-Status pro Fakt, informativ (kein Blocker). Phase 04e: API-Export-JSON-Builder — Pure-Function kombiniert alle Phasen zu strukturiertem JSON (integration_meta + ssot_injected + geo_briefing_global + scoring_summary + pages_to_generate + navigation_plan). Speicherung in content_intelligence_jobs.api_export_json. Notification 'content_intelligence_job_completed' an created_by nach Erfolg. Sub-Auftragsverarbeiter Phase 04c: Google LLC (Gemini, USA, SCCs/DPF). Rechtsgrundlage: Art. 6 Abs. 1 lit. b (Vertrag). Export-Download via GET /jobs/:id/export (admin/manager/member, optional ?page_id für Subset). Cleanup: Job-bezogen via CASCADE.
- Workflow Phase 03 — KI Content-Planung (PROJ-785, runPhase03, pg_cron ci-phase03-tick alle 30s): Nach phase_02_done werden 3 Sub-Phasen sequenziell ausgeführt. Phase 03a: Gemini-Call (Topic Blueprint) mit SSOT-Markdown (Unternehmenskontext, kann Personennamen enthalten), Target-Keyword, SERP-Top-10-URLs, PAA-Questions, Search Intent als Input. Gemini liefert Topic Blueprint (Haupt-Entität, Pillar-Cluster) — transiente Verarbeitung, kein Training auf Kundendaten. Phase 03b: HTTP-Fetch der eigenen Kunden-Website + max. 10 Wettbewerber-URLs (öffentlich zugängliche Seiten). isAcceptableHttpsUrl-Schutz gegen SSRF. HTML-Parser (Pure-Function, keine externe Library) extrahiert: Wortzahl, H-Struktur, Bilder-Count, Schema-Types — alles öffentlicher Content, kein Endnutzer-PII. Phase 03c: Gemini-Call (Cluster-Analyse + Content-Fahrplan) mit Topic Blueprint + Wettbewerber-Analyse als Input. Output: 3–20 geplante Content-Seiten mit Keywords, Wortzahlen, Cluster-Zuordnung, BIF-Estimate. Alle Outputs in content_intelligence_content_plans (plan_type: topic_blueprint/cluster_analysis/content_plan). Token-Usage in jobs.phase_checkpoint.phase_03. Sub-Auftragsverarbeiter: Google LLC (Gemini-API). Rechtsgrundlage: Art. 6 Abs. 1 lit. b (Vertrag). Cleanup: Job-bezogen via CASCADE
- UI-Workflow-Status-Tracking (PROJ-783, content_intelligence_content_plans.payload.content_plan[i].ui_status): Pro geplanter Inhaltsseite manuell vom Redakteur setzbarer Status (`offen`/`in_umsetzung`/`abgeschlossen`) im JSONB-Payload. Wird via Dropdown im Fahrplan-Tab der Deep-Dive-Ansicht via PATCH gesetzt. Reines Workflow-Tracking ohne Personenbezug — Geschäftsdaten zur Aufgabenverwaltung pro Job. Aufbewahrung mit Job (CASCADE bei Job-Löschung)
- Human Validation Gate — Seiten löschen/umbenennen + Segment-Filter + Knotenpunkt-Quick-Add (PROJ-1363, content_intelligence_content_plans.payload.content_plan[i].deleted / .custom_label, neue Route PATCH /cluster-jobs/:id/content-plan-overrides): Erweitert das bereits bestehende Content-Plan-JSONB pro Kind-Job um zwei optionale Keys — `deleted` (boolean, Soft-Delete NUR für den aktuellen, noch nicht bestätigten Job-Durchlauf; kein dauerhafter Ausschluss, ein neuer Job-Lauf kann dieselbe Seite erneut vorschlagen) und `custom_label` (Text, max. 255 Zeichen, überschreibt den KI-generierten Seitentitel bei Anzeige und bei der Phase-04-Textgenerierung; der ursprüngliche KI-Name bleibt nirgends als eigenständiger SSOT-Vorschlagswert erhalten). `deleted:true` kaskadiert rekursiv auf abhängige Seiten (verknüpft über parent_page_id). Beide Felder sind redaktionelle Content-Strategie-Daten (Seitentitel/Struktur) ohne Personenbezug. Zugriffskontrolle der neuen PATCH-Route: Workspace-Scope (getWorkspaceId), Rollen-Gate admin/manager, Ownership-Check (jede source_job_id muss ein Kind-Job desselben Clusters sein, sonst 403) — kein Cross-Tenant-Zugriff möglich. Der Segment-Filter im Knoten-Selektor (SSOTEntwurfsTree, Anzeigefilter auf das bereits bestehende Pflichtfeld ssot_items.data.segmenttyp) ist rein clientseitiger Sitzungs-State ohne neue Persistenz. Ein im Gate neu angelegter SSOT-Knotenpunkt wird über den bereits bestehenden, unveränderten Endpunkt POST /api/contacts/:id/ssot/items persistiert (kein neuer Sub-Auftragsverarbeiter, kein neuer LLM-Call). Datenexport (Art. 15/20) und Löschkonzept: unverändert — beide neuen Felder liegen im bereits vollständig exportierten und per CASCADE (job_id → contact_id) erfassten payload-JSONB, siehe Datenexport-Hinweis und deletionConcept oben
- URL-Erreichbarkeits-Check (PROJ-783, POST /api/content-intelligence/url-check): Beim Anlegen eines neuen Jobs prüft der Server, ob die vom Admin eingegebene Target-URL via HTTP-HEAD erreichbar ist (10s Timeout, redirect:manual, isAcceptableHttpsUrl-Schutz). Der Drittanbieter-Server (Kunden-Website) erhält dabei einen HTTP-HEAD-Request mit Vercel-Server-IP + User-Agent 'NEULAND-OS-ContentIntelligence-Scraper/1.0' — KEINE Daten des Endnutzers werden übermittelt, der Aufruf erfolgt server-seitig vom NEULAND-OS-Backend. Keine eigene Speicherung des Ergebnisses (nur Live-Anzeige im Modal). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an URL-Validierung vor Workflow-Start). Rate-Limit 30/Min pro User schützt vor Missbrauch
- Workflow Phase 01 — CRM/SSOT-Daten laden (PROJ-784, runPhase01): Nach Job-Anlage werden serverseitig (waitUntil) folgende DB-Daten gelesen: ssot_items des Kontakts (Live-Items via staging_set_id IS NULL + deleted_in_staging=false, sortiert nach section/position) → Markdown-Aufbau für KI-Kontext (Phasen 03/04); contacts.city + contacts.country → Unternehmensstandort-String. KEIN externer Aufruf in Phase 01 außer dem optionalen URL-Check (HTTP-HEAD mit 10s Timeout, max 5 Redirects, redirect:follow, kein Auto-Body-Download). Daten werden im job.phase_checkpoint.phase_01-JSONB gespeichert. Personenbezug: SSOT-Items können Namen von Geschäftsführern/Ansprechpartnern enthalten — vom Workspace-Admin selbst eingepflegt. Rechtsgrundlage: Art. 6 Abs. 1 lit. b (Vertrag)
- Workflow Phase 02 — DataForSEO-Datensammlung + Scoring (PROJ-784, runPhase02, pg_cron ci-phase02-tick alle 30s): Beim Pickup eines phase_01_done-Jobs werden 5 parallele DataForSEO-API-Calls ausgeführt (SERP Desktop/Mobile, OnPage-Instant für target_url, Search Intent, Keyword-Volume) via Promise.allSettled mit AbortSignal.timeout(30_000) + 3 Retries (R-587/R-665). Übermittelte Daten: target_keyword (öffentlicher Suchbegriff), target_location/target_language (Region/Sprache), target_url (öffentliche Kunden-Webseiten-URL). Sub-Auftragsverarbeiter: DataForSEO Ltd. (Litauen, EU — siehe bestehender PROCESSORS-Eintrag aus PROJ-210). Rohdaten der Calls landen in content_intelligence_raw_data (JSONB) — SERP-Ergebnisse + OnPage-Metriken + PAA + Related-Searches sind ausschließlich öffentliche Google-Suchdaten ohne Endnutzer-PII. TAS-SEO/TAS-GEO/BIF-Scoring rechnet Pure-Function-basiert lokal (keine externe Übermittlung), Faktoren werden in content_intelligence_scoring (DECIMAL) gespeichert, Aggregate (tas_seo, tas_geo, tas_gap, bif_score, bif_weight, priority_score, workflow_mode) in jobs. Rechtsgrundlage: Art. 6 Abs. 1 lit. b (Vertrag) + Art. 6 Abs. 1 lit. f (datengetriebene Inhaltsoptimierung). Cleanup: Job-bezogen via CASCADE (siehe deletionConcept)
- Phase-Trigger-Mechanik (PROJ-784): Phase 01 läuft inline via Vercel waitUntil() im POST /jobs-Handler (≤10s, kein externer Trigger). Phase 02 läuft asynchron via pg_cron-Job 'ci-phase02-tick' (jobid 234, alle 30 Sekunden); der Cron triggert /api/cron/ci-phase02-tick mit cron_config-Bearer (R-595), das maximal 5 phase_01_done-Jobs FIFO aufpickt. Jobs können vom Admin/Manager über POST /jobs/:id/cancel abgebrochen werden (nur in pending/running/phase_01_done) oder via POST /jobs/:id/restart neu gestartet (nur in error/cancelled/failed) — phase_checkpoint wird beim Restart zurückgesetzt. Notification 'content_intelligence_job_error' wird bei Fehler an created_by + admin/manager des Workspaces gesendet (DB-Constraint-Erweiterung in Migration 20260526130000)
- Workflow Phase 05 — Textgenerierung mit Claim-Level-Reasoning (PROJ-1401, runPhase05, automatischer Trigger direkt nach Phase-04-Abschluss über Vercel after(); seit PROJ-1415 zusätzlich automatischer Wiederanlauf endgültig gescheiterter Seiten — max. 3 Versuche pro Seite, gezählt im rein technischen Steuerfeld retry_count ohne Personenbezug — sowie manueller Retry-Button für admin/manager via POST /jobs/:id/text-generation/retry; beide Retry-Wege wiederholen dieselbe Verarbeitung mit identischem Dateninput, keine neue Datenkategorie und keine neue Übermittlung): Pro freigegebener Content-Plan-Seite (page-scoped, 1 Zeile je Seite in content_intelligence_generated_pages) generiert ein Claude-Sonnet-4.6-Call (bei >900 Wörtern Ziel-Textlänge 2–3 sequenzielle Calls mit Prompt-Caching, R-658) einen vollständigen Seitentext. Jeder Abschnitt trägt ein reasoning[]-Array auf Aussagen-Ebene mit Status grounded/generated/open_question + Provenance-Verweis (Pfad/ID, keine Textkopie) auf Phase 03c (Content-Plan) bzw. Phase 04 (Validierung/Grounding). Seit PROJ-1451 zusätzlich pro Aussage risk_type (factual_claim/commitment/regulatory/none — inhaltliche Risiko-Einordnung, von Anthropic mitgeliefert, kein Personenbezug, betrifft ausschließlich den generierten Marketingtext) sowie confidence_score (0–100, rein deterministisch aus status+risk_type serverseitig berechnet — NICHT von Anthropic geliefert, keine zusätzliche Übermittlung). Input an Anthropic: SSOT-Personas/USPs/Marketingziele (Flag-gesteuert, ai_assistants.workflow_config.ci_include_ssot_context), die zu generierende Content-Plan-Seite, Grounding-/Validierungs-Befunde aus Phase 04, AI-Overview-Text und Related-Searches aus content_intelligence_raw_data (öffentliche Google-Suchdaten, PROJ-1387, seit PROJ-1406 zusätzlich als Grounding-Quelle), Corporate-Language-Block aus ssot_ci_language (automatisch angehängt; seit PROJ-1415 alternativ über den Insert-Tag {{corporate_language}} referenzierbar — identische Daten, automatische Anhängung entfällt dann zur Dopplungs-Vermeidung). Die beiden PROJ-1415-Insert-Tags {{conversion_strategy}}/{{corporate_language}} machen ausschließlich diese bereits übermittelten Datenquellen zusätzlich als benannte Platzhalter referenzierbar (keine neue Erhebung). Alle Eingaben stammen aus bereits an anderer Stelle dokumentierten SSOT-/CI-Daten — keine neue PII-Kategorie. Notification 'content_intelligence_text_generation_completed' an created_by wenn alle Seiten eines Jobs fertig generiert sind. Export der generierten Texte (inkl./exkl. Reasoning, JSON/Markdown) via GET /jobs/:id/text-export (admin/manager/member, 4 Formate). Assistent 'Content Intelligence – Textgenerierung' (ai_assistants, Typ ci_assistant, sort_order 104) folgt derselben Admin-only-Konfigurationslogik wie die 4 bestehenden CI-Phasen-Assistenten (PROJ-1305). Datenexport (Art. 15/20): Metadaten (Status, Call-Anzahl, Wiederanlauf-Zähler retry_count, Zeitstempel) in content_intelligence_generated_pages sind Teil des Workspace-Datenexports — der vollständige Seitentext (sections-JSONB) ist auf Anfrage verfügbar, analog api_export_json bei content_intelligence_jobs
Redakteurs-Cockpit — Kommunikationspräferenz + Kundennachrichten-Generator (PROJ-1276)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfuellung — Erbringung von SEO-Beratungsdienstleistungen fuer Agenturkunden; Redakteure benoetigen die Ansprache und den Ansprechpartner-Namen um professionelle Kundenkommunikation im Rahmen der beauftragten Leistung zu erstellen)
- Kommunikationspraeferenz (customer_communication_preferences): Ansprache (du/Sie) + Ansprechpartner-Name (z.B. 'Frau Mueller') pro Workspace-x-Contact-Kombination. Der Ansprechpartner ist der Name einer natuerlichen Person beim Kundenkontakt und stellt PII dar. Gespeichert in customer_communication_preferences (workspace_id + contact_id, UNIQUE). Jederzeit ueber das Formular im Cockpit editierbar.
- Uebermittlung an Anthropic (Claude Haiku 4.5, transient): Beim Klick auf 'Kundennachricht generieren' werden Ansprechpartner-Name, Ansprache (du/Sie) und die ausgewaehlten KI-Empfehlungs-Titel+Beschreibungen aus content_intelligence_content_plans transient an Anthropic uebermittelt. Zweck: Generierung von 3 Textvarianten (formal-kurz, formal-ausfuehrlich, locker-kurz) fuer die haendische Verwendung durch den Redakteur. Kein Training, keine dauerhafte Speicherung bei Anthropic, kein Auto-Versand.
- KI-generierte Nachrichtenvarianten: Werden ausschliesslich im Browser angezeigt (3 Texte im Dialog) und nicht in der Datenbank gespeichert — rein ephemer.
- EU AI Act: Das Feature generiert KI-Texte die vom Redakteur als Vorlage genutzt werden (kein Auto-Versand). Der Dialog-Kontext ('Kundennachricht generieren', Ladeindikator 'Nachrichten werden generiert...') macht den KI-Charakter transparent. Kein vollautomatisierter Versand ohne menschliche Ueberpruefung — begrenztes Risiko (Art. 50 EU AI Act).
- Hinweis Datenexport (Art. 15/20): customer_communication_preferences (Ansprechpartner-Name) ist aktuell noch nicht im Workspace-Datenexport (GET /api/workspaces/data-export) enthalten — offenes Finding F-1 aus DSGVO-Pruefung 2026-06-26, Behebung in naechstem Sprint geplant.
Regionale Suchvolumen-Anreicherung via Google Ads API (PROJ-272)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — regionale Marktdaten als Bestandteil der Agenturdienstleistung). Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an exakten regionalen Suchvolumen für die Marketing-Potenzialanalyse von Kundenmärkten)
- Keyword-Texte (keywords-Tabelle): Marketingbegriffe ohne Personenbezug, z.B. „Marketing Agentur” — werden bei der Anreicherung an Google Ads übermittelt. Identisch zu den Daten die DataForSEO erhält (PROJ-210). Speicherung dauerhaft als Teil der Marketing-SSOT, Löschung durch CASCADE bei Kontaktlöschung
- Regionales Suchvolumen (keywords.regional_search_volume): Aggregierter monatlicher Suchvolumen-Wert (Integer) für das Keyword in einer spezifischen Region — von Google Ads `KeywordPlanIdeaService.GenerateKeywordIdeas` zurückgeliefert. Keine personenbezogenen Daten, ausschließlich aggregierte Marktdaten
- Verwendete Geo-Target-Criteria-ID (keywords.regional_location_code): Integer-Referenz auf die Google Ads Geo-Target-Criteria-ID, die für den regionalen Wert verwendet wurde (z.B. 20235 für Nordrhein-Westfalen, 1004607 für Köln) — zur Nachvollziehbarkeit, aus welchem Markt der Wert stammt
- Übermittelte Anfrage-Parameter: Keyword-Text, Geo-Target-Criteria-ID (aus `contact_target_markets.location_code`), Sprach-Criteria-ID (z.B. 1001 für Deutsch), Keyword-Plan-Network (GOOGLE_SEARCH). Keine Endnutzerdaten, ausschließlich Marketing-Konfigurationsdaten
- Verschlüsselte OAuth-Credentials (workspace_integrations.encrypted_credentials, Typ 'google_ads'): Developer Token, Customer-ID, OAuth Refresh Token, Client-ID, Client-Secret — AES-256-GCM verschlüsselt. Technische Zugangsdaten der Agentur, keine Endnutzerdaten
- API-Kosten-Einträge (api_cost_entries, Provider 'google_ads', Feature 'keyword_regional_search_volume'): Anzahl angefragter Keywords pro Anreicherungslauf, Workspace-ID, optionale Kontakt-ID (für Kunden-Attribution), Location-Code+Name als Meta-Feld. Keine personenbezogenen Daten
- DSGVO-Datenexport (Art. 15/20): keywords-Tabelle (inkl. regional_search_volume + regional_location_code) ist über den kontaktbasierten Export erreichbar (siehe Cross-Feature-Hinweis unten)
Keyword-Bedarfsgruppen-Verknüpfung (PROJ-275)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Zuordnung von Keywords zu Bedarfsgruppen-Seiten als Teil der Marketing-Strategieberatung)
- Keyword-Seiten-Zuordnungen (keyword_page_assignments): keyword_id (Referenz auf keywords-Tabelle), ssot_item_id (Referenz auf Bedarfsgruppen-Seite), created_by (User-ID des Erstellers), Zeitstempel. Die created_by-Spalte stellt einen Personenbezug her (Nutzerkennung)
- PROJ-1996: zuweisungs_konfidenz (KI-Konfidenz 0.00–1.00, ob das Keyword zu dieser Seite gehört, NULL solange unbewertet) — keine PII, rein modellseitige Kennzahl der Zuordnung
- DSGVO-Datenexport (Art. 15/20): keyword_page_assignments des Workspace sind im Workspace-Datenexport enthalten (GET /api/workspaces/data-export)
Druckprodukte-Bestellung (Flyeralarm-Integration)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Abwicklung von Druckaufträgen im Rahmen der Agenturdienstleistung)
- Lieferadresse (flyeralarm_orders.delivery_address, JSONB): Name, Straße, PLZ, Ort des Lieferempfängers. Wird für die Bestellabwicklung an Flyeralarm GmbH (Deutschland) übermittelt. Automatische Löschung 30 Tage nach Lieferung durch täglichen Cleanup-Cron (flyeralarm-address-cleanup)
- Produktkonfiguration (flyeralarm_orders.product_config_snapshot, JSONB): Gewähltes Format, Auflage, Papiersorte, Veredelung, Lieferzeit — keine personenbezogenen Daten, reine Bestellspezifikation
- Bestellstatus (flyeralarm_orders.status): Aktueller Status der Bestellung (wartend, in Produktion, versandt, geliefert). Aufbewahrung: 6 Jahre (GoBD-konforme Handelskorrespondenz gemäß §257 HGB)
- Kontakt-Zuordnung (flyeralarm_orders.contact_id): Referenz auf den bestellenden Kunden. Bei Kontaktlöschung wird contact_id auf NULL gesetzt (ON DELETE SET NULL) — der Bestelldatensatz bleibt anonym erhalten (GoBD)
EverReal Immobilien-Synchronisierung (Custom-Modul)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — automatisierte Datenübertragung als Agenturdienstleistung für den Kunden)
- Immobilienangebotsdaten (Sachdaten ohne direkten Personenbezug): Objekttitel, Typ (Miete/Kauf), Status, Preisfelder (Kaufpreis, Kaltmiete, Nebenkosten, Kaution, Provision), Adressdaten der Immobilie (Straße, PLZ, Ort), Beschreibungstexte (Objekt, Lage, Ausstattung), Bild-URLs, Grundriss-URLs, Verfügbarkeitsdatum, Fläche, Zimmeranzahl
- PROJ-757 Erweiterung 2026-05-22 — Bauliche und energetische Eigenschaften (Sachdaten ohne direkten Personenbezug): Baujahr, Stockwerke, Nettogrundrissfläche, Lage im Objekt (Etage), Zustand, Ausstattungsqualität, Modernisierungsjahr, Vermietungsstatus (true/false ohne Mieter-Bezug), Provisionspflicht
- PROJ-757 Erweiterung 2026-05-22 — Energieausweis-Daten (Sachdaten ohne direkten Personenbezug): Energieeffizienzklasse, Energiekennwert (kWh/m²a), Energieträger, Heizungsart, Energieausweis-Typ (Bedarfs-/Verbrauchsausweis), Energieausweis-Verfügbarkeit, Energieausweis-Erstellungszeitraum, Warmwasser-im-Energiebedarf-enthalten-Flag
- PROJ-757 Erweiterung 2026-05-22 — Ausstattungsmerkmale als Boolean-Flags (Sachdaten): Gäste-WC, Unterkellert, Stufenloser Zugang (Seniorengerecht), Aufzug, Balkon/Terrasse, Garten, Einbauküche, Stellplatz-Typ
- PROJ-758 Erweiterung 2026-05-22 — Bilder-Push ans Contao-Bundle (Sachdaten ohne direkten Personenbezug): EverReal-Listing-Bilder (Cover, Galerie, Grundrisse) werden nach jedem Sheet-Sync per HTTP-Multipart an das Bundle neulandagentur/contao-image-ingest-bundle auf der Kunden-Contao-Site gepusht. Bilder werden dort in tl_files unter /files/immobilien/everreal/{listing_id}/ abgelegt. Diff-State (everreal_image_sync_state-Tabelle, SHA-256-Hash pro Listing) verhindert unnötige Re-Pushes. Auth via Bundle-Token (AES-256-GCM-verschlüsselt in workspace_modules.config.contao_image_ingest_bundle_token_encrypted). Push erfolgt zur bestehenden Plesk-Hosting-Infrastruktur des Kunden (keine zusätzlichen Auftragsverarbeiter, Daten verlassen die Agentur-/Kunden-Sphäre nicht).
- PROJ-757 Erweiterung 2026-05-22 (PII) — Listing-Ansprechpartner (Beschäftigtendaten der Kunden-Mitarbeiter): Pro Immobilien-Listing wird der zuständige Mitarbeiter aus EverReal mitsynchronisiert. Datenkategorien: Vorname, Nachname, E-Mail-Adresse, Profilbild-URL (öffentlich, EverReal-CDN), interne User-ID (UUID). Telefon/Mobil/Fax sind im EverReal-Schema NICHT verfügbar. Diese Daten sind in EverReal selbst durch den Kunden gepflegt und werden bereits öffentlich auf der Immobilien-Homepage angezeigt — Daten verlassen also nicht den ohnehin öffentlichen Sphärenkreis. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Agenturleistung für Kunden). Information der Betroffenen erfolgt durch den Kunden (Schmitz Immobilienservice) als Arbeitgeber.
- PROJ-757 Erweiterung 2026-05-22 — weitere Listing-Metadaten (Sachdaten): Firmenname des Listing-Owners, Immobilien-Kategorie (Wohn-/Gewerbeimmobilie), Eigentumsverhältnis (Einzel-/Mehrfacheigentum), Voll-Adresse-String, Virtual-Tour-Link, Erstellungs- und Aktualisierungs-Zeitstempel, Unit-Beschreibungen (Objekt/Lage/Ausstattung/Sonstiges separat zur Listing-Beschreibung), Vermietungs-Bereitschafts-Status, Hauptkeller-Flag.
- PROJ-757 Bugfix 2026-05-27 — Listing-Dokumente (PDF-Exposés, Sachdaten ohne direkten Personenbezug): URLs zu PDF-Dokumenten, die der Kunde optional pro Listing in EverReal hochlädt (typischerweise Verkaufs-/Vermietungs-Exposés). Datenkategorie: Datei-URLs aus dem EverReal-CDN (öffentlich abrufbar, identische Verfügbarkeit wie bereits gesynchronisierte Bilder). Wir speichern ausschließlich die kommagetrennte URL-Liste im Google Sheet (Spalte expose_pdf_urls), keine PDF-Inhalte in der Plattform-DB. Keine PII-Verarbeitung — wenn ein Exposé Mieter-/Eigentümer-Klartextdaten enthält, ist die Verantwortung dafür beim Kunden (Schmitz Immobilienservice) in EverReal selbst.
- EverReal-Credentials (Client ID, Client Secret, Access Token, Refresh Token): AES-256-GCM verschlüsselt in workspace_modules.config (JSONB) gespeichert. Werden nie in API-Responses zurückgegeben. Access Token automatische Rotation (1h TTL)
- Google Service Account Key: Ausschließlich als Umgebungsvariable (GOOGLE_SERVICE_ACCOUNT_KEY), nicht in der Datenbank gespeichert
- Sync-Protokolle (everreal_sync_logs): Zeitstempel, Trigger-Typ (Cron/manuell), Status, Anzahl verarbeiteter Listings, Fehlermeldungen. Keine personenbezogenen Daten. Max. 200 Einträge pro Workspace (automatische Bereinigung)
- PROJ-941 — Outbound-Anfrage-Übermittlung (everreal_inquiry_submissions, PII): Immobilien-Interessenten füllen ein Anfrageformular auf der Kunden-Website (Contao) aus. Erfasst werden Anrede, Vor- und Nachname, E-Mail-Adresse, Telefonnummer, Freitext-Nachricht und Rückruf-Wunsch sowie die EverReal-Listing-ID des angefragten Objekts. Diese Daten werden über NEULAND. OS an EverReal übermittelt (Mutation upsertCandidateInitialApplication) und parallel in der Tabelle everreal_inquiry_submissions als Übermittlungsprotokoll inkl. Retry-Warteschlange gespeichert. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (vorvertragliche Maßnahmen auf Anfrage der betroffenen Person). Empfänger der Daten: EverReal GmbH (siehe Auftragsverarbeiter-Eintrag). Aufbewahrung: automatische Löschung der Protokolle nach 90 Tagen (Cleanup-Cron everreal-inquiry-cleanup). RLS: nur Admin/Manager des Workspaces können die Protokolle einsehen.
Bid4it Auktionskatalog-Synchronisierung (Custom-Modul, Kunde Nagel Auktionen — PROJ-930)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — automatisierte Datenübertragung als Agenturdienstleistung für den Kunden); für enthaltene Künstler-Personendaten Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an der Spiegelung bereits öffentlicher Auktionskatalog-Daten)
- Auktions-Sachdaten (kein direkter Personenbezug): UUID, ID, Code, Typ, Name, Start-/Aktiv-bis-Datum, Status, Anzahl Artikel, Mindestgebotsschritt, Aufgeld, Auktionsbedingungen, Versanddetails, Vorbesichtigungszeiten, Katalog-Link.
- Artikel-/Los-Sachdaten (kein direkter Personenbezug): Losnummern, Titel, Beschreibung, Schätzpreise (von/bis/Spanne), Start-/Verkaufs-/Sofortkaufpreis, Status, Kategorie, Highlight-/Versand-Flags, Bild-URLs (static.stather-it-consulting.de), Artikel-Link.
- Künstler-Stammdaten (PII, öffentliche Katalogdaten): Name sowie Beschreibung/Lebensdaten (z. B. Geburts-/Sterbeort und -jahr) der den Losen zugeordneten Künstler — teils lebende Personen. Diese Daten sind bereits öffentlich im Auktionskatalog des Kunden publiziert und werden unverändert gespiegelt; sie verlassen nicht den ohnehin öffentlichen Sphärenkreis. Rechtsgrundlage Art. 6 Abs. 1 lit. f DSGVO. Verantwortlich für die Erstpublikation ist das Auktionshaus (Nagel Auktionen).
- Datenfluss: Öffentliche Bid4it-Guest-API (Stather IT Consulting, EU) → NEULAND. OS (serverseitiger Pull, kein Auth) → Google Sheet (Google LLC, Service Account, bereits gelisteter Auftragsverarbeiter) → numero2-Spreadsheet-Catalog-Import in die Kunden-Contao-Site. Die Katalogdaten werden NICHT in der NEULAND.-OS-Plattform-DB gespeichert.
- Google Service Account Key: ausschließlich als Umgebungsvariable (GOOGLE_SERVICE_ACCOUNT_KEY), nicht in der Datenbank gespeichert.
- Sync-Protokolle (bid4it_sync_logs): Zeitstempel, Trigger-Typ (Cron/manuell), Status, Anzahl verarbeiteter Auktionen/Artikel/Kategorien/Künstler/Dateien (files_total), Dauer, Fehlermeldungen. Keine personenbezogenen Daten. Max. 200 Einträge pro Workspace (automatische Bereinigung).
- PROJ-1368 — Datei-Inventar der Kunden-Contao-Site (Tab „UUIDs“, finale Richtung 2026-07-03): Server-seitiger Pull des Datei-Manager-Inventars der Kunden-Website (dev.auction.de/_tools/file-info, eigene Contao-Instanz von Nagel Auktionen, kein Auth). Ins Google Sheet geschrieben werden seit der Scope-Revision 2026-07-03 nur noch 2 Felder pro Datei: Datei-Pfad (Path) und Contao-UUID (contaoUuid, technischer Identifier) — die übrigen von der Quelle gelieferten Felder (ID, Name, Typ, Extension, MIME, Meta) werden transient mitgelesen, aber nicht mehr persistiert. Löst ein zuvor manuell laufendes zweites Apps-Script (`importSurplusFileData()`) sowie die manuelle Tab-Pflege durch den Kunden ab. Überwiegend technische Asset-Metadaten (Theme-/Font-/Bild-Dateien, Auktionsartikel-Fotos nach numerischer Losnummer benannt); Stichproben-Prüfung (129.054 Datensätze, 2026-07-02) zeigte keine personenbezogenen Dateinamen. Datenfluss identisch zum bestehenden Katalog-Pull: Kunden-Contao-Site (eigene Infrastruktur des Kunden, kein neuer externer Auftragsverarbeiter) → NEULAND. OS (serverseitiger Pull, transiente Verarbeitung im Arbeitsspeicher) → Google Sheet, Tab „UUIDs“ (Full-Rebuild, kein Storage in der Plattform-DB). Fehler-isoliert: ein Ausfall dieses Zusatzschritts beeinflusst den Katalog-Pull (Auktionen/Artikel/Kategorien/Künstler) nicht.
- PROJ-1429 (opt-in, Default deaktiviert) — Automatische KI-Anreicherung leerer Künstlerfelder im kuratierten Tab „[Import] Künstler]“: Für Künstler mit noch leeren weißen Zielfeldern (Geburtsdatum, Geburts-/Sterbeort, Nationalität, Schaffenszeit, Kunststil, bekannteste Werke, Auszeichnungen, Kunstkategorie, Zitat, Beschreibung) wird der Künstlername serverseitig an SerpAPI (Web-Suche) und Anthropic (Claude, generateObject mit Web-Suchergebnissen als Beleg-Kontext, temperature=0, kein Erfinden unbelegter Fakten) übermittelt. Recherchierte Werte werden ausschließlich zellgenau in die betroffenen leeren Zellen des Google Sheets geschrieben — bereits befüllte Felder (inkl. bestehendem „-“-Platzhalter) werden nie überschrieben. Zwei neue, workspace-isolierte Plattform-Tabellen dienen NUR der Nachvollziehbarkeit, enthalten aber keine Künstler-Namen/-Biografiedaten selbst (diese bleiben ausschließlich im Google Sheet): `bid4it_known_artists` (Künstler-UUID, wann zuerst gesehen, Anreicherungs-Status als Boolean) und `bid4it_artist_enrichment_log` (Künstler-UUID, Zeitpunkt, Status erfolgreich/teilweise/fehlgeschlagen, Liste befüllter Feldnamen, ggf. Fehlermeldung). Rechtsgrundlage wie beim übrigen Künstler-Datensatz: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an der Vervollständigung bereits öffentlicher, teils lebender Personen betreffender Auktionskatalog-Stammdaten aus öffentlich zugänglichen Quellen). Umfang steuerbar (nur neu erkannte Künstler [Default] vs. gesamte Datenbank rückwirkend) und jederzeit deaktivierbar über die Modul-Konfiguration.
Mitarbeiter-Kompetenzpool (Aufgabenvorlagen)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Kapazitäts- und Aufgabenplanung als Bestandteil der internen Leistungserbringung)
- Pool-Zugehörigkeit (task_template_members): Zuordnung eines Workspace-Mitglieds (member_id → workspace_members) zu einer Aufgabenvorlage als berechtigter Bearbeiter. Enthält: Vorlage (task_template_id), Mitglied (member_id — interne UUID, kein Klartext), Reihenfolge (sort_order), Erstellungszeitpunkt. Zweck: Filterung des Assignee-Dropdowns beim Erstellen einer Aufgabe sowie Kapazitätsplanung im Angebot. Löschung automatisch bei Mitglieds-Deaktivierung oder Vorlagen-Löschung (CASCADE DELETE auf member_id bzw. task_template_id).
- Parallele Bearbeiter (task_templates.parallel_workers): Ganzzahl (1–10) — wie viele Pool-Mitglieder typischerweise gleichzeitig an dieser Aufgabe arbeiten. Reine Konfigurationszahl ohne Personenbezug.
Varianten-Upgrade & Extra-Korrektur-Nachbeauftragung
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — kostenpflichtige Änderungen/Upgrades als Bestandteil des Leistungsabrufprozesses zwischen Agentur und Kunden-Workspace) und Art. 6 Abs. 1 lit. c DSGVO (gesetzliche Verpflichtung) für GoBD-pflichtige Abrechnungsposten nach Kunden-Genehmigung
- Varianten-Upgrade-Protokoll (task_variant_upgrades): Enthält: Aufgabe (task_id), ursprüngliche und neue Variante (from_variant_id, to_variant_id), Snapshot der Variantennamen zum Zeitpunkt des Upgrades, Sprint-Differenz, Preisdifferenz netto, Status (pending/approved/rejected/cancelled), erstellt durch (created_by — User-ID), Abschlusszeitpunkt. Aufbewahrung: Bis zur Löschung des Workspace (CASCADE auf workspace_id). Bei genehmigten Upgrades mit Abrechnungsposten: GoBD-Aufbewahrung 8 Jahre.
Öffentlicher Print-Shop (PROJ-233)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung — Anfrage oder verbindliche Beauftragung durch den Interessenten)
- Kontaktdaten (shop_inquiries.contact_data, JSONB): Vorname, Nachname, E-Mail-Adresse (Pflicht), Telefonnummer (optional), Unternehmen (optional), Nachricht (optional). Vertragsanbahnung gemäß Art. 6 Abs. 1 lit. b DSGVO
- Rechnungsadresse (shop_inquiries.billing_address, JSONB, nur bei Beauftragung): Firmenname, Straße, PLZ, Ort. Für Rechnungsstellung und Vertragserfüllung
- Produktkonfiguration (shop_inquiries.product_config, JSONB): Gewähltes Druckprodukt, Format, Auflage, Papiersorte, Veredelung, Lieferzeit — keine personenbezogenen Daten
- Preis-Snapshot (shop_inquiries.price_snapshot, JSONB): Gestaltungskosten, Druckkosten, Aufschlag, Gesamtpreis — GoBD-konform bei Beauftragungen (6 Jahre)
- IP-Hash (shop_inquiries.ip_hash): SHA-256-Hash der IP-Adresse für Spam-Erkennung und Rate-Limiting-Nachvollziehbarkeit. Kein Klartext, keine Re-Identifizierung möglich
- CRM-Kontakt-Verknüpfung (shop_inquiries.contact_id): Bei Anfrage wird automatisch ein CRM-Kontakt angelegt (oder bestehender verknüpft). Lead-Quelle: 'print-shop'
Schulungssystem (Kurse, Module, Lektionen)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — interne Mitarbeiterschulungen als Bestandteil des Beschäftigungsverhältnisses)
- Kurse (courses): Titel, Beschreibung, Cover-Bild-URL, Status (Entwurf/Veröffentlicht), Ersteller (created_by — User-ID), Archivierungszeitstempel. Workspace-isoliert (workspace_id)
- Module (modules): Titel, Beschreibung, Ersteller (created_by — User-ID). Module sind eigenständige Entitäten, die in mehreren Kursen wiederverwendet werden können (N:M-Junction course_modules)
- Lektionen (lessons): Titel, Typ (Inhalt/Quiz/Abgabe), Sortierreihenfolge, Ersteller (created_by — User-ID). Gehören zu genau einem Modul
- Lektions-Inhaltsblöcke (lesson_blocks, PROJ-243/244): Block-Typ (Text/Bild/Video/Dokument/Callout/Trennlinie/Code/Multiple-Choice/Lückentext), Inhalt (JSONB — kann nutzergenerierte Freitexte, Markdown, Medien-URLs und Frage-/Antwortdaten enthalten), Sortierreihenfolge. Werden per CASCADE bei Lektions-Löschung entfernt
- Fragen-Antworten (lesson_question_responses, PROJ-244): Benutzer-ID (user_id), Lektions-ID, Block-ID, gegebene Antwort (JSONB — gewählte Optionen oder eingegebene Texte), Korrektheit (boolean), Zeitstempel. Pro Antwortversuch eine Zeile (für Lern-Analytik). Werden per CASCADE bei Lektions- oder Block-Löschung entfernt
- Lektions-Medien (lesson-media Bucket, PROJ-243/247): Bilder (max 5 MB), Videos (max 500 MB), PDFs (max 10 MB). Gespeichert in privatem Supabase Storage-Bucket, workspace-scoped ({workspace_id}/{lesson_id}/). Zugriff nur über zeitlich begrenzte signierte URLs (1 Stunde TTL). Verwaiste Dateien werden durch täglichen Cleanup-Cron bereinigt
- Browser-Videoaufnahmen (PROJ-247): Kamera- und Mikrofon-Daten (getUserMedia) sowie Bildschirminhalte (getDisplayMedia) werden ausschließlich client-seitig im Browser des aufnehmenden Nutzers verarbeitet und weder zwischengespeichert noch an externe Dienste übermittelt. Erst nach expliziter Nutzeraktion ('Übernehmen') wird der fertige WebM-Blob in den privaten lesson-media Storage-Bucket hochgeladen. Im Bildschirmaufnahme-Modus (Screen / Bild-im-Bild) können sichtbare Bildschirminhalte personenbezogene Daten Dritter enthalten (z.B. CRM-Ansichten, E-Mail-Inhalte) — der aufnehmende Nutzer ist selbst für die Auswahl datenschutzkonformer Inhalte verantwortlich. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung). Browser-Berechtigungen (Kamera/Mikrofon/Bildschirm) werden durch den Browser erteilt und können jederzeit widerrufen werden
- Kurs-Kategorien (course_categories): Name, Sortierreihenfolge. Keine personenbezogenen Daten
- Cover-Bilder: Gespeichert in privatem Supabase Storage-Bucket (course-covers), workspace-scoped. Max. 2 MB, JPEG/PNG/WebP
- Prüfungs-Konfigurationen (lesson_exam_configs, PROJ-245): Konfiguration pro Quiz-Lektion (Zeitlimit, Bestehensschwelle, maximale Versuche, Zufallsreihenfolge). Keine personenbezogenen Daten
- Prüfungs-Versuche (exam_attempts, PROJ-245): Benutzer-ID (user_id), Workspace-ID, Lektions-ID, Startzeit, Einreichzeit, Ergebnisprozent, Bestanden-Status, Bewertungsstatus, gespeicherte Fragen-Reihenfolge (JSONB). Werden per CASCADE bei Lektions- oder User-Löschung entfernt
- Prüfungs-Antworten (exam_responses, PROJ-245): Versuch-ID, Block-ID, Antwortdaten (JSONB — Freitext oder Auswahl), Korrektheit, vergebene Punkte, Bewerter-ID (reviewer_id — User-ID des Bewerters), Bewerter-Kommentar. Werden per CASCADE bei Versuchs-Löschung entfernt
- Abgaben (assignment_submissions, PROJ-246): Benutzer-ID (user_id), Workspace-ID, Lektions-ID, Block-ID, Versionsnummer, Abgabetyp (text/file/video), Abgabe-Text (bis 50.000 Zeichen), Storage-Pfad im privaten Bucket 'assignment-submissions' (public=false, kein öffentlicher Zugriff; Zugriff nur über zeitbegrenzte signierte URLs mit 1 Stunde TTL), Dateiname, Dateigröße, Status (submitted/in_review/approved/revision_requested), Bewerter-ID (reviewer_id — SET NULL bei User-Löschung), Bewerter-Kommentar (bis 10.000 Zeichen), Bewertungspunktzahl (1–100), Einreichungszeitpunkt, Bewertungszeitpunkt. Alle Versionen werden dauerhaft gespeichert (Revisions-Verlauf). Dateien werden durch täglichen Cleanup-Cron bei verwaisten Einträgen bereinigt. Werden per CASCADE bei Lektions- oder User-Löschung entfernt
- Lektions-Abschlüsse (lesson_completions, PROJ-248): Benutzer-ID (user_id), Lektions-ID, Workspace-ID, Abschlusszeitpunkt. Eindeutig pro Nutzer + Lektion. Werden per CASCADE bei Lektions- oder User-Löschung entfernt
- Kurs-Fortschritt (course_progress, PROJ-248): Benutzer-ID (user_id), Kurs-ID, Workspace-ID, Anzahl abgeschlossener Lektionen, Gesamtanzahl Lektionen, Prozentwert (generiert), Status (not_started/in_progress/completed), Startzeitpunkt, Abschlusszeitpunkt. Cache-Tabelle, wird bei jeder Lektions-Fertigstellung aktualisiert. Werden per CASCADE bei Kurs- oder User-Löschung entfernt
- Kurszuweisungen (course_assignments, PROJ-248): Benutzer-ID (user_id), Kurs-ID, Workspace-ID, Zuweisender (assigned_by — User-ID, SET NULL bei Löschung), Zuweisungszeitpunkt, optionale Frist (deadline_at), Abschlusszeitpunkt. Eindeutig pro Nutzer + Kurs. Werden per CASCADE bei Kurs- oder User-Löschung entfernt
Schulungsportal — Kurs-Freigaben für verbundene Workspaces
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Weitergabe von Schulungsinhalten an verbundene Kunden- und Partner-Workspaces als Bestandteil der vertraglichen Leistungserbringung)
- Kurs-Workspace-Freigaben (course_workspace_access): Kurs-ID, Quell-Workspace-ID (Agentur), Ziel-Workspace-ID (Kunde/Partner), Freigabe-erteilt-von (granted_by — User-ID), Freigabe-Zeitstempel. Steuert, welche Kurse in verbundenen Kunden- und Partner-Workspaces sichtbar sind
- Personenbezogene Daten: granted_by (User-ID des Admins, der die Freigabe erteilt hat). Keine direkten Lernfortschrittsdaten in dieser Tabelle — Fortschritt wird in course_progress und lesson_completions gespeichert (PROJ-248)
OKR-Management (Objectives & Key Results)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Zielvereinbarung und Fortschrittsverfolgung zur effizienten Unternehmenssteuerung)
- OKR-Perioden (okr_periods): Workspace-ID, Periodenname, Periodentyp (Monat/Quartal/Halbjahr/Jahr), Start- und Enddatum, Archivierungszeitpunkt. Keine direkten personenbezogenen Daten
- Objectives (okr_objectives): Workspace-ID, Perioden-ID, Titel, Beschreibung (optional, Freitext), Ebene (Unternehmen/Team/Persönlich/Projekt), Abteilungs-ID, Verantwortliche Person (owner_member_id — Referenz auf workspace_members), Projekt-ID, übergeordnetes Objective, Status-Override. Personenbezug über owner_member_id (identifiziert Mitarbeiter als Verantwortlichen)
- Key Results (okr_key_results): Objective-ID, Workspace-ID, Titel, Typ (Prozent/Zahl/Binär/Währung), Start-/Ziel-/Aktueller Wert, Tracking-Modus (manuell/automatisch via Aufgaben), Verantwortliche Person (owner_member_id). Personenbezug über owner_member_id
- Fortschritts-Updates (okr_kr_updates): Key-Result-ID, neuer Wert, Kommentar (optional, Freitext bis 2.000 Zeichen), Quelle (manuell/automatisch), Ersteller (created_by — User-ID). Kommentare können personenbezogene Informationen enthalten
- Aufgaben-Verknüpfungen (okr_kr_task_links): Junction-Tabelle zwischen Key Results und Aufgaben. Keine direkten personenbezogenen Daten, keine eigene workspace_id (Zugehörigkeit über Key Result → Objective → Workspace)
Preisliste & Rahmenvertrag (digitale Unterzeichnung)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Abschluss einer Rahmenvereinbarung zwischen Agentur und Kunde)
- Preislisten (price_lists): Workspace-ID, Kontakt-ID, Titel, Beschreibung, Gültigkeitstext, Vertragstext, kryptischer Token (UUID) für öffentliche URL, Status (Entwurf/Aktiv/Archiviert). Kontakt-ID referenziert bestehende CRM-Kontakte
- Preislisten-Positionen (price_list_items): Preislisten-ID, Aufgabenvorlagen-ID, Gruppenname, Sortierung, individueller Preis-Override. Keine direkten personenbezogenen Daten
- Preislisten-Unterschriften (price_list_signatures): Preislisten-ID, Name des Unterzeichners, E-Mail des Unterzeichners, Unterzeichnungszeitpunkt (UTC), IP-Adresse (nur für Signing-Dokumentation, nicht für Tracking), Base64-kodierte Unterschrift (Signatur-Bild), JSONB-Snapshot der gesamten Preisliste zum Zeitpunkt der Unterzeichnung (GoBD-unveränderbar). Die IP-Adresse wird ausschließlich zur Dokumentation der Unterzeichnung gespeichert (beweissichere Nachvollziehbarkeit)
- Versand-Protokoll (price_list_send_logs, PROJ-378): Preislisten-ID, User-ID des Absenders (Agentur-Mitarbeiter), Empfänger-E-Mail-Adresse, Ansprechpartner-ID (optional), persönliche Begleitnachricht (optional, max. 2.000 Zeichen), CC- und BCC-Adressen (optional), Versand-Zeitpunkt. Dient der internen Nachvollziehbarkeit wann welche Preisliste an wen versendet wurde
- PROJ-1271 Informative Preisliste (informative_price_lists): Workspace-ID, Titel, Status (draft/active/archived), Erstellungs- und Änderungs-Zeitstempel. Workspace-global — enthält keinen Kontaktbezug, keine User-ID des Erstellers und keine kundenbezogenen Daten. Dient als interne Agentur-Konfiguration für abrufbare Standardleistungen im Retainer-Kontext. Kein Personenbezug
- PROJ-1271 Informative Preislisten-Positionen (informative_pricelist_items): Preislisten-ID, Aufgabenvorlagen-ID (optional FK, bei Löschung der Vorlage auf NULL), Portal-Gruppen-ID (optional FK, bei Löschung der Gruppe auf NULL), Titel, Basispreis, berechnete Gruppenpreise A/B/C/D (NUMERIC), Sichtbarkeits-Flag, Status, Sortierung. Kein Personenbezug — reine Preis- und Leistungskonfiguration
- PROJ-1311 Varianten-Sichtbarkeit pro Position (informative_pricelist_item_variants): Position-ID (FK), Template-Varianten-ID (FK), Aktivierungs-Flag (BOOLEAN). Kein Personenbezug — reine Konfiguration ob eine Variante in der Preisliste angezeigt wird. Wird per CASCADE via item_id gelöscht wenn die Position entfernt wird
Referenzprojekte und Kundenstimmen (Signing-Seite)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an der Darstellung der Agenturleistung gegenüber potenziellen Kunden). Für namentlich genannte Personen in Kundenstimmen: Einwilligung (Art. 6 Abs. 1 lit. a DSGVO), die durch die Agentur dokumentiert wird.
- Referenzprojekte (signing_references): Kundenname (öffentlich oder anonym), Branchenzuordnung, Ergebnisbeschreibung, KPI-Highlight, Projektlogo (optional), Zeitraum, Link zur Case-Study (optional). Werden ausschließlich auf öffentlich zugänglichen Signing-Seiten angezeigt
- Kundenstimmen — Text (signing_testimonials, type='text'): Name des Testimonial-Gebers, Funktion/Position, Unternehmen, Testimonial-Text (max. 500 Zeichen), Profilfoto (optional), Sternebewertung (optional), Branchenzuordnung
- Kundenstimmen — Video (signing_testimonials, type='video'): Name des Testimonial-Gebers, Unternehmen, Videotitel, Video-URL (YouTube/Vimeo) oder Video-Datei (in Supabase Storage), Thumbnail (optional), Kurzbeschreibung
- Logos und Medien: Firmenlogos (Bucket 'signing-logos'), eigene Video-Uploads (Bucket 'signing-videos') — öffentlich lesbar, kein direkter Personenbezug, jedoch möglicherweise unternehmensbezogen
Automatisches Bug-Reporting & KI-Triage
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Fehleridentifikation und Systemstabilität)
- Fehlermeldung und Stack Trace: Technische Fehlerinformationen aus der Browserumgebung
- Browser- und Geräte-Metadaten: User-Agent, Betriebssystem, Bildschirmauflösung, Viewport-Größe, Device Pixel Ratio
- Aktuelle Seiten-URL: Die URL der Seite auf der der Fehler aufgetreten ist
- Screenshot: Automatischer Canvas-Snapshot des aktuellen Viewports zum Fehlerzeitpunkt — Passwort-Felder und Bereiche mit CSS-Klasse 'screenshot-excluded' werden vor dem Snapshot geschwärzt
- Nutzer-ID und Workspace-ID: Zur Zuordnung des Fehlers zum betroffenen Nutzer und Workspace
- KI-Analyse: Fehlermeldung und Stack Trace werden an Claude Haiku (Anthropic) zur Severity-Einschätzung und Fix-Vorschlag übermittelt — keine personenbezogenen Daten im KI-Prompt, nur technische Fehlerinformationen
- Eingeschränkte Member-Sichtbarkeit (PROJ-315): Alle Workspace-Mitglieder können eine vereinfachte Ansicht der Bug-Reports ihres Workspaces sehen — ausschließlich Seitenpfad (ohne Domain), Zeitpunkt, KI-Schweregrad (kritisch/normal) und Bearbeitungsstatus. Stack Trace, Screenshots, User-Agent und Fehlermeldung bleiben ausschließlich für Plattform-Admins sichtbar
- Release-Bug-Meldungen (PROJ-448): Agentur-Mitglieder können auf der /updates-Seite manuell einen Bug zu einem konkreten Release melden. Zusätzlich zu den oben genannten Metadaten wird eine Release-Referenz (app_release_id) sowie eine vom Einreicher geschriebene Freitext-Beschreibung (user_description, max. 5.000 Zeichen) gespeichert. Der Freitext geht gemeinsam mit der technischen Fehlermeldung in die KI-Severity-Triage ein — Anthropic Claude Haiku ist bereits als Auftragsverarbeiter aufgeführt, es kommen keine neuen externen Dienste hinzu. Die Release-Referenz bleibt beim Löschen des Release-Eintrags als NULL erhalten (ON DELETE SET NULL), damit die Meldungshistorie GoBD-konform dokumentiert bleibt
- Mehrfach-Anhänge (PROJ-1520): Bei einer manuellen Release-Bug-Meldung können bis zu 10 Anhänge statt nur eines Screenshots hochgeladen werden — zusätzlich zu Bildern (PNG/JPEG/WebP) jetzt auch PDF- und Textdateien (max. 10 MB je Datei). Der erste Bild-Anhang bleibt in der bestehenden screenshot_path-Spalte, Anhänge 2–10 (bzw. 1–10 falls der erste Anhang kein Bild ist) liegen in einer neuen Tabelle bug_report_attachments (Speicherort, Original-Dateiname, MIME-Typ, Position). Gleicher Storage-Bucket, gleiche Zugriffsbeschränkung (ausschließlich Platform-Admins, RLS-verifiziert) und gleiche 90-Tage-Löschfrist wie der bestehende Screenshot — keine neue Datenkategorie, nur eine Mengen- und Formaterweiterung. Die zusätzlichen Dateitypen (PDF/Text) können ein breiteres Spektrum an Inhalten enthalten als ein reiner Screenshot (z.B. Log-Auszüge mit technischen Details) — die einreichende Person wählt die Anhänge bewusst aus, keine automatische Erfassung. Anhänge werden NICHT in den Workspace-Datenexport aufgenommen (analog zum bestehenden Screenshot-Ausschluss, siehe deletionConcept), sind aber Teil der Dev-Session-Anhang-Pipeline für Lokal-Sessions (PROJ-806, dort dokumentiert)
- PROJ-663 Status-Historie (entwicklung_status_history): Pro manuellem oder automatischem Status-Wechsel eines Bug-Reports wird ein Audit-Eintrag gespeichert. Felder: entity_type=bug_report, entity_id, workspace_id, from_status, to_status, changed_by_user_id (UUID des Workspace-Mitglieds — NULL bei System-Trigger), changed_by_system_label (z. B. deploy-hook, nw-complete), optionale Notiz (max. 280 Zeichen Freitext), Zeitstempel. Sichtbarkeit: alle aktiven Mitglieder des Workspaces (admin/manager/member). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Nachvollziehbarkeit von Workflow-Entscheidungen im Team). Bei User-Löschung: changed_by_user_id wird auf NULL gesetzt (ON DELETE SET NULL); der Audit-Eintrag bleibt mit anonymisierter Aktor-Referenz erhalten. Datenexport (Art. 15/20): im Workspace-Datenexport enthalten. CASCADE-Löschung bei Workspace-Löschung; polymorpher Cleanup-Trigger entfernt zugehörige Audit-Einträge bei Löschung des Bug-Reports
- PROJ-676: parent_bug_report_id (UUID, nullable) verkettet Folge-Meldungen mit Ursprungs-Bug für Nachvollziehbarkeit unzureichender Fixes. CASCADE-Verhalten: ON DELETE SET NULL — bei Löschung des Ursprungs-Bugs bleibt der Folge-Bug als eigenständige Meldung erhalten. Kein neuer Personenbezug, reine Selbst-Referenz innerhalb bug_reports.
- PROJ-677: Verified-Signal (verified_at, verified_by_user_id) — Self-Approval-Bestätigung des Einreichers, dass der Fix passt. Nur der ursprüngliche Einreicher (bug_reports.user_id) darf den Verified-Toggle setzen; Admin/Manager können fremde Verified-Spuren lesen, aber nicht selbst verifizieren. Sichtbar für alle Workspace-Mitglieder (Spalte: Geprüft am / Geprüft von), dauerhaft im Audit-Trail. Bei Re-Open eines Bugs werden beide Verified-Spalten automatisch auf NULL zurückgesetzt; ein History-Eintrag (changed_by_system_label=unverified_by_reopen) dokumentiert den Reset. Bei Account-Löschung des Prüfers: verified_by_user_id ON DELETE SET NULL — Geprüft-am-Zeitstempel bleibt mit anonymisierter Aktor-Referenz erhalten. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Nachvollziehbarkeit der Fix-Bestätigung im Team).
- PROJ-978 Status-Integritäts-Abgleich (Sicherheitsnetz): Ein täglicher Cron (bug-status-reconcile) gleicht offene Bug-Reports (user_description/Fehlermeldung) UND offene Feature-Wünsche (feedback_submissions.description) semantisch gegen die letzten Release-Changelogs ab und markiert wahrscheinlich-behobene bzw. Duplikat-Kandidaten. Dazu werden Titel/Beschreibungen transient an Claude Sonnet 4.6 (Anthropic, Auftragsverarbeiter — siehe PROCESSORS) übermittelt; kein Training, keine Persistenz bei Anthropic. In der eigenen DB werden nur Markierungsfelder gesetzt (likely_resolved_by_release_id/confidence/reason/checked_at/rejected_at, likely_inprogress_proj, likely_duplicate_of). Die Markierung ändert den Status NICHT automatisch — ein Admin/Manager bestätigt manuell (Aktion bestätigen/in-Arbeit/Duplikat/verwerfen). Zusätzlich prüft ein Deployed-Guard vor dem Setzen auf behoben, ob der Fix-Commit live ist (GitHub-Vergleich, nur technischer Commit-Hash, keine Personendaten). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO. likely_resolved_by_release_id ON DELETE SET NULL bei Release-Löschung; alle Markierungsfelder werden mit dem Bug-Report (90-Tage-Cleanup) bzw. dem Feature-Wunsch gelöscht.
Gast-Chat auf der Signing-Seite
Rechtsgrundlage: Art. 6 Abs. 1 lit. a DSGVO (Einwilligung — explizite Zustimmung durch Checkbox beim Chat-Start, informiert über 90-Tage-Speicherdauer und Zweck der Angebotsberatung)
- Gast-Name: Frei gewählter Name des Chat-Teilnehmers (max. 200 Zeichen), vorausgefüllt mit dem Namen aus dem Angebot
- Chat-Nachrichten (signing_guest_chat_messages): Nachrichtentext (max. 2.000 Zeichen), Absender-Typ (Gast/Mitarbeiter), Zeitstempel
- Chat-Metadaten (signing_guest_chats): Angebots-Referenz, Ansprechpartner-Referenz, Einwilligungszeitpunkt, Zeitstempel der letzten Nachricht
- Native macOS Companion App (PROJ-549): Der zugewiesene Ansprechpartner kann Gast-Chats zusätzlich zur Web-App über die NEULAND. OS Companion App lesen und beantworten. Die App ruft die Daten über dedizierte Companion-Endpunkte (/api/companion/chat/guest-chats/*) ab — Bearer-Token-Authentifizierung, Mitgliedschafts-Check via signing_guest_chats.member_id. Auf dem Gerät werden Nachrichten ausschließlich im Arbeitsspeicher der App gehalten (keine lokale Persistenz). Live-Updates erfolgen über kurzes Polling (5 Sekunden) der Companion-API, da die signing_guest_chat_messages-Tabelle nicht in der Realtime-Publikation ist. Es entsteht kein neuer Auftragsverarbeiter — die Verarbeitung erfolgt weiterhin in NEULAND. OS (Supabase + Vercel)
Bedarfsgruppen URL-Alias-Historie (PROJ-281)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Dokumentation von URL-Änderungen an Website-Seitenstrukturen als Teil der Marketing-/Webentwicklungs-Dienstleistung)
- URL-Alias-Einträge (ssot_items.data.url_aliases, JSONB-Array): Alte URL, Änderungszeitpunkt (changed_at), Verursacher der Änderung (changed_by — User-ID). Die changed_by-Spalte stellt einen Personenbezug her (Nutzerkennung). Maximal 50 Einträge pro Seite
- Bedarfsgruppen-Status-Konfiguration (bedarfsgruppen_statuses): workspace_id, Name, Farbe, Position, Default-Flag, Erstellungszeitpunkt. Keine personenbezogenen Daten
Bedarfsgruppen Staging & Entwurfsmodus (PROJ-326)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Staging-Entwürfe als Teil der Website-Strategieberatung)
- Staging-Sets (bedarfsgruppen_staging_sets): Entwurfsname (optional, Freitext), Kontakt-Zuordnung (contact_id), Ersteller (created_by — User-ID), Share-Token (kryptischer UUID-Link), Share-Status, optionaler PIN-Schutz (pin_hash, pin_salt, pin_updated_at). created_by stellt einen Personenbezug her
- Segment-Zuordnung des Entwurfs (segment_id, PROJ-1544): Optionale Referenz auf crm_segments (leer = globaler Entwurf für den ganzen Kontakt). Ein Kontakt kann ab sofort mehrere gleichzeitig offene Entwürfe haben — maximal einen pro Segment. Reine Organisationszuordnung, kein zusätzlicher Personenbezug (analog der Bewertung des crm_segments-Eintrags aus PROJ-1538). Übernimmt ein Mitarbeiter im Segment-Kontext einen Vorschlag für einen bislang global geltenden Live-Eintrag, entsteht eine neue, eigenständige Kopie ausschließlich für dieses Segment (is_global=false, was_global=true) — das globale Original bleibt unverändert für alle anderen Segmente bestehen. Diese Kopien sind gewöhnliche ssot_items-Zeilen ohne neue Datenkategorie
- Staging-Items (ssot_items mit staging_set_id IS NOT NULL): Kopien der Live-Bedarfsgruppen-Seiten mit Staging-Kontext. Gleiche Datenstruktur wie reguläre ssot_items. Referenz auf Live-Pendant (live_item_id) und Soft-Delete-Marker (deleted_in_staging)
- Öffentliche Preview-Seite (/bedarfsgruppen-preview/[token]): Ohne Login aufrufbar. Zeigt Staging-Struktur als read-only in zwei wählbaren Darstellungsoptionen (Listenansicht oder Mindmap). Die Mindmap-Ansicht nutzt die clientseitige Bibliothek @xyflow/react (keine externen API-Aufrufe). Zwei localStorage-Einträge (bdg_preview_view_mode, bdg_preview_show_system_pages) speichern die vom Nutzer gewählte Ansicht und den Filter-Status für System-Fehlerseiten (401/403/404/503). Die Werte sind rein literale Strings ohne Personenbezug und gelten nach §25 Abs. 2 Nr. 2 TDDDG als technisch unbedingt erforderlich (keine Einwilligung nötig, analog zu Theme-Präferenzen). noindex-Meta-Tag verhindert Indexierung. IP-Adresse temporär für Rate Limiting (100 Aufrufe/Minute, < 1 Stunde in Redis)
- Optionaler PIN-Schutz: Der Ersteller kann einen 4-stelligen PIN setzen, den Empfänger auf der öffentlichen Vorschauseite eingeben müssen, um den Entwurf zu sehen. Der PIN wird clientseitig per POST an /api/bedarfsgruppen-preview/public/[token]/verify-pin übermittelt und serverseitig mit PBKDF2-SHA256 (100.000 Iterationen, 16-Byte Salt) gegen den gespeicherten Hash verglichen. Der Klartext-PIN wird nie persistiert. Nach erfolgreicher Validierung erhält der Browser ein HMAC-Signatur-Session-Token (1 Stunde gültig), das tab-lokal in sessionStorage gespeichert und bei nachfolgenden Requests im Header x-bedarfsgruppen-session mitgesendet wird. SessionStorage-Eintrag ist rein technisch für die Authentifizierung erforderlich (§25 Abs. 2 Nr. 2 TDDDG). Brute-Force-Schutz: 5 PIN-Versuche/Stunde pro IP+Token in Redis
- CI-Entwurfs-Knoten (ssot_items mit ci_status='ci_proposed' oder 'ci_rejected', PROJ-953 deployed 2026-06-06): Temporaere Bedarfsgruppen-Entwuerfe die das CI-System beim Human-Validation-Gate anlegt. Felder: ci_status, update_source='content_intelligence', update_source_id=job_id (FK auf content_intelligence_jobs). Inhalte: Seitenname + Cluster-Rolle aus KI-Output (keine PII). PROJ-1937 (2026-08-06/07): Zwei Klassifikationsfelder liegen seither in eigenen Feldern statt in data.seitentyp. (1) data.cluster_rolle (pillar/subtopic/conversion_asset) — die Cluster-Rolle aus dem KI-Output; derselbe Wert wie vorher, nur an anderer Stelle im selben JSONB-Objekt. (2) data.katalog_bedarf (blog/news/termine/referenzen/produkte) — welchen Inhaltskatalog eine Seite benötigt; wird redaktionell gesetzt, nicht abgeleitet. Beides sind Inhaltsklassifikationen ohne Personenbezug, keine neue Datenkategorie. Beide sind im Workspace-Datenexport enthalten, weil dieser das vollstaendige data-Objekt ausgibt. Workspace-scoped, admin/manager-only (RLS analog Live-Bedarfsgruppen). Cleanup: pg_cron loescht ci_proposed-Knoten wenn Job > 30 Tage in awaiting_human_validation. Data-Export: ci_proposed-Knoten werden nicht exportiert (gefiltert). Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO
- DSGVO-Datenexport (Art. 15/20): bedarfsgruppen_staging_sets und Staging-ssot_items sind im Workspace-Datenexport enthalten (GET /api/workspaces/data-export). share_token, pin_hash und pin_salt werden aus Sicherheitsgründen nicht exportiert — der Export enthält stattdessen has_pin (boolean) und pin_updated_at (Zeitstempel). Seit PROJ-1544 zusätzlich segment_id im Export enthalten
- KI-Assistent Bedarfsgruppen-Generierung (PROJ-1100): Der Zwei-Personas-Wizard (Berater → Executor → Freigabe) hält Job-IDs und Zwischenergebnisse ausschließlich im flüchtigen React-State des geöffneten Sheets (kein localStorage, keine Persistenz über Seiten-Reload hinweg). Persistiert werden nur Server-seitig die Jobs in ki_bedarfsgruppen_jobs und die Content-Gap-Entscheidungen in ki_bedarfsgruppen_gap_entscheidungen (entschieden_von = User-ID, Rechtsgrundlage Art. 6 Abs. 1 lit. b DSGVO)
Bedarfsgruppen-Strukturprüfung (PROJ-1864)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Qualitätssicherung der Website-Seitenstruktur als Teil der Marketing-/Webentwicklungs-Dienstleistung)
- Validierungsläufe (struktur_validierung_runs): Kontakt- und Workspace-Zuordnung, optionales Entwurfs-Set, Auslöser (Änderung, täglich, manuell, vor Generierung), Start- und Endzeit, Dauer, Zustand, Anzahl Befunde je Schweregrad, Bereitschaftsflag, Fehlertext. Keine personenbezogenen Daten — der Lauf beschreibt einen Seitenbaum, keine Person
- Befunde (struktur_validierung_befunde): Befundtyp, Schweregrad, betroffene Seiten-IDs und Klartext-Begründung. Die Begründung enthält Seitenbezeichnungen und URLs der Kundenwebsite (B2B-Organisationsdaten), keine personenbezogenen Daten
- Seitenrollen (struktur_seitenrollen): je Seite zwei abgeleitete Kennzahlen (Reichweite und Conversion, 0–100), Hauptrolle, Begründung, herangezogene Felder und Rohwerte, Herkunft (berechnet oder manuell). Bei manueller Setzung zusätzlich gesetzt_von (User-ID) und gesetzt_am — gesetzt_von stellt einen Personenbezug her (Mitarbeiterkennung, analog created_by bei Staging-Sets)
- Platzierungsvorschläge (struktur_platzierungsvorschlaege): vorgeschlagenes Elternteil, Position, Navigationsebene, Begründung, Sicherheitswert, Empfehlung, Bearbeitungszustand. Bei Entscheidung zusätzlich entschieden_von (User-ID) und entschieden_am — entschieden_von stellt einen Personenbezug her
- Prüf-Markierung (struktur_validierung_marker): Kontakt- und Workspace-Zuordnung plus Zeitstempel. Transiente Warteschlange, wird nach Abarbeitung geleert. Keine personenbezogenen Daten
- Keine KI-Verarbeitung in Prüflauf und Seitenrolle: Die Seitenrolle wird über eine feste Zuordnungstabelle aus bereits vorhandenen SSoT-Feldern (Seitenziel, primärer KPI, Navigationsebene) berechnet, der Prüflauf selbst arbeitet regelbasiert. Weder dabei noch beim Aufbau des Strukturkontexts werden Daten an ein Sprachmodell übermittelt. Ausnahme ist ausschließlich die unten genannte Erzeugung von Korrekturvorschlägen (PROJ-1886)
- Regelwerk-Grundeinstellung (struktur_regelwerk_grundeinstellung, PROJ-1885): je Workspace ein Konfigurationssatz — Schweregrad/Aktiv-Zustand/Geltungsbereich/Punktkosten/Dimension je Regel, die Pflichtfeld-Matrix und die Liste kanonik-geprüfter Felder. Reine Konfiguration, keine personenbezogenen Daten
- Regelwerk-Kunden-Abweichung (struktur_regelwerk_kunden_abweichung, PROJ-1885): je Kunde höchstens ein Konfigurationssatz mit den Abweichungen von der Workspace-Grundeinstellung. Reine Konfiguration, keine personenbezogenen Daten
- Befund-Zustand (struktur_befund_zustand, PROJ-1885): Lebenszyklus eines Befunds (offen/gelöst/verworfen/veraltet) je Kunde, gebunden an ein stabiles fachliches Merkmal (Befundtyp + betroffene Seiten-IDs) statt an die bei jedem Lauf wechselnde Befund-ID. Bei Verwerfen zusätzlich Begründung, Zeitpunkt und zustand_geaendert_von (User-ID) — zustand_geaendert_von stellt einen Personenbezug her (Mitarbeiterkennung, analog gesetzt_von/entschieden_von oben). Seit PROJ-1886 zusätzlich: loesungsweg (übernommener Vorschlag oder selbst eingetragene Lösung) und uebernommener_vorschlag_id (Verweis auf den übernommenen Korrekturvorschlag). Seit PROJ-1889 zusätzlich loesungsweg-Wert 'wizard_uebernommen' und wizard_lauf_id (Verweis auf den Wizard-Lauf, ON DELETE SET NULL — 'Lösungsweg ist eine historische Tatsache', analog uebernommener_vorschlag_id). Wird eine Lösung selbst eingetragen, steht ihr Freitext in derselben Begründungsspalte
- Wizard-Läufe (struktur_wizard_laeufe, PROJ-1889): je Sammel-Übernahme des KI-Optimierungsassistenten ein Protokolleintrag (nicht je Öffnen) — die im Wizard angezeigten Schritte und Wege (schritte), die getroffenen Entscheidungen je Schritt inkl. 'übersprungen' (entscheidungen), Score vorher/Vorschau/nachher sowie je Weg das Ergebnis (erfolgreich/gescheitert mit fachlichem Grund). Zusätzlich ausgefuehrt_von (User-ID) — stellt einen Personenbezug her, analog zustand_geaendert_von/gesetzt_von/entschieden_von. Enthält keine personenbezogenen Daten der Kundenwebsite über das hinaus, was ohnehin in den zugrundeliegenden Korrekturvorschlägen steht (Titel/Beschreibung der Wege, keine Feldwerte — die Bündelung selbst erzeugt keine)
- Korrekturvorschläge (struktur_korrekturvorschlaege, PROJ-1886): je Befund bis zu drei Vorschläge, wie er zu beheben ist — Titel, Empfehlungskennzeichen, Konfidenzwert 0–100, strukturierter Änderungsvorschlag (Feld, bisheriger Wert, vorgeschlagener Wert), Begründungstext, herangezogene Quellen sowie ein Fingerabdruck der betroffenen Seiten zum Erzeugungszeitpunkt. Enthält keine personenbezogenen Daten — wer einen Vorschlag übernommen hat, steht am Befund-Zustand, nicht am Vorschlag. Ein Vorschlag wird niemals automatisch angewendet; jede Änderung an der Struktur setzt eine ausdrückliche Übernahme durch einen Menschen voraus
- KI-Verarbeitung bei Korrekturvorschlägen (PROJ-1886): Die Vorschläge werden von einem Sprachmodell erzeugt — erst beim Öffnen eines Befunds, danach gespeichert, nicht bei jedem Prüflauf im Voraus. Übermittelt werden ausschließlich Strukturdaten der Kundenwebsite: Seitenbezeichnungen, Adressen, Navigationsebene, Segmenttyp und die weiteren SSoT-Konfigurationsfelder der betroffenen Seiten (B2B-Organisationsdaten). Personenbezogene Daten werden nicht übermittelt; Freitextanteile durchlaufen zusätzlich die etablierte Bereinigung, bevor sie in den Prompt gelangen
- Verbindungsvorschläge (struktur_verbindungsvorschlaege, PROJ-1887): vorgeschlagene interne Verweise zwischen zwei Seiten desselben Kunden — Ausgangs- und Zielseite, Anlass des Vorschlags (Hierarchie, Seitenrolle, Segment oder gemeinsames Suchwort), ein Vorschlag für den Ankertext, eine Begründung in einem Satz und der Berechnungszeitpunkt. Keine personenbezogenen Daten und keine Mitarbeiterkennung: die Vorschläge werden ausschließlich maschinell berechnet, niemand trägt sie ein. Kein Sprachmodell beteiligt — die Berechnung ist regelbasiert und deterministisch, wie Seitenrolle und Prüflauf
- Ist-Kanten der internen Verlinkung (struktur_ist_verbindungen, PROJ-1888): je Prüflauf ermittelte tatsächliche Verweise zwischen zwei Seiten desselben Kunden — Ausgangs- und Zielseite, Herkunft (navigation oder inhalt), Kennzeichen für eine domainübergreifende Kante und der Ermittlungszeitpunkt. Keine personenbezogenen Daten außer der Zuordnung zum Kunden — die Kanten werden ausschließlich maschinell aus dem CMS-Seitenbaum und den Inhalten der Website gelesen, niemand trägt sie ein
- Angelegte Verweise (struktur_angelegte_verweise, PROJ-1888): Buchführung über Verweise, die über die Oberfläche des Tabs 'Verlinkung' ins CMS geschrieben wurden — Ausgangs- und Zielseite, die betroffene CMS-Seite, der verwendete Ankertext und die Kennung des erzeugten Eintrags im Verweis-Block, damit eine Rücknahme möglich ist. Zusätzlich angelegt_von (User-ID) und angelegt_am sowie bei Rücknahme zurueckgenommen_von (User-ID) und zurueckgenommen_am — angelegt_von und zurueckgenommen_von stellen einen Personenbezug her (Mitarbeiterkennung, analog gesetzt_von/entschieden_von oben)
- KI-Verarbeitung bei der Wizard-Bündelung (PROJ-1889, Bugfix AC-B1 04.08.2026): Ein zweiter, separater KI-Aufruf — anderer Zweck als PROJ-1886, bündelt beim Öffnen des Wizards die bereits erzeugten Korrekturvorschläge des gesamten offenen Befundbestands eines Kunden zu Entscheidungsschritten und erklärt sie, erzeugt selbst keine Feldwerte/Diffs. Übermittelt werden je Befund dieselben Seitenbezeichnungen/Adressen/Konfigurationsfelder wie bei PROJ-1886 plus die Vorschlagstitel, außerdem Punktkosten (Zahl) und Score-Dimension (fester Kategoriename, kein Freitext), dazu eine aggregierte SSOT-Kontext-Zeile mit Gesamtseitenzahl und Seitenzahl je Segment-Bezeichnung des Kunden. Personenbezogene Daten werden nicht übermittelt; alle Freitextanteile (Seitenbezeichnungen, Vorschlagstitel, Segment-Bezeichnungen) durchlaufen dieselbe Bereinigung (sanitizeForPrompt)
- DSGVO-Datenexport (Art. 15/20): Alle Tabellen des Strukturmoduls sind im Workspace-Datenexport enthalten (GET /api/workspaces/data-export), einschließlich struktur_korrekturvorschlaege, struktur_verbindungsvorschlaege, struktur_ist_verbindungen, struktur_angelegte_verweise und struktur_wizard_laeufe (PROJ-1889). Der Kontakt-Datenexport (GET /api/contacts/:id/data-export), der an den Kunden herausgegeben wird, umfasst die elf kontaktbezogenen Tabellen — die vier ursprünglichen plus struktur_regelwerk_kunden_abweichung, struktur_befund_zustand, struktur_korrekturvorschlaege, struktur_verbindungsvorschlaege, struktur_ist_verbindungen, struktur_angelegte_verweise und struktur_wizard_laeufe. Ausgenommen sind dort gesetzt_von, entschieden_von, zustand_geaendert_von, angelegt_von, zurueckgenommen_von und ausgefuehrt_von — sie identifizieren Agentur-Mitarbeiter, nicht den Kunden. struktur_validierung_marker bleibt aus dem Kontakt-Export heraus (transiente Warteschlange ohne Inhalte), struktur_regelwerk_grundeinstellung ebenfalls (je Workspace ein Satz, kein Kontaktbezug)
Seitentext-Erzeugung aus Bedarfsgruppen-Knoten (PROJ-1865)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — KI-gestützte Texterstellung als Teil der Website-/Content-Dienstleistung)
- Läufe (ci_seitentext_laeufe): Kontakt- und Workspace-Zuordnung, der Bedarfsgruppen-Knoten und ggf. die CMS-Seite für die Text erzeugt wird, optionales Entwurfs-Set, verwendeter Strukturprüfungs-Stand (PROJ-1864) samt Zeitpunkt, Erzeugungsweg (fest 'seitentext', zur Unterscheidung vom Cluster-/Keyword-Weg), Iterationsnummer (wiederholte Läufe überschreiben nicht), Modellname, Status, Zeiten, Fehlertext und ein Veraltet-Kennzeichen falls sich der Seitenbaum während des Laufs änderte. Keine personenbezogenen Daten — der Lauf beschreibt eine Seite, keine Person
- Abschnitte (ci_seitentext_abschnitte): erzeugter Text je Abschnitt mit benanntem fachlichem Zweck (z.B. Einstieg/Nutzen/Beleg/CTA) und optionalem Lesbarkeitswert. B2B-Website-Inhalt, keine personenbezogenen Daten
- Claims (ci_seitentext_claims): je Abschnitt eine oder mehrere geprüfte inhaltliche Aussagen mit Herkunfts-Zustand (belegt/generiert/offene Frage), Quelltyp, Risikotyp und Konfidenzwert. Keine personenbezogenen Daten
- Keywords (ci_seitentext_keywords): Ziel- und tatsächlich erreichte Keyword-Dichte je Lauf. Keine personenbezogenen Daten
- Interne Links inkl. CTA (ci_seitentext_links): Ziel-Seiten-ID (ausschließlich aus der von PROJ-1864 gelieferten Linkziel-Liste, nie eine freie URL), Ankertext, Begründung, CTA-Kennzeichen und zugehöriges Marketingziel. Keine personenbezogenen Daten
- Scores (ci_seitentext_scores): Quantifizierung (SEO-/GEO-Sicht und Einzelfaktoren) je Element (Abschnitt/Claim/Keyword/Link) — Metrik-Typ, Wert und Berechnungsgrundlage. Keine personenbezogenen Daten
- Befunde (ci_seitentext_befunde): Informationslücken, verworfene Linkvorschläge, Konflikte und der Hinweis auf einen während des Laufs veralteten Seitenbaum, je mit Begründung und Folge. Keine personenbezogenen Daten
- KI-Verarbeitung (Claude, callCiPhaseAnthropic — derselbe Helfer wie bei den übrigen Content-Intelligence-Erzeugungswegen): Erzeugt aus dem Bedarfsgruppen-Knoten gegliederten Seitentext. Übermittelt werden ausschließlich Strukturdaten der Kundenwebsite und der Marketingstrategie — Seitenbezeichnung/-pfad/-typ/-ziel/-KPI, die zuletzt ermittelte Seitenrolle (Reichweite-/Conversion-Score), Marketingziele, Zielgruppen/Personas und USPs aus der SSOT sowie die Corporate-Language-Vorgaben und die zulässigen internen Linkziel-IDs. Freitextanteile aus der Datenbank (Persona/USP/Marketingziel/Corporate-Language) sind vor der Prompt-Zusammenstellung bereits R-1446-sanitisiert. Keine personenbezogenen Daten; kein Training, kein automatisches Veröffentlichen — der erzeugte Text landet zunächst als Entwurf in den obigen Tabellen und durchläuft erst danach eine ausdrückliche menschliche Prüfung/Übernahme (Debugging-Bereich, PROJ-1868)
- DSGVO-Datenexport (Art. 15/20): Alle 7 Tabellen der Seitentext-Pipeline sind sowohl im Workspace-Datenexport (GET /api/workspaces/data-export) als auch im Kontakt-Datenexport (GET /api/contacts/:id/data-export) enthalten — keine der Tabellen führt eine Mitarbeiter-Actor-Spalte, daher keine Ausnahme zwischen beiden Exporten (anders als beim Strukturmodul PROJ-1864). PROJ-2112 (Zielwert-getriebene Generierung): Die Iterations-Historie-Spalte ci_seitentext_laeufe.zielwert_verlauf (Gate-Scores/Klassifikationen je Nachbesserungs-Runde, keine personenbezogenen Daten) und der Befundtyp ci_seitentext_befunde.befundtyp='kundeninput_erforderlich' (kundengerichteter Hinweistext bei fehlender inhaltlicher Grundlage) sind in beiden Exporten mit enthalten
Wireframe-Erzeugung aus Seitentext (PROJ-1866)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — KI-gestützte Seitenstruktur-/Wireframe-Erstellung als Teil der Website-/Content-Dienstleistung). Die Mitarbeiter-Actor-Spalten (Urheber von Faktor-Änderungen) zusätzlich Art. 6 Abs. 1 lit. f DSGVO / Art. 88 BDSG (berechtigtes Interesse an der Nachvollziehbarkeit interner Bearbeitungsschritte)
- Läufe (wireframe_ki_laeufe): Kontakt- und Workspace-Zuordnung, der Bedarfsgruppen-Knoten und ggf. die CMS-Seite, optionales Entwurfs-Set, der zugrunde gelegte Seitentext-Lauf (PROJ-1865) und Strukturstand samt Zeitpunkten, Iterationsnummer (wiederholte Läufe überschreiben nicht), Modellname, Status, Zeiten, Fehlertext und ein Veraltet-Kennzeichen falls der Textstand während des Laufs ersetzt wurde. Keine personenbezogenen Daten — der Lauf beschreibt eine Seite, keine Person
- Elemente (wireframe_ki_elemente): je Wireframe-Element die frei gewählte Elementart, der fachliche Zweck, eine Begründung, ein Confidence-Wert je Element und die Herkunft des Reasonings (durchgereicht aus PROJ-1865 oder neu). B2B-Website-Inhalt, keine personenbezogenen Daten
- Element↔Abschnitt-Zuordnung (wireframe_ki_element_abschnitte) und ausdrücklich weggelassene Abschnitte mit Begründung (wireframe_ki_nicht_uebernommen): welcher PROJ-1865-Textabschnitt zu welchem Element gehört bzw. warum ein Abschnitt nicht übernommen wurde. Keine personenbezogenen Daten
- Ziele interaktiver Elemente (wireframe_ki_element_ziele): Ziel-Seiten-ID (ausschließlich aus der von PROJ-1864 gelieferten Linkziel-Liste, nie eine freie URL) bzw. benanntes Marketingziel. Keine personenbezogenen Daten
- Textänderungs-Protokoll (wireframe_ki_textaenderungen): je Kürzung/Umformulierung eines Textabschnitts der Ausgangstext neben dem Ergebnistext plus Grund — abgeleiteter B2B-Website-Text, keine personenbezogenen Daten
- Selbstgesetzte Bewertungs-Faktoren (wireframe_ki_faktoren): frei benannte Faktoren mit Bezeichnung, Beschreibung, Klartext-Messvorschrift, aktuellem und ursprünglich von der KI vorgeschlagenem Gewicht, Aktiv-Zustand und Herkunft (ki/mensch). Bezeichnung/Beschreibung/Messvorschrift sind durch Admin/Manager als Freitext (bis 2.000 Zeichen) editierbar — kein Personenbezug im Inhalt, aber erstellt_von und geaendert_von (User-IDs) identifizieren Agentur-Mitarbeiter (Mitarbeiterkennung, analog gesetzt_von/entschieden_von im Strukturmodul)
- Faktor-Änderungsverlauf (wireframe_ki_faktor_historie): je geänderter Spalte eine Zeile mit Feldname, altem und neuem Wert sowie urheber (User-ID) — urheber stellt einen Personenbezug her (Mitarbeiterkennung)
- Bewertungen (wireframe_ki_bewertungen): je Element×Faktor ein Zahlenwert mit Begründung. Keine personenbezogenen Daten
- Befunde (wireframe_ki_befunde): Informationslücken, fehlende Handlungsaufforderung, Keyword-Abweichung, Faktor-Konflikt, veralteter Textstand und Abschnitts-Überschneidung, je mit Begründung, Folge und Schweregrad. Keine personenbezogenen Daten
- KI-Verarbeitung (Claude, callCiPhaseAnthropic — derselbe Helfer wie bei den übrigen Content-Intelligence-Erzeugungswegen): Erzeugt aus dem Seitentext-Lauf und dem Strukturkontext eine geordnete Wireframe-Elementliste. Übermittelt werden ausschließlich Strukturdaten der Kundenwebsite (Seitenbezeichnung/-typ/-ziel, zulässige interne Linkziele), der bereits R-1446-sanitisierte Seitentext (Abschnitte/Claims/Links aus PROJ-1865) sowie die von Admin/Manager gesetzten, ebenfalls R-1446-sanitisierten Faktoren-Freitexte (Bezeichnung/Beschreibung/Messvorschrift). Keine personenbezogenen Daten; kein Training, kein automatisches Veröffentlichen — das Wireframe landet als Entwurf in den obigen Tabellen und durchläuft erst danach eine ausdrückliche menschliche Prüfung
- DSGVO-Datenexport (Art. 15/20): Alle 10 Tabellen der Wireframe-Pipeline sind sowohl im Workspace-Datenexport (GET /api/workspaces/data-export) als auch im Kontakt-Datenexport (GET /api/contacts/:id/data-export) enthalten. Im Kontakt-Datenexport, der an den Kunden herausgegeben wird, sind die Mitarbeiter-Actor-Spalten erstellt_von, geaendert_von und urheber ausgenommen (sie identifizieren Agentur-Mitarbeiter, nicht den Kunden); die Agentur-Default-Faktoren (contact_id NULL) sind dort ebenfalls nicht enthalten, da sie dem Workspace und nicht dem Kontakt gehören
Bedarfsgruppen-Vorschau Kunden-Anmerkungen (PROJ-471)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Kunden-Feedback zur Bedarfsgruppen-Seitenstruktur im Rahmen der Agenturdienstleistung)
- Kunden-Anmerkungen (bedarfsgruppen_preview_annotations): Freitext-Anmerkungen (1–2.000 Zeichen) die der Kunde über die öffentliche Vorschau-Seite pro Bedarfsgruppen-Seite hinterlassen kann. Pro Staging-Seite ist max. 1 Anmerkung möglich (Upsert-Pattern — spätere Eingaben überschreiben frühere). Die Anmerkung kann personenbezogene Daten enthalten (Kunde entscheidet selbst über den Inhalt). Keine User-Session oder IP-Speicherung — der Zugriff erfolgt ausschließlich über den kryptischen Share-Token des Staging-Sets (+ optionalen PIN-Schutz des Parent-Features PROJ-326). Rate Limiting: 10 Schreibvorgänge/Minute pro IP (temporär in Redis, < 1 Stunde)
- Inbox-Notification für Agentur: Bei neuer oder geänderter Anmerkung erhalten aktive admin/manager/member des Workspaces eine Inbox-Benachrichtigung (notifications.type = 'bedarfsgruppen_preview_annotation_added'). Die Notification enthält einen Auszug der Anmerkung (max. 100 Zeichen) in metadata.annotation_preview sowie Referenz auf ssot_item_id und staging_set_id. Deduplication: Wenn bereits eine ungelesene Notification für dieselbe Seite existiert, wird kein neuer Eintrag erstellt
- DSGVO-Datenexport (Art. 15/20): bedarfsgruppen_preview_annotations sind im Workspace-Datenexport enthalten (GET /api/workspaces/data-export). Zusätzlich werden die Anmerkungen im Agentur-Dashboard unter SSOT → Bedarfsgruppen → Staging-Status-Bar angezeigt (read-only für die Agentur — nur der Kunde selbst kann seine Anmerkungen via Share-Link editieren oder löschen)
App-Updates & Release-Changelog
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Information der Agentur-Mitglieder über Plattform-Änderungen im Rahmen der SaaS-Dienstleistung)
- Release-Einträge (app_releases): Titel, Beschreibung, Typ (Feature/Verbesserung/Bugfix), PROJ-Referenz, Veröffentlichungszeitpunkt, Ersteller-User-ID (created_by_user_id — Personenbezug), plattform-spezifische Download-Felder (macos_storage_path: Pfad in Storage-Bucket native-releases; ios_testflight_url: TestFlight-Einladungslink — beide technische Felder ohne Personenbezug). Globale Tabelle ohne Workspace-Bezug
- Native-App-Distribution (PROJ-617, Storage-Bucket native-releases): Privater Supabase-Storage-Bucket mit den signierten macOS-Companion-App-ZIP-Bundles. Inhalt enthält ausschließlich die kompilierte App (Sourcecode-Bundle + Apple-Notarization-Stapling) — keine personenbezogenen Daten. Zugriff ausschließlich vom Server via createSignedUrl (30 min TTL, gegen Auth-Check), nie öffentlich zugänglich. Download-Triggers werden nicht protokolliert (kein User-Tracking pro Download)
- Detaillierte Release-Beschreibung (app_releases.detailed_description — PROJ-426): Die detaillierte Beschreibung wird mittels KI (Anthropic Claude) automatisch generiert und enthält keine personenbezogenen Daten. Input für die Generierung sind die Feature-Spezifikation und der Commit-Diff — beide beschreiben technische Software-Änderungen ohne Personenbezug
- Backfill-Queue für historische Releases (app_release_backfill_queue — PROJ-426 Follow-up): Audit-Tabelle für den nachträglichen Backfill-Mechanismus. Enthält pro Eintrag: id (UUID), release_id (FK CASCADE), status (pending/processing/completed/failed), attempts-Zähler, last_error, created_at/updated_at/processed_at sowie created_by (UUID des Platform-Admins, der den Backfill getriggert hat, SET NULL bei User-Löschung). RLS-Zugriff ausschließlich für Platform-Admins. Enthält keine inhaltlichen Nutzerdaten — nur Audit-Metadaten über die ausgeführte Admin-Aktion
- Lese-Tracking (app_release_reads): User-ID + Release-ID + Lese-Zeitpunkt. Dient ausschließlich der Ungelesen-Badge-Anzeige im Feedback-Widget. UNIQUE-Constraint verhindert Mehrfach-Tracking
- DSGVO-Datenexport (Art. 15/20): app_release_reads des anfragenden Nutzers sind im Workspace-Datenexport enthalten (Release-Referenz, Lese-Zeitpunkt). app_release_backfill_queue-Einträge wo der anfragende Nutzer als created_by eingetragen ist sind ebenfalls im Workspace-Datenexport enthalten (nur für Platform-Admin-Nutzer relevant)
Persönliche Voice-Notizen (Mobile Diktat)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — produktivitätsbezogene Notiz-Funktion im Rahmen der SaaS-Dienstleistung)
- Sprach-Transkripte (personal_voice_notes.transcript): Vom Whisper-Service erzeugter Klartext der Mobile-Diktate. Inhaltlich potenziell PII — kann Namen, E-Mail-Adressen, Adressen, Gesundheitsdaten enthalten, je nach Diktat-Inhalt. Maximal 32 KB pro Note. Strikt user-scoped via RLS (user_id = auth.uid()) — kein anderer User kann diese Notizen lesen, auch nicht Workspace-Admins
- KI-überarbeitete Variante (personal_voice_notes.optimized_transcript): Optional von VoiceService.processWithPersonalAssistant generiert (Anthropic Claude Haiku — bereits als Auftragsverarbeiter dokumentiert). Gleiche PII-Klasse wie das Rohtranskript
- Aufnahme-Metadaten: recording_duration_seconds (Sekunden), status (open/converted_to_task/dismissed), Workspace-Referenz, Aufnahme-Zeitstempel, Update-Zeitstempel, optional converted_task_id (Referenz auf erzeugte Aufgabe nach Konvertierung)
- Audio-Dateien werden NICHT persistent gespeichert. Die Sprachaufnahme bleibt lokal auf dem iPhone/Mac (transient während Whisper-Upload), wird nach erfolgreicher Transkription verworfen und nie an die Plattform-Datenbank übermittelt. Re-Hören in der Inbox ist daher nicht möglich
- DSGVO-Datenexport (Art. 15/20): personal_voice_notes des anfragenden Nutzers werden in den Workspace-Datenexport aufgenommen (alle Felder inkl. Transkript)
Persönliche Text-Snippets (macOS Companion App)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — produktivitätsbezogene Snippet-Funktion im Rahmen der SaaS-Dienstleistung). Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — vorgefertigte Text-Bausteine zur effizienten Kommunikation)
- Snippet-Inhalte (companion_text_snippets.text): Vom Nutzer frei vergebener Text-Baustein (max. 10.000 Zeichen). Inhaltlich potenziell PII — kann Namen, E-Mail-Adressen, Adressen, Signaturen oder andere personenbezogene Daten enthalten, je nach Anwendungsfall (z.B. Briefvorlagen, AGB-Hinweise, E-Mail-Signaturen). Strikt user-scoped via RLS (user_id = auth.uid()) — kein anderer User kann diese Snippets lesen, auch nicht Workspace-Admins oder Mitglieder desselben Workspaces
- Snippet-Name (companion_text_snippets.name): Vom Nutzer frei vergebener Anzeigename (max. 100 Zeichen). Kann theoretisch personenbezogene Inhalte enthalten, falls der Nutzer etwa einen Kontaktnamen als Snippet-Namen verwendet — Nutzer wird empfohlen, neutrale Bezeichner zu wählen (z.B. „Begrüßung Kunde” statt „Vorlage Max Mustermann”)
- Konfigurations-Metadaten: sort_order (Reihenfolge im Panel), is_active (Sichtbarkeit im Panel — deaktivierte Snippets erscheinen nicht), created_at, updated_at, Workspace-Referenz (für CASCADE bei Workspace-Löschung)
- Übermittlung: Snippets werden ausschließlich zwischen der nativen macOS Companion App und NEULAND. OS (Supabase + Vercel) übertragen — keine externen KI-Dienste, keine Drittanbieter, kein Tracking. Die Authentifizierung erfolgt per Bearer-Token (Supabase JWT, im macOS-Keychain biometrisch geschützt). Beim Einfügen via Floating-Panel wird der Text lokal in die aktive Anwendung simuliert (CGEventPost) — kein Server-Roundtrip pro Einfüge-Vorgang
- Floating-Panel-Nutzung: Das Panel zeigt eine scrollbare Liste der aktiven Snippets des angemeldeten Nutzers. Die Daten werden beim App-Start einmalig geladen und im Arbeitsspeicher der App gehalten (keine lokale Persistenz, kein Cache nach App-Neustart). Bei macOS-Neustart sind die Snippets erst wieder verfügbar nachdem die App neu gestartet und mit dem Server synchronisiert wurde
- DSGVO-Datenexport (Art. 15/20): companion_text_snippets des anfragenden Nutzers werden in den Workspace-Datenexport aufgenommen (alle Felder inkl. Volltext, Name, Reihenfolge und Aktivierungs-Status)
Ziel-Statuswechsel Audit-Trail (Marketing-Ziel-Lifecycle)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Dokumentation von Marketing-Ziel-Statusänderungen im Rahmen der Agenturdienstleistung). Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — nachvollziehbare Entscheidungsdokumentation, GoBD-analoge Aufbewahrung)
- Ziel-Statuswechsel (goal_status_changes): Ziel-Referenz (ssot_item_id, SET NULL bei Löschung), Kontakt-ID (CASCADE bei Kontaktlöschung), Workspace-ID (CASCADE), geändert-von (User-ID), Zeitstempel, alter/neuer Status, Begründungstext (Freitext, 10–1000 Zeichen, kann personenbezogene Daten enthalten), Änderungstyp (Statuswechsel oder Aktivierung)
- Begründungstext: Die Pflicht-Begründung kann Namen und andere personenbezogene Daten enthalten (internes Dokument). Wird im Workspace-Datenexport (DSGVO Art. 15/20) eingeschlossen
- Notizen im Kommunikations-Tab: Bei jedem Statuswechsel wird automatisch ein Notiz-Eintrag im Kontakt-Kommunikationsverlauf erstellt (Kanaltyp 'marketing_goal') mit Beschreibung der Änderung
Standort-Erkennung & Anwesenheits-Anzeige
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter Teamkollaboration — Mitarbeiter müssen nicht manuell kommunizieren wo sie sich befinden). Widerspruchsrecht gemäß Art. 21 DSGVO wird durch Opt-out-Schalter im Profil gewährleistet (profiles.location_visible)
- IP-Adresse (serverseitiger Vergleich): Wird bei jeder aktiven Browser-Session aus dem HTTP-Header (x-forwarded-for) gelesen und gegen die konfigurierten Büro-IP-Ranges verglichen. Die IP-Adresse wird ausschließlich im Arbeitsspeicher verarbeitet und sofort verworfen — keine Speicherung in der Datenbank, kein Logging, keine Weitergabe an Dritte
- Standort-Ergebnis (office oder null): Das Vergleichsergebnis wird ephemer über den Supabase Realtime Presence-Kanal an andere Workspace-Mitglieder übermittelt. Keine dauerhafte Speicherung in der Datenbank
- Standort-Sichtbarkeit (location_visible): Dauerhaft in der profiles-Tabelle gespeichert (boolean, Standard: sichtbar). Der Nutzer kann die Sichtbarkeit jederzeit über die Profileinstellungen deaktivieren — bei Deaktivierung wird das Standort-Icon für andere Mitglieder nicht angezeigt. Löschung bei Account-Löschung (CASCADE)
- Büro-IP-Konfiguration (workspace_location_config): Array von IP-Adressen/CIDR-Ranges, konfiguriert durch den Workspace-Admin. Enthält keine personenbezogenen Daten. Löschung bei Workspace-Löschung (CASCADE)
- Verfügbar nur in Agentur-Workspaces. Client- und Partner-Workspaces haben keinen Zugriff auf die Standort-Erkennung
Signing-Portraits (Mitarbeiter-Bilder auf der Signing-Seite)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an professioneller Geschäftspräsentation gegenüber potenziellen Kunden). Mitarbeiter werden über die Verwendung ihres Bilds informiert (Hinweis im Upload-Dialog)
- Signing-Portrait (workspace_members.signing_portrait_path): Separates Bild pro Workspace-Mitglied, das ausschließlich auf der öffentlichen Signing-Seite angezeigt wird. Gespeichert im privaten Supabase-Storage-Bucket 'signing-portraits' (Pfad: workspace_id/member_id.ext). Zugriff nur über zeitbegrenzte signierte URLs (1 Stunde Gültigkeit). Unterstützte Formate: JPEG, PNG, WebP (max. 5 MB). Upload und Löschung nur durch Workspace-Admins und -Manager
- Fallback-Kette: Wenn kein Signing-Portrait vorhanden ist, wird das reguläre Profilbild (Avatar) auf der Signing-Seite angezeigt. Wenn auch kein Avatar vorhanden ist, werden Initialen angezeigt
- DSGVO-Datenexport (Art. 15/20): signing_portrait_path ist im Workspace-Datenexport als Datenpunkt enthalten (Storage-Pfad, keine Bilddatei)
KI-Projektbeschreibung auf Signing-Seite (PROJ-287)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an professioneller Angebotspräsentation)
- Briefing-Text (quotes.project_description_briefing): Vom Admin eingegebener Freitext zur Projektbeschreibung. Kann Kundennamen, Projektziele und Anforderungen enthalten. Wird an Anthropic (Claude) zur KI-Textgenerierung übermittelt
- Angebotskontext (automatisch zusammengestellt): Angebotstitel, Kontaktperson (Vorname, Nachname, Firmenname) und Positionstitel/-beschreibungen werden als Kontext an die KI gesendet
- Generierte Projektdokumentation (quotes.project_description): Strukturiertes JSON-Dokument mit Projekttitel, Übersicht, Abschnitten und Punktelisten. Wird auf der öffentlichen Signing-Seite angezeigt (über kryptische Token-URL). Enthält keine Preise oder vertrauliche Geschäftsdaten — nur sachliche Projektbeschreibungen
- KI-Verarbeitung: Anthropic (Claude Sonnet) verarbeitet Briefing + Angebotskontext und generiert strukturierte Projektbeschreibung. Keine Speicherung durch Anthropic (Zero Data Retention Policy). Token-Verbrauch wird im KI-Kosten-Tracking protokolliert
- Übernahme ins Projekt (projects.project_documentation/_html, PROJ-1881): Beim Auftragsstart kann dieselbe Projektdokumentation einmalig unverändert ins entstehende Projekt kopiert werden (identische JSON-/HTML-Struktur, keine erneute KI-Verarbeitung, kein zusätzlicher Anthropic-Aufruf). Dort bleibt sie dauerhaft im Projekt-Tab sichtbar — auch für den Kunden (read-only), nicht mehr nur befristet über die Signing-Token-URL. Löschung folgt automatisch der Projekt-Löschung (keine eigene Aufbewahrungsfrist)
First-Party Website-Event-Tracking (PROJ-288)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an anonymisierter Website-Analyse)
- Anonymisierter Session-Hash (tracking_events.session_hash): Täglicher HMAC-SHA256-Hash aus IP-Adresse + User-Agent + Tages-Salt. IP-Adressen werden NICHT gespeichert — der Hash ist nicht rückrechenbar. Salt rotiert täglich und wird nach 180 Tagen gelöscht
- Seitenaufruf-Daten (tracking_events): Domain, Pfad, Event-Typ (page_view, button_click, form_start, form_complete, scroll_depth, anchor_interaction), Referrer-URL, UTM-Parameter (source, medium, campaign, term, content)
- Gerätekategorie (tracking_events.user_agent_category): Kategorisierung in Mobile/Desktop/Bot anhand des User-Agent-Strings. Der vollständige User-Agent wird NICHT gespeichert
- Betriebssystem (tracking_events.os, PROJ-386): Aus User-Agent abgeleitete Kategorisierung in Windows/macOS/iOS/Android/Linux/Other. Wird bei Event-Ingestion gesetzt und dient ausschließlich der workspace-internen Analyse-Filterung. Der vollständige User-Agent wird NICHT gespeichert. Speicherdauer 180 Tage (identischer Cleanup-Cron)
- Standortdaten (tracking_events.country_code, city): Länderkürzel und Stadt aus Vercel-IP-Geolokalisierungs-Headern. Keine Speicherung von IP-Adressen oder GPS-Koordinaten
- Aggregierte Tagesstatistiken (daily_campaign_performance): Zusammenfassung pro Workspace + Domain + Tag mit Sessions, Event-Zähler, Top-Seiten. Enthält keine personenbezogenen Daten
- SSOT-Marketing-Klassifizierungs-Snapshot (tracking_events.ssot_page_id, ssot_page_type, ssot_marketing_goal_id, ssot_keywords, ssot_resolved_at, ssot_resolution_method, PROJ-771): Pro Event werden nach erfolgter URL-Auflösung gegen die SSOT-Bedarfsgruppen-Seiten (ssot_items section='bedarfsgruppe') interne Klassifizierungs-Metadaten gespeichert — FK auf die gematchte SSOT-Seite (ssot_page_id), kategorischer Seitentyp aus der SSOT-Definition (ssot_page_type, z.B. 'landing', 'product'), FK auf das priorisierte Marketing-Ziel (ssot_marketing_goal_id, abgeleitet aus zugewiesenen Keywords), JSONB-Snapshot der mit der Seite verknüpften Keywords (ssot_keywords: Array aus keyword_id + keyword_text + marketing_goal_id — pseudonyme technische Referenzen ohne Personenbezug), Zeitstempel der Auflösung (ssot_resolved_at) sowie Methoden-Code (ssot_resolution_method: 0=kein Treffer, 1=live_url-Exakt-Match, 2=computed_url-Hierarchie, 3=slug-Match). Reine Klassifizierungs-Metadaten ohne neue personenbezogene Daten — keine IP-Adressen, keine User-Daten, keine Inhalte aus Formular-Eingaben. Dient ausschließlich der workspace-internen Marketing-Performance-Analyse (Welche SSOT-Seite/welches Marketing-Ziel wurde besucht?). Auflösung erfolgt asynchron via Backfill-Cron (alle 15 Min, ssot-resolution-backfill) oder Lazy-Resolution-Endpunkt (POST /api/tracking/ssot-resolve). Zusätzlich: keywords.marketing_goal_id (PROJ-771): FK auf ssot_items (section='marketing_goal') — verknüpft jedes SEO-Keyword global mit dem zugehörigen Marketing-Ziel. Reine Konfigurations-Beziehung, keine personenbezogenen Daten
- Admin-Reset-Protokoll der SSOT-Snapshot-Felder (ssot_resolution_audit_log, PROJ-773): Internes Audit-Log über manuelle Re-Resolutions, die ein Workspace-Admin unter 'Einstellungen > Analyse > SSOT-Neuauflösung' auslöst. Pro Reset-Aktion werden gespeichert: user_id des ausführenden Admins (auth.users.id — Mitarbeiterdaten, kein Kunden-PBD), Workspace-ID, Reset-Zeitraum (date_from/date_to), optionaler URL-Filter, Anzahl zurückgesetzter Hits und Zeitstempel (created_at, completed_at). Reine Administrations-Protokoll-Daten zur Nachvollziehbarkeit der Workspace-Konfiguration — keine personenbezogenen Daten von Endnutzern/Website-Besuchern. Sichtbarkeit: nur Admin+Manager des eigenen Workspaces. Read-only für User (keine Lösch-Funktion)
CRM-Kampagnen-Context-Mapping (PROJ-291)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Kampagnen-Attribution und Conversion-Analyse)
- Session-Attribution (tracking_sessions): Materialisierte Session-Ebene mit UTM-Parametern, Click-IDs (gclid, fbclid, msclkid, wbraid, gbraid), SSOT-Touchpoint- und Marketingziel-Verknüpfung, First-Touch-Markierung und Conversion-Zeitstempel. Keine personenbezogenen Daten — nur anonymisierte Session-Hashes und Kampagnen-Metadaten
- Click-IDs (tracking_sessions.gclid, fbclid, msclkid, wbraid, gbraid, li_fat_id): Netzwerkspezifische Identifikatoren aus URL-Parametern. Werden beim ersten page_view einer Session extrahiert und gespeichert. gclid/wbraid/gbraid = Google Ads, fbclid = Meta Ads, msclkid = Microsoft Ads, li_fat_id = LinkedIn Ads First-Party Ad Tracking-ID (ersetzt 3rd-Party-Cookies für LinkedIn-Conversion-Tracking). Click-IDs sind pseudonyme Identifikatoren der Werbenetzwerke — kein direkter Personenbezug. Die Verwendung für Server-to-Server-Conversion-Attribution (Übermittlung an Google/Meta) ist im PROJ-293-Eintrag dokumentiert. li_fat_id wird aktuell nur persistiert (kein S2S-Versand). PROJ-290/306
- Eigene Kampagnen-Attribution (tracking_sessions.nl_tid, nl_campaign_id, native_click_id, PROJ-1477): Beim ersten Seitenaufruf einer Session mit nl_tid-URL-Parameter (interne, nicht-erratbare Kampagnen-Tracking-ID aus campaign_registry, PROJ-1458) werden drei Felder befüllt — nl_tid (Rohwert des Parameters), nl_campaign_id (FK auf campaign_registry, nur bei Match im selben Workspace gesetzt) und native_click_id (Snapshot des gclid-Parameters desselben Seitenaufrufs). Bei fehlendem Match oder Workspace-fremdem nl_tid bleibt nur nl_tid gesetzt, keine Kampagnen-Verknüpfung. First-Touch-gesperrt wie die übrigen Attribution-Felder dieses Eintrags — keine Überschreibung bei Folge-Events derselben Session. Alle drei Felder sind technische Attributions-Kennungen ohne direkten Personenbezug (nl_tid/nl_campaign_id sind interne Werbekampagnen-Referenzen, native_click_id ist funktional identisch zur bereits dokumentierten gclid-Spalte). Kein neues Cookie, keine zusätzliche Consent-Pflicht — nutzt den bestehenden cookielosen session_hash-Mechanismus dieses Eintrags
- Referrer-URL (tracking_sessions.referrer): URL der verweisenden Seite beim ersten Seitenaufruf der Session — auf Session-Ebene materialisiert (analog tracking_events.referrer aus PROJ-288). Kein direkter Personenbezug
- Standort- und Gerätedaten (tracking_sessions.country_code, city, user_agent_category): Länderkürzel, Stadt und Gerätetyp-Kategorie (Mobile/Desktop/Bot) — auf Session-Ebene materialisiert (analog zu tracking_events-Feldern aus PROJ-288). Keine Speicherung von IP-Adressen
- Kampagnen-Taxonomie-Regeln (campaign_taxonomy_rules): Konfigurationsdaten pro Workspace und Domain. Definieren welche UTM-Kombinationen welchem SSOT-Touchpoint und Marketingziel zugeordnet werden. Keine personenbezogenen Daten
- Conversion-Event-Konfigurationen (conversion_event_configs): Regeldefinitionen pro Domain für Conversion-Erkennung (Event-Typ, Pfad-Filter, Event-Data-Filter). Keine personenbezogenen Daten
- Conversion-Gruppen (conversion_event_groups): Konfigurierbare Gruppenbezeichnungen (z.B. 'Primäre Conversions') pro Workspace/Domain. Keine personenbezogenen Daten. PROJ-305
- SSOT-Tracking-Statistiken (ssot_tracking_stats): Aggregierte Zähler (Sessions, Conversions, identifizierte Unternehmen) pro Touchpoint, Marketingziel und Zeitraum. Rein statistische Daten ohne Personenbezug
- First-Touch-UTM-Snapshot (tracking_sessions.first_touch_utm_snapshot): JSONB-Kopie der UTM-Parameter zum Zeitpunkt der First-Touch-Session. Dient der historischen Attribution auch nach Taxonomie-Änderungen. Keine personenbezogenen Daten
- Redaktionsplan-Verknüpfung (tracking_sessions.editorial_entry_id): Optionaler Verweis auf einen veröffentlichten Redaktionsplan-Eintrag. Die Verknüpfung basiert auf UTM-Parametern-Übereinstimmung (utm_source/utm_medium) — keine neuen personenbezogenen Daten. Dient der Content-Performance-Attribution. PROJ-305
- UTM-Template-Konfigurationen (utm_template_configs): UTM-Template-Schemas pro Domain/Plattform (z.B. 'google', 'cpc', '{campaign.name}'). Technische Konfigurationsdaten, keine personenbezogenen Daten. PROJ-305 / PROJ-521 erweitert um optionale ssot_touchpoint_id (FK auf strategy_touchpoints, ON DELETE SET NULL) und ergänzt die platform-Whitelist um 9 Werbenetzwerk-Schlüssel (ads_google, ads_bing, ads_meta, ads_linkedin, ads_youtube, ads_tiktok, ads_spotify, ads_facebook, ads_instagram). Vorlagen können einem konfigurierten Touchpoint zugeordnet sein, was die automatische Vorschlagsgenerierung im Tracking-Vorlagen-Tab steuert. Keine personenbezogenen Daten
- Tracking-Domain Aggregator-Stempel (tracking_domains.last_unassigned_utms_alert_at, PROJ-521): Zeitstempel der letzten ausgelösten 'tracking_unassigned_utms_threshold'-Notification pro Domain — De-Dup für den stündlichen unassigned-utms-aggregator-Cron (Re-Alert frühestens nach 24h). Keine personenbezogenen Daten
- Channel-Gruppierungs-Regeln (channel_grouping_rules): Workspace-weite Regeln zur Kanal-Klassifizierung (Gruppenname, Bedingungstyp, Bedingungswert) und optionale domain-spezifische Regeln (tracking_domain_id — nullable FK auf tracking_domains). Technische Konfigurationsdaten, keine personenbezogenen Daten. PROJ-305 / PROJ-467
- Platform-Standard-Channel-Deaktivierungen (workspace_disabled_channels, PROJ-467): Pro Workspace-Konfiguration welche der 7 Platform-Standard-Channels (paid_search, ai_sources, organic_search, social_media, email, direct, other) bei der automatischen Session-Klassifizierung übersprungen werden sollen. Enthält workspace_id, channel_key (Enum-String), disabled_at, disabled_by (User-ID des deaktivierenden Admins — interner Audit-Trail). Keine personenbezogenen Daten über Dritte. Reine Workspace-Konfiguration
- Session-Channel-Klassifizierung (tracking_sessions.channel_classic + channel_semantic, PROJ-467 + PROJ-529): Zwei Klassifizierungsfelder auf Session-Ebene. channel_classic (vormals 'channel', PROJ-467): synchron berechnetes Ergebnis der deterministischen Kanal-Zuordnung bei Session-Erstellung — Werte aus PLATFORM_CHANNEL_KEYS oder benutzerdefinierten channel_grouping_rules. channel_semantic (PROJ-529): asynchron berechnetes Ergebnis der semantischen Klassifizierung (Curated-Lookup, Workspace-Override, in PROJ-530 ergänzt um Dark Social, GSC Brand-Split, Customer Referral, LLM-Fallback). Beide Werte sind Klassifikations-Metadaten abgeleitet aus bereits gespeicherten Signalen (Referrer-URL, UTM-Parameter, Click-IDs, Landing-Pfad) — keine personenbezogenen Daten
- Attribution Semantic Queue (attribution_semantic_queue, PROJ-529): Asynchrone Verarbeitungs-Queue zur Berechnung von channel_semantic. Pro neu erstellter Tracking-Session wird ein Eintrag mit session_id (FK CASCADE), workspace_id, domain_id, UTM-Snapshot (utm_source/medium/campaign), referrer_domain (Hostname ohne Pfad), landing_page_path, status (pending/processing/done/failed/skipped), result_channel, result_source, error_message, retry_count, next_retry_at, created_at, processed_at angelegt. Keine personenbezogenen Daten — die Queue persistiert ausschließlich die bereits in tracking_sessions vorhandenen Attribution-Signale für die Worker-Verarbeitung. RLS: nur Service-Role intern (keine User-Reads). Verarbeitung alle 2 Minuten via pg_cron-Job 'attribution-semantic-worker'
- Globale Curated-Plattform-Definitionen (attribution_curated_sources, PROJ-529): Plattformweit kuratierte Liste bekannter öffentlicher Plattformen (Linktree, Beehiiv, Substack, Buffer, Hootsuite, Calendly, Notion, Slack, bio.site etc.) mit Match-Typ (utm_source_contains/referrer_domain_contains), Match-Wert und target_channel. KEINE workspace_id — bewusst global, da ausschließlich öffentlich bekannte Plattform-Wissens-Daten ohne Kundenbezug. Initial 24 Einträge, erweiterbar durch Plattform-Admin via Service-Role. Keine personenbezogenen Daten
- Workspace-Attribution-Overrides (attribution_workspace_overrides, PROJ-529): Pro Workspace gespeicherte Attribution-Overrides — entweder manuell vom Admin (override_source='manual') oder ab PROJ-530 als KI-Vorschlag bzw. KI-bestätigt (ai_suggestion/ai_confirmed). Spalten: workspace_id (FK CASCADE), match_type (utm_source_contains/referrer_domain_contains/utm_combination/landing_page_contains), match_value, target_channel, override_source, created_by (User-ID des erstellenden Admins — interner Audit-Trail, ON DELETE SET NULL), created_at. Keine personenbezogenen Daten über Dritte. RLS: SELECT/INSERT/UPDATE/DELETE nur Admin/Manager via workspace_members
- Ignorierte UTM-Kombinationen (utm_combination_ignores): Workspace- und Domain-spezifische Liste von UTM-Kombinationen, die ein Admin/Manager bewusst NICHT einem Touchpoint oder Marketingziel zuordnen möchte (verhindert Wiederkehr in der Schnellzuweisungs-Liste). Enthält lowercase-normalisierte UTM-Strings + Workspace-/Domain-Referenzen + created_by (User-ID des ausführenden Admins, dient ausschließlich Workspace-Audit-Trail). Keine personenbezogenen Daten über Dritte. PROJ-429
- Session-ID-Verknüpfung mit Lead-Karten (PROJ-428): Beim Versand eines Contao-Formulars übermittelt snippet.js die pseudonyme client_session_id (bzw. session_hash) über ein verstecktes Formular-Feld (`neuland_session_id`) an den Webhook-Receiver. Nach Erstellung der Lead-/Bewerber-Karte (contacts.notes bzw. client_applicants.notes) wird diese um einen Kontext-Block erweitert: UTM-Parameter, Referrer-URL, Link zum Session-Recording (falls vorhanden) und Zeitpunkt der ersten Interaktion — ausschließlich aus bereits in tracking_sessions gespeicherten pseudonymen Daten. Die Session-ID selbst ist ein technischer Identifier ohne Personenbezug. Ziel: Transparenz über die Traffic-Quelle des Leads für Agentur-Mitarbeiter. Die Verbindung zu einer konkreten Person entsteht erst durch die freiwillige Formular-Eingabe des Interessenten (Name, E-Mail) — nicht durch die Session-ID. Zusätzlich kann serverseitig ein synthetisches form_submit-Event in tracking_events nachgeneriert werden (event_data.source='server_backfill'), falls das client-seitige Event durch einen Adblocker geblockt wurde. Dieses Backfill-Event ist ein pseudonymer statistischer Datensatz ohne PII
- Session Engagement & Quality Index (PROJ-528 — tracking_sessions.is_engaged, engaged_at, quality_index, session_duration_seconds, event_count, scoring_backfilled_at): Pro Session werden serverseitig fünf rein numerische/boolesche Aggregat-Metriken aus den bereits gespeicherten tracking_events berechnet: ein Engagement-Flag (true/false, abgeleitet aus aktiver Verweildauer ≥ 10 s, ≥ 2 Pageviews oder Interaktion-Events), Zeitstempel der Engagement-Erreichung, Session Quality Index 0–100 (gewichtete Punktesumme aus konfigurierbaren Event-Regeln), aktive Verweildauer in Sekunden, Event-Zähler. Bot-Sessions (is_bot=true) werden weder als engaged klassifiziert noch gescort. Diese Metriken sind reine Aggregat-Werte ohne Personenbezug und werden zur internen Traffic-Qualitäts-Bewertung der Agentur und ihrer Kunden genutzt
- Konfigurierbare SQI-Regeln (tracking_domain_sqi_events, PROJ-528): Pro Tracking-Domain hinterlegt der Account-Manager eine Liste von Punkt-Regeln je Event-Typ (event_type, points_per_trigger 0–100, max_points_per_session 0–100, set_to_max boolean, sort_order). Beim Anlegen einer neuen Domain werden fünf System-Default-Regeln (page_view, content_engaged, form_step_view, form_interaction, generate_lead) per DB-Trigger eingefügt. Reine Workspace-Konfigurationsdaten — keine personenbezogenen Daten. RLS: SELECT für alle Workspace-Mitglieder, INSERT/UPDATE/DELETE nur Admin/Manager. CASCADE-DELETE bei Domain-Löschung
- Event-Idempotenz-UUID (tracking_events.event_id, PROJ-528): Client-generierte UUID v4 pro Event aus snippet.js. Dient ausschließlich der serverseitigen Duplikats-Erkennung (60-Sekunden-Fenster pro session_hash) zur Vermeidung doppelter SQI-Punkte bei Browser-Retries. Kein Personenbezug — die UUID identifiziert kein Endgerät und keinen Nutzer dauerhaft, sondern nur ein einzelnes Sende-Ereignis innerhalb einer Session. Backwards-Compatibility: alte Snippet-Versionen ohne event_id werden serverseitig mit einer UUID versehen
- URL-Brand-Scores (url_brand_scores, PROJ-530): Aggregierte Brand-Wahrscheinlichkeit pro URL-Pfad einer Tracking-Domain. Spalten: domain_id (FK CASCADE auf tracking_domains), url_path (z.B. /blog/marken-vergleich), brand_probability (0.000–1.000), total_impressions, brand_impressions, last_computed_at. Datenquelle: aggregiertes seo_keyword_daily.is_brand der letzten 30 Tage (gepflegt durch PROJ-417 SEO-Brand-Infrastruktur). Berechnung täglich 04:30 UTC durch Cron-Job attribution-gsc-scorer NACH seo-brand-apply (04:00). Verwendung: Wenn eine Tracking-Session auf einer URL mit brand_probability >= 0.5 landet UND channel_classic = organic_search, wird channel_semantic = organic_search_brand gesetzt; andernfalls organic_search_discovery. KEINE personenbezogenen Daten — URL-Pfade sind technische Klassifizierungs-Metadaten ohne Nutzerbezug. RLS: SELECT für Admin/Manager des Workspace via tracking_domains->workspace_members; INSERT/UPDATE/DELETE nur Service-Role intern. 90-Tage-Retention via tracking-cleanup-Cron, CASCADE-Löschung bei Domain-Löschung
- Tracking-Domain Attribution-Settings (tracking_domains.customer_referral_routing_enabled + dark_social_min_depth, PROJ-530): Zwei reine Konfigurations-Spalten für die semantische Attribution-Engine. customer_referral_routing_enabled (boolean, default false): aktiviert pro Tracking-Domain den CRM-Domain-Match — wenn true und der Session-Referrer einer im CRM hinterlegten Kunden-Domain (ssot_items section=domain) entspricht, wird channel_semantic = customer_referral gesetzt. Subdomain-tolerantes Matching, Self-Referral-Ausschluss für eigene Domains. dark_social_min_depth (integer, default 2): Mindest-URL-Tiefe (Anzahl Pfadsegmente) für Dark-Social-Klassifizierung bei Sessions ohne Referrer. Reine Domain-Konfiguration ohne Personenbezug. CRM-Kunden-Domains sind B2B-Daten (Firmen-Hostnames) — keine personenbezogenen Daten
Identity Anchor Konfigurator (PROJ-289)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an pseudonymisierter Cross-Session-Attribution)
- Entity-Hash (anchor_interactions.entity_hash, session_entity_mapping.entity_hash): SHA256-Hash aus freiwilliger Nutzereingabe (z.B. Seriennummer, Firmenname) + Anchor-spezifischem Salt. Der Original-Input wird NICHT gespeichert — der Hash ist nicht rückrechenbar
- PII-Hash (anchor_interactions.pii_hash, session_entity_mapping.pii_hash): SHA256-Hash aus hochindividueller Eingabe (z.B. E-Mail, Telefonnummer) + Anchor-spezifischem Salt. Wird nur bei expliziter PII-Klassifikation des Anchors erzeugt. Der Original-Input wird NICHT gespeichert
- Session-Hash (anchor_interactions.session_hash): Referenz auf das anonyme Session-Konzept aus PROJ-288 (HMAC-SHA256 aus IP + User-Agent + Tages-Salt). Keine IP-Adresse gespeichert
- Eingabelänge (anchor_interactions.raw_input_length): Nur die Zeichenlänge des Inputs, NICHT der Inhalt
- Display-Hint (anchor_interactions.display_hint, PROJ-414): Datenschutzkonformer Hinweis, clientseitig in snippet.js vor dem Hashing berechnet — der Rohwert verlässt den Browser nie. Für PII-Anchors: maskierte E-Mail (j***@domain.com) oder teilmaskierter Wert. Für Entity-Anchors: Unternehmensdomain oder -name im Klartext (keine personenbezogenen Daten). Max. 200 Zeichen. NULL für Bestandsdaten vor PROJ-414
- KI-Validierungsscore (anchor_interactions.ai_validity_score): Bewertung 0–100 der semantischen Sinnhaftigkeit einer Eingabe durch Claude Haiku. Input-Kontext (Anchor-Name, Eingabelänge) wird anonymisiert an Anthropic übermittelt — keine Originalinhalte
- Identity Graph (pii_to_entity_mapping): Dauerhaft verknüpfte Paare aus pii_hash und entity_hash. Beide Werte sind irreversible SHA256-Hashes — keine Rückrechnung auf Original-Daten möglich
- OCR-Bilderkennung (anchor_ocr): Bei File-Upload-Anchors wird ein Bild an Claude Sonnet (Anthropic) zur Texterkennung gesendet. Der extrahierte Text wird sofort gehasht, das Originalbild wird NICHT gespeichert (nur in-memory verarbeitet)
IP-Unternehmens-Erkennung & ABM-Dashboard (PROJ-290) — erweitert um manuelle Company-Name-Korrektur & KI-Vorschlag (PROJ-456), Branche/Herkunft-Attribute & Change-Log (PROJ-1390)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse im B2B-Kontext — Identifikation von Unternehmens-Interessenten zur Vertriebsunterstützung und Korrektur fehlerhafter IPinfo-Rohdaten zur Qualitätssicherung des Dashboards)
- Unternehmens-Anreicherungsfelder auf tracking_sessions: company_name (Unternehmensname, z.B. 'Bosch GmbH'), company_domain (Domain des Unternehmens, z.B. 'bosch.com'), company_industry (Branche), company_size_range (Größenklasse, z.B. '1001-5000'). Diese Felder enthalten ausschließlich Unternehmens-Daten (keine Daten natürlicher Personen). IP-Adressen werden NICHT gespeichert — sie werden transient für den IPinfo.io-API-Aufruf verwendet und danach verworfen
- Hot-Account-Benachrichtigungs-Tabelle (abm_hot_account_notifications): workspace_id, company_domain (Unternehmens-Domain als Identifier), notified_at (Zeitstempel der letzten Benachrichtigung). Dient dem 7-Tage-Cooldown für Benachrichtigungen. Keine personenbezogenen Daten
- Manuelle Namens-Korrekturen und Lead-Qualifizierung (abm_domain_overrides, PROJ-456 + PROJ-457): workspace_id, domain (Ziel-Domain wie 'hetzner.com'), company_name_override (manuell korrigierter Firmenname, max. 500 Zeichen), lead_status (Lead-Qualifizierungs-Enum: qualified/disqualified/no_lead/null, seit PROJ-457 aktiv genutzt), updated_at, updated_by (User-ID des Admins/Managers, der die Änderung vorgenommen hat — interne Workspace-Mitgliederreferenz). Der gespeicherte Firmenname ist die Bezeichnung einer juristischen Person (kein direkter Personenbezug); lead_status ist eine workspace-interne Klassifikation (juristische Person, keine natürliche Person); updated_by ist als Audit-Trail-Verweis auf einen Workspace-Mitarbeiter personenbezogen. Auflösungs-Priorität in allen ABM-Views: company_name_override > tracking_sessions.llm_clean_name > tracking_sessions.company_name. Zugriff: nur für Workspace-Mitglieder des Eigentümer-Workspaces (RLS), Schreibrechte nur Admin/Manager. Kunden-Portal-Sichtbarkeit (PROJ-457): Im Kunden-Portal (/api/client/abm) werden Einträge mit lead_status='disqualified' oder 'no_lead' IMMER aus der Response gefiltert — Kunden sehen nur qualifizierte und unbewertete Unternehmen. Die Klassifikation selbst wird nicht zum Kunden übermittelt. Dashboard-Filter (Agentur-Workspace) zeigt standardmäßig nur qualifizierte + unbewertete Einträge; disqualified/no_lead sind ausgeblendet, aber per Filter sichtbar (gedimmt dargestellt). Branche/Herkunft (industry/origin, PROJ-1390): zwei zusätzliche nullable Firmografie-Felder — Branche der Domain und Herkunft der Domain-Erkennung (z.B. ipinfo/manuell/llm). Beide beschreiben die juristische Person (Unternehmen), kein Personenbezug. In Etappe 1 nur Schema-Vorsorge, initial NULL, noch kein Admin-UI zur Befüllung
- Entity-Attribut-Änderungshistorie (entity_attribute_change_log, PROJ-1390): workspace_id, domain, feld (eines von company_name_override/industry/origin), alter_wert, neuer_wert, geaendert_am. Wird ausschließlich durch einen Datenbank-Trigger auf abm_domain_overrides befüllt (kein manueller Insert-Pfad) — protokolliert jede Änderung an den drei Firmografie-Feldern automatisch. Enthält KEINE Nutzer-/Actor-ID (kein Personenbezug zum ändernden Mitarbeiter) — reine Werteverlaufs-Historie einer juristischen Person
- KI-Namensvorschlag (PROJ-456 — abm_name_suggestion): Admin-/Manager-ausgelöster Claude-Haiku-Call zur Ermittlung des korrekten Firmennamens einer Domain. Übermittelt wird ausschließlich der Domain-Name (öffentliche Information, kein direkter Personenbezug). Output: Firmenname oder 'UNKNOWN'. Vorschlag wird nicht automatisch gespeichert — der Admin entscheidet explizit über die Übernahme (EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Vorschlags-Banner). Kein Bulk-Klassifikator, nur on-demand je Domain. Token-Tracking via logTokenUsage(feature=abm_name_suggestion). Timeout 10 s. Auftragsverarbeitung über Anthropic PBC (siehe PROCESSORS-Tabelle)
Website-Tracking User-Ebene — Identity Resolution & Unique Visitors (PROJ-1503)
Rechtsgrundlage: Gemischt je Tier: Tier 1 Endkunden-Login = Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Reichweiten-Messung, abhängig vom Kunden-AVV ggf. auch lit. b Vertragserfüllung im Verhältnis Kunde↔Endnutzer). Tier 2 pseudonymer Opt-in = Art. 6 Abs. 1 lit. a DSGVO (Einwilligung, § 25 Abs. 1 TDDDG). Interne Traffic-Signale (Contao-Backend-/NeulandOS-Login von NEULAND-Mitarbeitenden) = Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an korrekter Reichweiten-Messung durch Ausschluss eigener Zugriffe) i.V.m. Beschäftigtendatenschutz (§ 26 BDSG) — betrifft ausschließlich NEULAND-Mitarbeitende, nicht Website-Besucher.
- Kanonisches Personen-Profil (user_identity): pseudonymous_id (First-Party-UUID, Cookie-Wert nl_uid), deterministic_id_hash (HMAC-SHA256 aus workspace_id:kind:login_id mit serverseitigem Secret TRACKING_IDENTITY_SECRET — der Klartext-Login wird NIE gespeichert oder geloggt, technisch eine Pseudonymisierung nach Art. 4 Nr. 5 DSGVO, keine Anonymisierung: bei Kenntnis von Secret + Login-ID ist der Hash reproduzierbar und damit re-identifizierbar), tier (pseudonymous/deterministic), is_internal-Flag, first_seen/last_seen, company_domain-Referenz (Inherit von abm_domain_overrides, PROJ-1390 — keine Dopplung von Firmendaten), consent_visitor_id (Verweis auf den Consent-Nachweis), revoked_at (Widerrufszeitpunkt)
- Merge-Historie (user_identity_merge_log, append-only, DB-Trigger-geschützt gegen UPDATE/DELETE): Protokolliert Zusammenführung pseudonymer Profile in deterministische Profile (Anzahl übernommener Sessions), Company-Zuordnungs-Wechsel (Alt-/Neu-Domain) und Internal-Flag-Setzungen. Kein Klartext-Login, nur interne UUID-Referenzen
- Unique-Visitor-Sketches (unique_visitor_sketches): HyperLogLog-Sketches (binäre Aggregat-Struktur, keine Einzeldaten rekonstruierbar) pro (Workspace, Entity-Typ, Entity, Tag). Reine statistische Aggregate ohne Personenbezug — die Sketch-Struktur selbst kann keine Einzelperson identifizieren, auch nicht approximativ
- Interne-Traffic-Signale (internal_traffic_signals): Protokolliert same-origin erkannte Login-Signale (Contao-Backend- oder NeulandOS-CMS-Login) bzw. Office-IP-Treffer, die eine user_identity dauerhaft als 'intern' markieren. Betrifft NEULAND-Mitarbeitende, die im Rahmen ihrer Tätigkeit Kunden-Websites im Backend bearbeiten — kein Tracking privaten Surfverhaltens (nur Login-Ereignis + Zeitstempel + Domain, keine Inhalte)
- Office-IP-Allowlist (internal_office_ip_allowlist): Agentur-weite Konfigurationsliste von Büronetzwerk-IP-Ranges (CIDR) als Fallback-Erkennung für rein extern gehostete Kunden-Domains ohne same-origin-Login-Signal. Enthält created_by (Admin-User-ID, interner Audit-Trail). Keine Website-Besucher-Daten
- Domain-Admin-Toggle (tracking_domains.identity_tracking_enabled): Workspace-Konfiguration, ob Tier-2-Identity-Tracking für eine Domain aktiviert ist (Default false). Keine personenbezogenen Daten
- Cookie nl_uid (siehe COOKIES-Tabelle): First-Party, HttpOnly, Secure, SameSite=None, 395 Tage rolling, ausschließlich nach Opt-in in der Consent-Kategorie 'identity' gesetzt
ABM Account Intelligence — LLM-Klassifikation & Intent Scoring (PROJ-433)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an Leadqualifizierung und Vertriebsunterstützung im B2B-Kontext; Unternehmens-Sessions ohne Personenbezug)
- LLM-Klassifikations-Felder auf tracking_sessions (PROJ-433): llm_is_b2b (Boolean: echtes B2B vs. Infrastruktur), llm_category (Kategorie: Enterprise/SME/Public Sector/VPN/Datacenter/ISP/Bot), llm_clean_name (bereinigter Unternehmensname, max. 200 Zeichen). Ausschließlich Unternehmens-Daten — keine PBD natürlicher Personen
- Intent-Scoring-Felder auf tracking_sessions: buying_intent_score (Integer 0–100, Kaufabsichts-Score), intent_explanation (KI-generierter Begründungssatz, max. 150 Zeichen, kein Personenbezug — beschreibt besuchte Seitenkategorien). llm_classified_at, llm_classify_attempts, intent_scored_at (technische Zeitstempel)
- An Anthropic PBC (Claude Haiku) übermittelte Daten: (1) Unternehmensname aus IPinfo-Lookup — kein direkter Personenbezug; (2) URL-Pfade ohne Query-Parameter (z. B. '/leistungen') als Journey-Array. Keine IP-Adressen, keine E-Mails, keine Namen natürlicher Personen
ABM Lead Quality Score & Insight Text (PROJ-466)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an Leadqualifizierung und Vertriebsunterstützung im B2B-Kontext). Erweitert PROJ-433 (Account Intelligence Engine) und PROJ-456 (ABM Company-Name-Korrektur) um eine pro-Firma (Workspace × Domain) Lead-Bewertung und eine on-demand Visit-Story. Für den KI-Scoring- und KI-Insight-Pfad Auftragsverarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC (siehe PROCESSORS). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung an allen Ausgabe-Elementen.
- Lead Quality Score (abm_domain_overrides.quality_score, quality_label, quality_scored_at): Score 0–100 und Label ('lead' | 'competitor' | 'unlikely' | 'infrastructure') pro (workspace_id, domain). Deterministisch vor-klassifiziert für Infrastruktur und Wettbewerber, KI-bewertet nur für B2B-Firmen ohne negative Signale. Bewertet eine juristische Person (kein Personenbezug natürlicher Personen)
- Visit-Story-Text (abm_domain_overrides.insight_text): On-Demand generierter deutscher 2–3-Sätze-Text (max. 1000 Zeichen) der die zusammengefasste Besuchs-Story einer Firma beschreibt. Erwähnt Kanal, intensiv besuchte Seitentypen und Verweildauern — keine einzelnen Sessions, keine IP-Adressen, keine Klartext-Session-IDs. Input-Seitenpfade werden query-param-bereinigt
- Interessen-Tags (abm_domain_overrides.insight_tags): JSONB-Array von max. 5 Tags aus einer serverseitigen Whitelist (#SEO, #EmployerBranding, #LeadGen, #Performance, #WebDesign, #SocialMedia, #Branding, #Entwicklung, #Tracking, #CRM). Server verwirft alle Tags, die nicht in der Whitelist stehen. Keine freien Nutzer-Texte
- Kostennachvollziehbarkeit (abm_domain_overrides.insight_generated_at, insight_generated_by): Zeitstempel und User-ID (auth.users) des Admins/Managers der den Generate-Button geklickt hat. Interner Workspace-Audit-Trail für KI-Token-Kosten
- An Anthropic PBC (Claude Haiku) übermittelte Quality-Score-Daten: Firmenname aus IPinfo-Lookup (öffentliche B2B-Information), Domain, Kategorie-Label, company_size_range (Mitarbeiter-Range als kategorischer Wert). Keine IP-Adressen, keine Personennamen, keine E-Mails
- An Anthropic PBC (Claude Haiku) übermittelte Insight-Text-Daten: Anzahl Sessions, Erst-/Letzt-Besuchs-Zeitstempel, UTM-Quelle/-Medium/-Kampagne (kategorisch), Top-10 URL-Pfade ohne Query-Parameter + aggregierte Verweildauern, Formular-Interaktions-Anzahl, maximale Scroll-Tiefe. Keine IP-Adressen, keine Session-Hashes, keine Personennamen, keine Formular-Eingabewerte
- DSGVO-Datenexport (Art. 15/20): abm_domain_overrides wird im Workspace-Datenexport ausgegeben (alle Spalten inkl. quality_score, quality_label, quality_scored_at, insight_text, insight_tags, insight_generated_at, insight_generated_by; außer internen Primärschlüsseln)
ABM KI-Firmenbereinigung (PROJ-477)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an einer bereinigten Lead-Liste im ABM-Dashboard — Ausblenden von ISP-/Hoster-/Telco-Einträgen, die keinen Vertriebs-Wert haben, ist unmittelbare Arbeitserleichterung für Vertriebsmitarbeiter). Erweitert PROJ-290 (IP-Unternehmens-Erkennung) und PROJ-456 (ABM Company-Name-Korrektur) um eine automatische Domain-Klassifikation mit 24h-Cache. Keine personenbezogenen Daten werden zusätzlich erhoben — die Klassifikation erfolgt ausschließlich auf öffentlichen Domain-Namen. Für den KI-Klassifikationspfad Auftragsverarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC (siehe PROCESSORS). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung an allen korrigierten Tabellen-Einträgen.
- ISP-Klassifikations-Flag (abm_domain_overrides.ai_is_isp_domain): Boolean pro (workspace_id, domain) — gibt an, ob die Domain zu einem Internet-Service-Provider, Hosting-Anbieter, Telekommunikationsbetreiber oder VPN-Dienst gehört. Bewertet eine juristische Person (keine Personenbezug natürlicher Personen)
- Bereinigter Firmenname (abm_domain_overrides.ai_resolved_name): KI-abgeleiteter Firmenname (max. 200 Zeichen) oder NULL wenn kein sinnvoller Name ableitbar war. Bezieht sich ausschließlich auf Unternehmen (keine Personen)
- Klassifikations-Zeitstempel (abm_domain_overrides.ai_resolved_at): TIMESTAMPTZ — definiert den 24-Stunden-Cache-TTL. Nach Ablauf erfolgt erneute Klassifikation durch den Worker
- An Anthropic PBC (Claude Haiku) übermittelte Daten: ausschließlich der Domain-Name (z. B. 'hetzner.com', 'vodafone.de'). Kein Firmenname-Kontext aus IPinfo, keine IP-Adressen, keine Session-Daten, keine Personennamen, keine E-Mails. Öffentliche Domain-Information im Sinne des Handelsrechts
- DSGVO-Datenexport (Art. 15/20): Die 3 neuen abm_domain_overrides-Spalten (ai_is_isp_domain, ai_resolved_name, ai_resolved_at) werden im bestehenden Workspace-Datenexport mit ausgegeben
Sortierung und Filter für Laufende Briefings (PROJ-1174)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — persönliche Sortier-/Filter-Präferenz der Briefing-Tabelle als Dienst-Konfiguration des NEULAND. OS-Mitarbeiters). Keine inhaltlichen personenbezogenen Daten — lediglich UI-Anzeige-Einstellungen.
- Briefing-Ansichts-Präferenz (user_briefing_preferences): user_id (FK auf auth.users — NEULAND. OS-Mitarbeiter-ID), sort_by (Enum: title | branch | status | created_by | validated_at, nullable), sort_order (Enum: asc | desc, nullable), filter_status (JSONB-Array von Status-Strings), filter_created_by (JSONB-Array von User-UUIDs der ausgewählten Ersteller-Filter), updated_at. Persönliche Konfiguration der Tabellen-Sortierung und -Filterung im Tab „Laufende Briefings“. Bezieht sich ausschließlich auf NEULAND. OS-Mitarbeiter, nicht auf Endnutzer von Kunden-Websites. filter_created_by enthält UUIDs anderer Workspace-Mitglieder ausschließlich als Filter-Referenz (kein neuer Personenbezug, keine Profil-Daten).
- DSGVO-Datenexport (Art. 15/20): user_briefing_preferences wird im Workspace-Datenexport über workspace_members gefiltert ausgegeben (user_id, sort_by, sort_order, filter_status, filter_created_by, updated_at).
ABM-Mismatch-Validator-Erweiterung, Daily Digest und Blacklist-Permissions (PROJ-584)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — ABM-Notification-Präferenz als persönliche Dienst-Konfiguration des NEULAND. OS-Mitarbeiters). Folgeverarbeitungen des Daily Digest folgen Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse, identisch mit PROJ-290 ABM-Dashboard — Aggregation bestehender Unternehmens-Besuchsdaten ohne neue PBD-Erhebung).
- ABM-Notification-Präferenz (user_abm_preferences): user_id (FK auf auth.users — NEULAND. OS-Mitarbeiter-ID), abm_notification_mode (Enum: single = Einzel-Benachrichtigungen bei Auftreten, digest = Daily Digest täglich 07:30 UTC), tracking_notification_mode (PROJ-616, Enum: single | digest = Daily Digest täglich 07:00 UTC für Tracking-Blueprints + kritische Anomalien). Persönliche Konfiguration des Notification-Empfangs. Bezieht sich ausschließlich auf NEULAND. OS-Mitarbeiter, nicht auf Endnutzer von Kunden-Websites.
- Daily-Digest-Notifications (notifications.metadata, type=abm_daily_digest): digest_date (ISO-Datum des Digest-Tages), total_hot_accounts (Integer-Zähler), domains_summary (JSONB-Array mit domain, type=agency/client, companies-Liste mit name=bereinigter Unternehmensname, intent_score, quality_score, channel_label). Ausschließlich Unternehmens-Daten (juristische Personen) — keine personenbezogenen Daten natürlicher Personen.
- Tracking-Analyse-Daily-Digest-Notifications (PROJ-616, notifications.metadata, type=tracking_analysis_daily_digest): digest_date, blueprint_count, anomaly_count, form_anomaly_count, domains_summary (JSONB-Array mit domain, type=agency/client, blueprints-, anomalies-, form_anomalies-Listen). Aggregiert tracking_blueprints + tracking_insights der letzten 24h. Keine personenbezogenen Daten — nur Tracking-Konfiguration und aggregierte Metriken.
- DSGVO-Datenexport (Art. 15/20): user_abm_preferences wird im Workspace-Datenexport über workspace_members gefiltert ausgegeben (user_id, abm_notification_mode, tracking_notification_mode, created_at, updated_at). Implementiert in Phase 4e (R-241).
Website-Tracking Proaktive KI-Engine — Anomalie-Erkennung & Root-Cause-Analyse (PROJ-436)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Erkennung kritischer Abweichungen im Website-Tracking und deren Erklärung zur Unterstützung der Marketing-Entscheidungen der Agentur). Erweitert PROJ-288 (First-Party Tracking-Infrastruktur) und PROJ-306 (Behavioral Biometrics) um ein Insight-Layer über bestehenden Aggregaten — keine personenbezogenen Daten werden neu erhoben. Für die optionale Root-Cause-Analyse Auftragsverarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC (siehe PROCESSORS).
- Insights (tracking_insights): workspace_id, domain_id, insight_type (7 Typen: anomaly_bounce_spike, anomaly_traffic_drop, anomaly_traffic_spike, anomaly_new_source, anomaly_conversion_drop, anomaly_segment_specific, info_high_value_keyword), severity (info/warning/critical), metric_key (z. B. 'bounce_rate', 'conversion_rate'), metric_delta_percent (Abweichung zum 7-Tage-Baseline, Dezimal), filter_state (JSONB — kategorische Scope-Werte wie utm_source='google', device_type='mobile' — keine Klartext-IPs, keine Namen), data_context (JSONB — aggregierte Vorher/Nachher-Werte), detected_at, expires_at (7 Tage TTL). Kein Personenbezug — alle Felder sind Aggregat-Metriken oder kategorische Scope-Werte
- LLM-Erklärungen (tracking_insights.llm_explanation): On-Demand via Admin-Klick 'Erklärung anfordern' generierter KI-Text (Claude Haiku, max. 2.000 Zeichen) mit 1–3 Hypothesen und Handlungsempfehlungen. Der Erklärungstext wird in deutscher Sprache gerendert und als KI-generiert gekennzeichnet (✦ Badge gemäß EU AI Act Art. 50). Keine Zitierung konkreter Sessions, IPs oder Personen — ausschließlich Aggregat-Interpretation
- An Anthropic PBC (Claude Haiku) übermittelte Daten (nur bei expliziter 'Erklärung anfordern'-Aktion): (1) insight_type (kategorischer Wert), (2) metric_delta_percent (Prozent-Wert), (3) filter_state (kategorische Scope-Werte wie utm_source/channel/device_type — keine Klartext-IDs, keine URLs, keine Unternehmensnamen), (4) data_context (aggregierte Vorher/Nachher-Werte). Keine IP-Adressen, keine User-Agents, keine URL-Pfade, keine Session-Hashes, keine Identity-Anchor-Werte
- Feedback (tracking_insights.thumbs_up_count, thumbs_down_count, thumbs_down_reason): Workspace-Mitglieder können eine Erklärung als hilfreich/nicht-hilfreich markieren. Optionaler Grund-Freitext (max. 500 Zeichen) — kann indirekten Personenbezug enthalten wenn der Admin dort einen Kommentar notiert. Zweck: Qualitätsverbesserung der KI-Erklärungen
- Insight-Notifications: Bei severity='critical' wird eine Inbox-Notification (tracking_critical_anomaly) an Workspace-Admins ausgelöst. Keine zusätzliche Datenerhebung — nur Verweis auf den Insight-Datensatz über insight_id
- DSGVO-Datenexport (Art. 15/20): tracking_insights wird im Workspace-Datenexport ausgegeben (alle Spalten außer internen Primär-/Fremdschlüsseln, inklusive filter_state und data_context JSONB)
Website-Tracking Agency-View Dashboard (PROJ-441)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an einer konsolidierten Portfolio-Sicht auf alle betreuten Kunden-Domains zur Priorisierung von Betreuungsaufgaben). Reine Read-Aggregation über bestehende Datenbestände — keine neue Datenerhebung, keine neuen personenbezogenen Daten. Erweitert PROJ-288 (First-Party Tracking), PROJ-290 (ABM), PROJ-387 (Formular-Analyse) und PROJ-436 (KI-Engine) um eine aggregierte Anzeige-Ebene.
- Aggregierte Portfolio-Kennzahlen (4 neue Read-Endpunkte): /portfolio-birds-eye liefert workspace-weite KPI-Aggregate (Sessions-Summe, Unique-Visitor-Count, gewichtete Conversion-Rate, Formular-Submit-Summe, Copy-to-Clipboard-Summe, Median true_reading_time, Hot-Account-Count, Bot-Share) für einen wählbaren Zeitraum (13 Presets + Custom-Range) sowie die gleiche Berechnung für die Vorperiode (Trend-Ermittlung). /portfolio-sparklines liefert Tagesaggregate pro Domain über 60 Tage für das Mini-Liniendiagramm im Smart Data Grid. /portfolio-quick-view liefert pro Domain den 30-Tage-Sparkline, Top-3-UTM-Quellen/-Medien, Median-Reading-Time, Copy-Count, Form-Submit-Count, 3 neueste Insights. Alle Aggregate sind Zahlen oder kategorische Gruppen (utm_source/utm_medium) — keine individuellen Sessions, keine IPs, keine Klartext-Nutzerinhalte.
- Erweiterung /portfolio-health (PROJ-412): 5 zusätzliche Felder pro Domain im Response — health_status (Enum: learning/healthy/needs_attention/critical), health_status_reasons (max. 3 menschenlesbare Grund-Texte für Tooltip), ai_pulse_has_signals (Boolean), ai_pulse_signal_count (Integer), ai_pulse_first_text (nullable Text aus tracking_insights.llm_explanation der Domain). Alle Felder sind Aggregations-Ableitungen aus bestehenden Daten (tracking_sessions, tracking_insights) — keine neue Datenerhebung, keine personenbezogenen Daten.
- Google Favicon-Service (externe Drittanbieter-Anfrage aus dem Browser): Frontend-Komponenten (portfolio-smart-grid.tsx, portfolio-quick-view-sheet.tsx, global-alert-center.tsx) laden Kunden-Favicons über `https://www.google.com/s2/favicons?domain=<domain>&sz=64`. Der Request erfolgt ausschließlich aus dem Browser des eingeloggten Agentur-Admins (nicht vom Tracking-Snippet auf Kunden-Websites). Google erhält nur den Domain-Namen der Kunden-Website als Query-Parameter; keine personenbezogenen Daten des Agentur-Admins oder der Endnutzer werden übermittelt. Fallback bei 404/Netzwerkfehler: farbiger Initialbuchstaben-Avatar (kein externer Request). Auftragsverarbeiter-Eintrag in PROCESSORS.Google LLC.
- LocalStorage (Browser, workspace-weit): Key `neuland.tracking.birds_eye_kpis.<user_id>` speichert die vom Agentur-Admin gewählten 3–4 KPI-Keys (Array von max. 4 Strings aus fester Whitelist von 8 Werten: sessions_total, unique_visitors_total, conversion_rate_avg, form_submits_total, copy_to_clipboard_total, engagement_rate_avg, hot_accounts_count, bot_share_pct). Keine personenbezogenen Daten, nur UI-Präferenz. TDDDG §25 Abs. 2 Nr. 2 (unbedingt erforderlich für den Dienst) — keine Einwilligung erforderlich, da funktional.
- URL-Parameter (Browser-URL, nicht serverseitig gespeichert): ?range=<preset> oder ?from=YYYY-MM-DD&to=YYYY-MM-DD zur Persistierung des gewählten Zeitraums in der URL. Kein Personenbezug. ?birds_eye_config=1 öffnet den KPI-Konfigurations-Dialog (Deep-Link für Hilfe-Center).
- PROJ-631 Business Impact Dashboard — Daily-Aggregat-Snapshots (business_impact_daily_snapshots, business_impact_gsc_snapshots): Tägliche Aggregat-Tabellen pro Workspace+Tag mit den 5 Funnel-KPIs (Impressions, Sessions, Engagement-Rate, Conversions, Leads) als Soll/Ist-Werte. Befüllt durch zwei pg_cron-Jobs (02:00 UTC: GSC-Snapshot via PROJ-27 GSC-Adapter; 03:00 UTC: Daily-Aggregator aus tracking_sessions, tracking_events, business_impact_lead_counts, ssot_items section=marketing_goal). Aggregat-Werte sind ausschließlich Zahlen (Counts, Rates) — KEINE personenbezogenen Daten, kein Session-Hash, keine IDs. Quellen-Tabellen behalten ihre eigenen Retention-Policies (tracking_sessions 180 Tage, business_impact_lead_counts 730 Tage). Aggregat-Tabellen Retention 730 Tage. Workspace-scoped, CASCADE-DELETE bei Workspace-Löschung. RLS: SELECT für aktive workspace_members, alle Writes ausschließlich via Service-Role (Cron-Pfad). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an konsolidierter Performance-Sicht). Read-API: /api/business-impact/portfolio (Agency-Portfolio) und /api/business-impact/:workspaceId (Detail). Im Datenexport (Art. 15/20 DSGVO) enthalten.
- PROJ-653 Erweiterung Kontakt-Achse (business_impact_daily_snapshots.contact_id, business_impact_gsc_snapshots.contact_id; jeweils nullable, FK auf contacts(id) mit ON DELETE CASCADE): Snapshots werden ab PROJ-653 zusätzlich auf eine Kontakt-Achse geführt, damit CRM-Kontakte mit Marketingzielen auch ohne eigenen Kunden-Workspace im Portfolio sichtbar sind. Workspace-Achse bleibt parallel für Backwards-Kompat. Die Aggregat-Werte (Counts, Rates) bleiben unverändert anonym — kein neuer Personenbezug, keine Eskalation der Datenkategorien. CASCADE-DELETE: bei Löschung eines Kontakts (Art. 17 DSGVO) werden die zugehörigen Snapshot-Zeilen automatisch via FK ON DELETE CASCADE entfernt; bei Workspace-Löschung greift weiterhin der Workspace-CASCADE. Zusätzlich: Konfigurations-Feld workspaces.agency_self_contact_id (UUID, nullable, FK auf contacts(id) ON DELETE SET NULL) — markiert deterministisch den CRM-Kontakt, der die eigene Agentur im Business-Impact-Portfolio repräsentiert (z.B. NEULAND.-Kontakt im Agentur-Workspace). Nur durch Workspace-Admin via /api/workspaces/settings setzbar; Pre-Write-Check stellt sicher dass der Ziel-Kontakt im gleichen Workspace liegt. Im Datenexport (Art. 15/20 DSGVO) enthalten: contact_id pro Snapshot-Zeile sowie agency_self_contact_id im Workspace-Stammdatensatz. Read-API: zusätzlich /api/business-impact/contact/:contactId (Kontakt-Detail) — Auth via workspace_members des Workspaces in dem der Kontakt liegt.
Behavioral Biometrics & Bot-Detection (PROJ-306)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Erkennung und Abwehr von Bot-Traffic, Click-Fraud und automatisierten Angriffen auf Werbebudgets) sowie an Verständnis des Nutzerverhaltens und Conversion-Messung auf Kundenwebsites
- Verhaltens-Event-Daten (tracking_events): 14 Behavioral-Biometrics-Event-Typen — rage_click, cursor_hesitation, rapid_scroll_bail, form_field_time, form_field_correction_rate, form_paste_action, form_abandonment_snapshot, copy_to_clipboard, text_highlighting, true_reading_time, exit_intent_movement, network_downgrade, bot_detection, click_fraud_analysis. Alle Events verwenden den anonymisierten Session-Hash aus PROJ-288 (kein Personenbezug). Event-Daten enthalten Interaktions-Metriken (Zeitdauern, Zähler, Schwellenwerte) — keine Inhalte, keine Eingabetexte, keine kopierten Daten
- Tracking-Expansion 2026-04-15 (tracking_events): 11 zusätzliche Event-Typen — scroll, outbound_click, file_download, view_search_results, form_submit, generate_lead, form_error, video_start, video_progress, video_complete, user_engagement. Identifikation weiterhin ausschließlich über den anonymen Session-Hash aus PROJ-288
- Navigations-Metadaten (page_view, scroll): page_title (max. 500 Zeichen), page_referrer (URL der Herkunfts-Seite), is_virtual_pageview (Boolean für SPA-Navigationen), scroll_depth_percent (Integer). Keine PII unless der Kunde personalisierte Seitentitel nutzt (diese liegen dann in page_title)
- Klick-Metadaten (outbound_click, file_download): link_url (Ziel-URL, max. 500 Zeichen), link_domain (Host-Name), link_text (sichtbarer Button-/Link-Text, max. 100 Zeichen — kann in Ausnahmefällen personalisierten Text enthalten wenn die Kundenwebsite diesen rendert), element_classes (CSS-Klassen-Namen, max. 200 Zeichen), file_url/file_name/file_extension
- Such-Metadaten (view_search_results): search_term (vom Nutzer eingegebener Suchbegriff aus URL-Parameter ?q=/?s=/?search=/?query=, max. 200 Zeichen). Begriff kann in Einzelfällen PII enthalten wenn der Nutzer persönliche Daten als Suchbegriff eingibt. Speicherung auf Session-Hash-Ebene, keine Verknüpfung zu einer Person
- Formular-Metadaten (form_start, form_submit, generate_lead, form_error): form_id (form#id oder Array-Index), form_name (name-/aria-label-Attribut), form_destination_url (action-Attribut), first_field_interacted (name-/id-Attribut des ersten fokussierten Felds), field_name (Feldname bei Fehler, max. 100 Zeichen), error_type (HTML5 ValidityState-Klassifikation: value_missing/type_mismatch/pattern_mismatch/etc.), error_message (HTML5 validationMessage — browser-lokalisierter Standardtext ohne Eingabewerte, max. 300 Zeichen). Keine Formular-INHALTE werden erfasst — nur Metadaten über Formular-Struktur
- Lead-Heuristik (generate_lead): Ein form_submit wird zusätzlich als generate_lead gemeldet wenn das Formular ein Feld vom Typ email/tel oder mit email/phone/telefon/mail im Namen enthält. Der E-Mail-Wert selbst wird NICHT erfasst, nur das Vorhandensein eines entsprechenden Felds
- Video-Metadaten (video_start, video_progress, video_complete): video_url (src-Attribut des <video>-Elements), video_title (title-/aria-label-Attribut), video_provider (derzeit ausschließlich 'html5' — YouTube-/Vimeo-Iframe-Tracking nicht implementiert), video_percent (0/10/25/50/75/100). Keine Video-Inhalte gespeichert
- Engagement-Metrik (user_engagement): engagement_time_msec (15.000 ms pro Heartbeat) — wird alle 15 Sekunden gesendet solange der Tab aktiv ist (document.visibilityState === 'visible'). Dient der Messung tatsächlicher Verweildauer. Keine PII
- Bot-Detection-Events (tracking_events, event_type: bot_detection): Client-seitige Bot-Erkennungs-Signale (navigator.webdriver, PhantomJS-Erkennung, UA-Bot-String-Match, fehlende Mausbewegung, Instant-Click <50ms). Ergebnis: is_bot (boolean) + confidence (0–100) + detected_signals (Array der positiven Signale). Keine personenbezogenen Daten
- Bot-Sessions (bot_sessions): Erkannte Bot-Sessions mit session_hash, domain_id, bot_confidence_score (0–100), bot_type (webdriver/phantom/ua_bot/no_mouse/instant_click/combined), detected_signals (JSONB-Array), ip_hash (täglicher HMAC-SHA256-Hash — IP-Adresse wird NICHT gespeichert). Dient der aggregierten Bot-Traffic-Analyse pro Domain
- Click-Fraud-Analyse (tracking_events, event_type: click_fraud_analysis): Nur für bezahlten Traffic (Sessions mit gclid/fbclid/msclkid). Berechnet einen Click-Quality-Score (0–100) basierend auf Verhaltenssignalen (Verweildauer, Scroll-Tiefe, Seitenbesuche). Score wird auf tracking_sessions.click_quality_score gespeichert. Keine personenbezogenen Daten
- Bot-Flag auf Sessions (tracking_sessions.is_bot): Boolean-Flag das bei erkanntem Bot-Traffic (confidence >70) auf true gesetzt wird. Dient der Filterung in Traffic-Analysen
- Forensische Einzel-Session-Ansicht (PROJ-416 Traffic-Qualität-Dashboard v2): Workspace-Admins/Manager/Member sehen für einzelne Click-Fraud-Sessions die detaillierten Trigger-Begründungen (serverseitig in lesbare deutsche Texte gemappt aus detected_signals und fraud_flags), den ip_hash (SHA-256), Quality-Score-Balken (0-100) und Bot-Typ/-Confidence. Keine Klartext-IP, keine Personennamen. Die Ansicht ist read-only und erfolgt auf Basis der bereits gespeicherten Daten aus bot_sessions und tracking_events — es werden keine zusätzlichen personenbezogenen Daten erhoben
Formular-Analyse-Modul (PROJ-387)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Optimierung der Formular-Ergonomie und Conversion-Messung auf Kundenwebsites). Rechtsgrundlage analog PROJ-288 (First-Party Tracking-Infrastruktur) — keine personenbezogenen Daten werden neu erhoben, die neuen Dimensionen erweitern ausschließlich bestehende Form-Events um Kontext-Metadaten.
- Erweiterung bestehender Form-Events um page_url (volle URL, max. 2.000 Zeichen) und page_title (Seitentitel, max. 500 Zeichen). Zweck: Zuordnung kryptischer form_ids zu Klartext-Seiten für die Dashboard-Anzeige. Betroffene Event-Typen: form_start, form_submit, form_complete, form_error, form_field_time, form_field_correction_rate, form_paste_action, form_abandonment_snapshot, generate_lead. Keine neuen personenbezogenen Inhalte — URL und Titel stammen aus den öffentlichen Seiten der Kundenwebsite
- PROJ-410-Erweiterung: Zusätzlich werden field_type (HTML-Inputtyp wie 'email', 'tel', 'text', max. 50 Zeichen), form_fingerprint (deterministischer FNV-1a-Hash der Formular-Struktur, 16 Zeichen) und step_number (numerischer Schritt-Index bei mehrstufigen Formularen, z. B. Heyflow) erfasst. Neue Event-Typen: form_step_view, form_step_complete. Alle Werte sind Meta-Informationen über die Formular-Struktur — KEIN Eingabeinhalt, KEIN Personenbezug
- Formular-Mappings (tracking_form_mappings): Klartext-Namen für Formulare (display_name, max. 300 Zeichen), optionale Notizen (max. 2.000 Zeichen), domain, form_id, page_url_pattern. Keine personenbezogenen Daten — reine Konfigurationsdaten des Workspace-Admins. Aufbewahrung: bis manuelle Löschung oder Workspace-Löschung (CASCADE)
- Tages-Aggregate (tracking_form_daily_aggregates, tracking_form_field_aggregates): Nach (workspace_id, form_id, page_url, Tag) bzw. (workspace_id, form_id, field_name, Tag) aggregierte Metriken — Zähler (page_views, form_starts, form_submits, form_errors), Median-Zeiten (median_duration_ms, median_time_ms), Raten (discovery_rate, completion_rate, correction_rate), Frustrations-Zähler (rage_click_count, cursor_hesitation_count aus PROJ-306), Feld-Effort-Score. Keine session_hashes, keine IPs — anonymisierte Aggregate
- Dark-Funnel-Matches (tracking_form_dark_funnel_matches): Pseudonymisierte Erkennung von 'erfolgreichen Abbrechern' — form_abandonment_snapshot + copy_to_clipboard-Event derselben Session innerhalb von 5 Minuten. Gespeichert: session_hash (anonymisierter HMAC aus PROJ-288), form_id, page_url, abandonment_at, copy_event_at, time_diff_seconds, copied_kind (phone/email/other). Keine kopierten Inhalte — nur die Kategorie des Werts
- Anomalie-Erkennung (on-the-fly): Vergleich der Fehlerrate eines Formulars gegen den gleitenden 7-Tage-Durchschnitt. Bei Abweichung über dem konfigurierbaren Workspace-Schwellwert (Default 20 %, Bereich 10–50 %) wird eine Inbox-Notification an admin + manager gesendet. Notification-Typ: form_error_rate_anomaly. Nutzer können Notifications über die Benachrichtigungs-Schaltzentrale (PROJ-237) deaktivieren
- Abbruch-Klassifikation: form_abandonment_snapshot-Events werden anhand von network_downgrade-Events (PROJ-306) in 'UX-Abbruch' vs. 'technischer Abbruch' klassifiziert. Rein rechnerische Zuordnung — keine neuen Daten
- DSGVO-Datenexport (Art. 15/20): Mappings (display_name, domain, form_id, notes) und aggregierte Metriken werden im Workspace-Datenexport ausgegeben. Rohdaten (einzelne Events) bleiben im bestehenden PROJ-288-Export
Semantische Feld-Normalisierung & Global Form Benchmarks (PROJ-410)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an semantischer Vereinheitlichung von Formular-Feldnamen zur Workspace-übergreifenden Vergleichbarkeit und Ergonomie-Analyse). Erweitert PROJ-387 (Formular-Analyse-Modul) — keine personenbezogenen Daten werden neu erhoben; rohe HTML-Feldnamen (Attribut-Werte aus <input name="...">) werden auf semantische Standardschlüssel gemappt. Für den KI-Klassifizierungspfad Auftragsverarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC (siehe PROCESSORS).
- Feld-Mappings (tracking_form_field_mappings): Zuordnung von anonymen HTML-Feldnamen (z. B. "FNAME", "vorname", "email-address-2", "prenom") auf semantische Standardschlüssel (STD_FIRST_NAME, STD_LAST_NAME, STD_EMAIL, STD_PHONE, STD_COMPANY, STD_MESSAGE, STD_ADDRESS, STD_ZIP, STD_CITY, STD_COUNTRY, STD_BIRTHDATE, STD_GENDER, STD_GDPR_CONSENT, STD_NEWSLETTER_CONSENT, STD_UNKNOWN). Gespeichert: workspace_id, field_name (max. 200 Zeichen, anonymer HTML-Attribut-Wert), normalized_std_key, confidence (0.0–1.0), source (heuristic/ai/manual), domain_id (optional), created_at, updated_at. Keine Eingabeinhalte, keine personenbezogenen Daten — ausschließlich Mapping-Metadaten
- Klassifizierung (2-Stufen): (1) Heuristik mit mehrsprachigem Wörterbuch (DE/EN/FR) — Konfidenz ≥ 0.7 wird direkt als source='heuristic' persistiert. (2) Rest (max. 50 pro Cron-Lauf) wird an Claude Haiku (Anthropic PBC) gesendet zur semantischen Klassifizierung. Übermittelt werden ausschließlich der Feldname und optional der field_type (HTML-Attribut) — keine Eingabewerte, keine Kontaktdaten, kein Personenbezug. Anthropic-Nutzung als 'anchor_validity_check'-analoge Verarbeitung (siehe PROCESSORS Anthropic PBC). Manuelle Overrides (source='manual') werden niemals überschrieben
- Global Form Benchmarks (agency_brain_form_benchmarks): Workspace-übergreifend anonymisierte Durchschnittswerte pro (STD-Schlüssel, field_type) — z. B. mediane Bearbeitungszeit für STD_EMAIL-Felder, durchschnittliche Korrektur-Rate für STD_PHONE-Felder. Aggregation erfolgt aus tracking_form_field_aggregates über alle teilnehmenden Workspaces. Keine workspace_ids, keine form_ids, keine Unternehmensnamen — nur statistische Verteilungen (Median, P25, P75, Sample-Größe). Mindest-Sample-Größe pro Zelle: ≥ 10 unabhängige Formulare aus ≥ 5 verschiedenen Workspaces (K-Anonymität). Zweck: Benchmarking der eigenen Formular-Ergonomie gegen anonymisierten Branchendurchschnitt
- Cron-Infrastruktur: (a) tracking-field-normalization läuft alle 5 Minuten, verarbeitet bis zu 100 neue Feldname-Kandidaten je Lauf. (b) agency-brain-form-benchmarks läuft täglich und aggregiert die Benchmarks neu. Alle Aggregationen sind rechnerisch — keine neuen Datenerhebungen
- Mehrstufige Formulare (Heyflow & generische Step-Flows): Neue Event-Typen form_step_view und form_step_complete erfassen den numerischen Schritt-Index bei mehrstufigen Formularen. Kein Inhalt der Schritte wird erfasst — ausschließlich Navigations-Metadaten (Schritt-Nummer, Zeitstempel, form_fingerprint). Workspace-Konfiguration 'multi_step_forms_enabled' (Default: true) und 'heyflow_origins' (Array von Heyflow-Embed-Ursprüngen) im tracking_domains-Config erlauben Admins das Feature zu deaktivieren. HeyFlow-Erfassung erfolgt auf zwei komplementären Pfaden: (a) postMessage-Listener für direkt eingebettete HeyFlow-iFrames (PROJ-410 BUG-2-C); (b) window.dataLayer-Monkey-Patch (PROJ-447) für GTM-Setups, bei denen HeyFlow Events in den GTM-DataLayer pusht. Der dataLayer-Patch ruft die native Array.prototype.push-Methode weiterhin über .apply() auf, sodass GTM und alle anderen DataLayer-Konsumenten unbeeinträchtigt bleiben. Erfasst werden ausschließlich Events mit source='heyflow' oder event-Name beginnend mit 'heyflow-' — alle anderen dataLayer-Einträge werden ignoriert. Zusätzliche event_data-Felder auf diesen Events: form_provider='heyflow' (statisches Label zur Unterscheidung von Contao- und Standard-HTML-Formularen), heyflow_raw_event_type (Original-Event-Name, max. 100 Zeichen) und heyflow_flow_id (technische Flow-ID, max. 100 Zeichen) — alle ohne Personenbezug. Dedup-Schutz zwischen postMessage- und dataLayer-Pfad über clientseitigen 500ms-Guard auf form_submit-Events mit gleicher form_id. PROJ-494-Erweiterung (Serverseitiges Heyflow Event-Mapping): Das snippet.js ergaenzt die event_data um heyflow_screen_name (Schritt-Bezeichnung des aktuellen Heyflow-Screens, z. B. Kontaktdaten, max. 200 Zeichen), heyflow_screen_id (technische Heyflow-Screen-ID, max. 200 Zeichen) und heyflow_previous_screen_name (Bezeichnung des vorherigen Screens, max. 200 Zeichen) — saemtlich Formular-Navigations-Metadaten ohne Personenbezug (kein Eingabeinhalt, kein Name, keine E-Mail). Serverseitig werden diese Felder auf normalisierte tracking_events.event_data-Schluessel gemappt: form_id (aus flowID), step_name, step_id, previous_step. Die Zuordnung von Heyflow-Event-Typen auf Standard-Event-Typen (z. B. heyflow-screen-view auf form_step_view) ist durch Admins workspace-individuell konfigurierbar und in der Tabelle heyflow_event_mappings gespeichert (Workspace-Overrides plus Server-seitige System-Defaults). Heyflow-Events die als Ignorieren konfiguriert sind werden serverseitig vollstaendig verworfen ohne DB-Insert
- DSGVO-Datenexport (Art. 15/20): tracking_form_field_mappings wird im Workspace-Datenexport ausgegeben (alle Spalten außer internen Primär-/Fremdschlüsseln). Agency-Brain-Benchmarks (agency_brain_form_benchmarks) sind nicht workspace-scoped und werden daher NICHT im Datenexport aufgeführt — sie enthalten definitionsgemäß keine workspace-spezifischen Daten
Automatisierte Heatmap-Engine (PROJ-389)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Optimierung der Seiten-UX auf Kundenwebsites). Rechtsgrundlage analog PROJ-288 (First-Party Tracking-Infrastruktur) — die Koordinaten-Events werden als prozentuale Viewport-Positionen (0–100) gespeichert und sind dadurch viewport-unabhängig anonymisiert.
- Koordinaten-Events (heatmap_data_points): Klick-Positionen, Mausbewegungen (throttled max. 1 pro 100 ms) und maximale Scroll-Tiefe pro Session. Koordinaten ausschließlich als Prozentwerte (0.00–100.00) relativ zum Viewport — kein Personenbezug in der Position selbst, da die Größe der Besucher-Bildschirme nicht rekonstruiert werden kann. Gespeichert: event_type (click/mousemove/scroll), x_percent, y_percent, scroll_depth_percent, device_type (desktop/mobile/tablet), viewport_width/viewport_height (zum Kontext der Aggregation), element_selector (CSS-Pfad des angeklickten Elements, max. 500 Zeichen — keine Eingabeinhalte), anonymer session_hash aus PROJ-288 (HMAC mit Tages-Salt), Zeitstempel
- Heatmap Intelligence Layer 1 — Erweiterte Klick-Metadaten (PROJ-453): Zusätzlich zu den Koordinaten werden pro Klick-Event drei neue Felder erfasst: (1) click_inner_text — sichtbarer Elementtext (max. 200 Zeichen). Input-Masking in snippet.js verhindert die Erfassung aus <input>/<textarea>-Feldern; dennoch potentiell personenbezogen, wenn Kundenwebsites z.B. Namens-Tags in Kontakt-Cards rendern — wird deshalb mit Vorsicht behandelt und nur für die KI-Label-Generierung im Workspace verwendet. (2) time_to_interaction_ms — Millisekunden seit DOMContentLoaded bis zum Klick. Kein PBD. (3) is_dead_click — Boolean, markiert Frustrations-Klicks auf nicht-interaktive Elemente (erkannt per is_interactive-Heuristik + sessionStorage-Counter >= 3). Kein PBD. Rechtsgrundlage und Einwilligungspflicht wie beim Basis-Heatmap-Tracking (analog PROJ-389 / §25 Abs. 1 TDDDG).
- Heatmap Intelligence Layer 1 — KI-Element-Labels (heatmap_element_labels — PROJ-453): Cache-Tabelle für KI-generierte lesbare Element-Namen pro (Workspace, Domain, CSS-Selektor). Täglicher Cron (heatmap-label-generation, 02:00 UTC) gruppiert Klick-Events der letzten 7 Tage, wählt die Top-50 häufigsten Selektoren pro Workspace ohne aktuelles Label und übermittelt je Selektor + häufigsten click_inner_text an Claude Haiku (Anthropic). Ergebnis: ein deutscher Kurzname (max. 50 Zeichen) wie 'Button: Jetzt anfragen'. Labels älter als 30 Tage werden automatisch regeneriert um Seitenänderungen abzubilden. Fallback auf regelbasiertes Label aus Selektor-Parsing bei LLM-Timeout oder fehlendem innerText. Tabelle enthält ausschließlich technische Element-Beschreibungen — keine personenbezogenen Daten. Token-Verbrauch wird via logTokenUsage(feature=heatmap_semantic_labels) erfasst.
- Heatmap-Konfigurationen (heatmap_configs): Workspace-Einstellungen für Seiten-Pattern — Name, domain, url_pattern (z. B. /produkte/{slug}), url_type (exact/prefix/regex), device_filter (all/desktop/mobile), Flag is_auto_generated. Keine personenbezogenen Daten — reine Konfigurationsdaten der Agentur
- Seiten-Screenshots (Storage Bucket heatmap-screenshots, öffentlich lesbar): PNG-Screenshots der Heatmap-Seite in Desktop- (1280×800) und Mobile-Auflösung (375×812). Erstellt durch den hauseigenen Self-Hosted Screenshot-Service (PROJ-393, auf Fly.io Frankfurt betrieben durch NEULAND. Agentur GmbH, Playwright + Chromium in Docker), der die Seite ohne Cookies und ohne Login-Kontext rendert — keine personenbezogenen Inhalte im Screenshot. Kein externer Auftragsverarbeiter für die Screenshot-Erzeugung (nur Fly.io als Infrastruktur-Anbieter, siehe PROCESSORS). Pfad: {workspaceId}/{heatmap_id}/{device}_{timestamp}.png. Max. 10 MB pro Screenshot
- Automatische Heatmap-Generierung: Ein täglicher Cron-Job (heatmap-auto-generate) analysiert die Top-20-Seiten pro aktiver tracking_domain aus heatmap_data_points der letzten 7 Tage und erstellt automatisch heatmap_configs. Template-Grouping: URL-Segmente werden normalisiert (UUIDs → {uuid}, Ziffern → {id}, Slugs → {slug}); ab 5 URLs pro Muster entsteht eine aggregierte Prefix-Config. System-URLs (/error, /404, /500, /login, /api, /admin) werden ausgeschlossen. Manuell angelegte Configs (is_auto_generated=false) werden niemals überschrieben
- DSGVO-Datenexport (Art. 15/20): heatmap_configs (Konfigurationsdaten) werden im Workspace-Datenexport als Liste ausgegeben. heatmap_data_points werden als Gesamtanzahl (Count) exportiert — keine Rohdaten (aggregierte Prozent-Koordinaten mit pseudonymisiertem session_hash haben keinen direkten Personenbezug; die Rohdaten bieten keinen Art. 15-Mehrwert gegenüber den bereits aggregierten Heatmap-Ansichten). Fix DSGVO-1 AUDIT-2026-04-19 (R-295).
- PROJ-397 Admin-Monitoring (Agentur-intern): Täglich 09:00 UTC läuft ein Cron (tracking-consent-gap-alert), der Workspace-Admins per Inbox-Benachrichtigung (tracking_consent_gap) informiert, wenn eine Domain mit aktiviertem heatmap_enabled seit 7+ Tagen keine heatmap_data_points erfasst hat. Admin-Bypass möglich via tracking_domains.consent_bypass=true (nur für interne Test-Domains empfohlen — auf öffentlichen Kundenwebsites DSGVO-kritisch und mit destructive-styled Warnhinweis im Admin-UI versehen). Monitoring betrifft ausschließlich Agentur-Admin-Kommunikation — keine Datenübermittlung an Kunden oder Besucher.
Digitale Medienverwaltung — Markenassets-Bibliothek
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Agentur verwaltet Markenassets im Auftrag des Kunden)
- Markenassets (brand_assets): Name (max. 200 Zeichen), Kategorie, Abteilungs-Tags (JSONB-Array), optionale Beschreibung (max. 1.000 Zeichen), Dateipfad im Storage, Dateiname, Dateigröße, MIME-Typ, Freigabe-Status (intern/veröffentlicht), Platzhalter-Flag (is_placeholder — Boolean, kein PII), Herkunfts-Verweis auf Redaktionsplan-Eintrag (source_editorial_entry_id — interne FK, kein PII), Sortierung, Hochladender Benutzer (created_by — User-ID, indirekt personenbezogen). Aufbewahrung: Bis zur manuellen Löschung durch ein Workspace-Mitglied oder bis zur Löschung des zugehörigen Kontakts (CASCADE) bzw. Workspaces (CASCADE)
- Asset-Versionen (brand_asset_versions, PROJ-349): Versionslabel (max. 500 Zeichen — kann indirekten Personenbezug enthalten, z.B. 'Version für Kunde XY'), Dateipfad im Storage, Dateiname, Dateigröße, MIME-Typ, Primär-Flag (is_primary — Boolean), Sortierung, Ersteller (created_by — User-ID, ON DELETE SET NULL, DSGVO-konform). Aufbewahrung: Bis zur manuellen Löschung der Version, des übergeordneten Assets oder des Workspaces (CASCADE). Zweck: Verwaltung von A/B-Test-Varianten und alternativen Kreativ-Dateien unter einem Asset-Datensatz
- Dateien im Storage (Bucket brand-assets, privat): Dateien werden in einem privaten Supabase-Storage-Bucket gespeichert. Pfad: {workspaceId}/{contactId}/brand-assets/{uuid}/{dateiname}. Zugriff nur über signierte URLs (1 Stunde Gültigkeit) für berechtigte Workspace-Mitglieder. Erlaubte Formate: PDF, DOCX, PPTX, Bilder (PNG, JPG, SVG, GIF, WEBP), Design-Formate (AI, EPS, PSD, INDD), ZIP, Video (MP4, MOV). Maximale Dateigröße: 200 MB pro Datei
- DSGVO-Datenexport (Art. 15/20): brand_assets-Metadaten (Name, Kategorie, Tags, Beschreibung, Dateiname, Dateigröße, Dateityp, Freigabe-Status, Ersteller-ID, Zeitstempel) sind im Workspace-Datenexport enthalten
- PROJ-589 SSOT Asset Rückkanal (brand_assets-Erweiterung): brand_assets.contact_id ist nullable für Workspace-eigene Assets ohne Contact-Bezug (z.B. via CMS-Block-Editor hochgeladen). Neue Spalte content_hash (SHA-256 der Datei) für Duplikat-Erkennung beim Upload — kein PII, rein technischer Fingerprint. Neue Spalte cms_block_count (Integer) als Aggregator: Anzahl cms_blocks im Workspace die das Asset referenzieren — wird via Trigger auf cms_blocks-INSERT/UPDATE/DELETE automatisch gepflegt. Neue Spalte master_image_brand_asset_id auf cms_blocks (FK auf brand_assets) sowie additional_image_brand_asset_ids[] (UUID-Array) erlauben CMS-Blocks Bilder direkt aus dem brand_assets-Pool zu referenzieren statt externe URLs zu speichern — entspricht der CI-Konsistenz und vermeidet IP-Leaks an externe Server. Orphan-Detector-Cron (täglich 03:00 UTC) findet brand_assets mit cms_block_count=0 die älter als 7 Tage sind und benachrichtigt Workspace-Admin per Inbox (notification-type 'brand_asset_orphan_detected'). Quellen-Markierung: ai_generated_by='higgsfield' für Higgsfield-AI-Bilder (PROJ-596), kein expliziter source-Flag bei manuellen CMS-Uploads (file_url-Pfad-Segment '/cms-uploads/' nach der workspace_id identifiziert sie). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (Konsistenz der Markenpflege).
Brand Hub & Unified Kunden-Präsentation — Operative Markenzugänge für externe Nutzer
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) / Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — operative Bereitstellung von Markenunterlagen und Marketing-Strategie)
- Brand Hub Links (brand_hub_links — Legacy): Link-Titel (interner Name, max. 200 Zeichen), Link-Token (UUID), sichtbare Bereiche (JSONB-Array), Abteilungsfilter-Konfiguration, optionaler PIN-Hash und PIN-Salt (PBKDF2, 100.000 Iterationen — Klartext-PIN wird nicht gespeichert), Ablaufdatum, Aktivierungsstatus, Aufrufzähler, Ersteller (created_by — User-ID), Erstellungszeitpunkt, Aktualisierungszeitpunkt
- Unified Präsentations-Links (ssot_presentation_links — PROJ-320, erweitert PROJ-322): Link-Titel (interner Name, max. 200 Zeichen), Link-Token (UUID), sichtbare Sektionen (JSONB-Array, bis zu 17 Bereiche: Marketing-Strategie + Corporate Identity + Monitoring + Kennzahlen), Abteilungsfilter-Konfiguration, optionaler PIN-Hash und PIN-Salt (PBKDF2, 100.000 Iterationen — Klartext-PIN wird nicht gespeichert), Ablaufdatum, Aktivierungsstatus, Aufrufzähler, Ersteller (created_by — User-ID), Erstellungszeitpunkt, Aktualisierungszeitpunkt. Alle Daten werden live aus den Quelltabellen geladen (kein Snapshot). PROJ-322-Erweiterung: 7 neue Sektionen (uptime_status, pagespeed, visibility_index, keyword_rankings, marketing_goal_kpis, campaign_analytics, traffic_overview) zeigen aggregierte Monitoring- und Kampagnen-Metriken aus bestehenden Tabellen (monitors, pagespeed_checks, domain_visibility_history, keyword_rankings, campaign_snapshots, daily_campaign_performance). Diese Daten enthalten keine personenbezogenen Daten — ausschließlich technische Metriken (Verfügbarkeit, Scores, Positionen, Impressions, Klicks, Kosten). PROJ-1545-Erweiterung (Datenminimierung): Ein Präsentations-Link kann optional einem oder mehreren Segmenten (crm_segments, PROJ-1538) zugeordnet werden — bereits als Multi-Select-Zuordnung über die Join-Tabelle ssot_presentation_links_segments vorhanden. Ist ein Link segmentiert, liefert die öffentliche Route nur noch Inhalte des/der zugeordneten Segments/Segmente plus global geltende Inhalte, statt wie zuvor immer alle Daten des Kontakts — reduziert die auf dem öffentlichen Link exponierte Datenmenge (Art. 5 Abs. 1 lit. c DSGVO, Datenminimierung). Unsegmentierte Links (0 zugeordnete Segmente, weiterhin der Standardfall) verhalten sich unverändert
- Aufrufzählung: Beim Öffnen eines Brand Hub oder Präsentations-Links wird der Aufrufzähler um 1 erhöht. Zur Deduplizierung wird ein IP-basierter Rate Limiter verwendet (max. 1 Inkrement pro IP + Token pro Stunde). Die IP-Adresse wird NICHT in der Datenbank gespeichert — nur temporär im Rate-Limit-Cache (Upstash Redis, automatische TTL-Löschung nach 1 Stunde)
- DSGVO-Datenexport (Art. 15/20): brand_hub_links- und ssot_presentation_links-Metadaten (Titel, Token, sichtbare Bereiche, Abteilungsfilter, Ablaufdatum, Status, Aufrufzähler, Ersteller-ID, Zeitstempel) sind im Workspace-Datenexport enthalten. PIN-Hash und PIN-Salt werden aus Sicherheitsgründen NICHT exportiert
Corporate Design Assets (SSOT CI-Bereich)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Agentur dokumentiert Corporate Design im Auftrag des Kunden)
- Corporate Design Assets im Supabase Storage Bucket 'ssot-media' (öffentlich lesbar, Pfad: {workspaceId}/{contactId}/{section}/{dateiname}): Logos (Normal/Invertiert/Hintergrund), Farbfeld-Dateien (SVG/PNG), Schrift-Vorschaubilder (Headline/Paragraph), Moodboard-Bilder, Favicon (.ico/.png/.svg). Enthält Unternehmens-Design-Assets — typischerweise keine personenbezogenen Daten; bei Einzelunternehmern kann ein persönliches Logo mittelbar personenbezogen sein (Art. 6 Abs. 1 lit. b DSGVO, analoges Rechtsverhältnis wie Kontaktnamen in SSOT-Präsentationen)
- PROJ-404: CSS-Design-Token-Dateien (text/css, max. 1 MB) im selben Bucket 'ssot-media' unter Pfad {workspaceId}/{contactId}/ci_token_file/ — automatisch generierte CSS-Custom-Properties aus den CI-Daten (Farben, Fonts, 8px-Spacing-Raster, WCAG-Kontrast-Werte als Kommentare). Enthält keine personenbezogenen Daten — nur Design-Konfiguration. Max. 1 Datei pro Kontakt (Upsert beim Brand-Hub-Veröffentlichen)
- PROJ-405: CSS-Komponenten-Library-Dateien (text/css, max. 1 MB) im selben Bucket 'ssot-media' unter Pfad {workspaceId}/{contactId}/ci_components_file/ — automatisch generierte CSS-Klassen für UI-Komponenten (7 Button-Typen mit State-Matrix, Navigation, Data-UX, Floating Elements, Pagination) basierend auf den Design-Tokens aus PROJ-404. Zwei Varianten: 'components' (nur Komponenten-CSS) oder 'combined' (Tokens + Komponenten). Enthält keine personenbezogenen Daten — nur Design-Konfiguration. Max. 1 Datei pro Kontakt (Upsert beim Brand-Hub-Veröffentlichen)
- Corporate Design Metadaten in ssot_items.data (JSONB): Farbwerte (HEX, RGB, CMYK, Pantone, HKS, Folie), semantische Farbrollen, Typografie-Angaben (H1–H6, Plattform, Klassifizierung, Beschreibung, Download-Link), Logo-Typen und Varianten, Moodboard-Bezeichnungen, Tonalität und Sprach-Guidelines (CI Language)
- PROJ-404: Design-Token-Konfiguration in ssot_items.data (JSONB) über zwei neue Sections: 'ci_token_context' (Area-Context-Overrides pro Sub-Bereich wie Karriere/Intranet — Felder: name, slug, overrides als Token-Name→Wert-Map) und 'ci_token_file' (Brand-Hub-Veröffentlichungs-Metadaten — Felder: file_url, published_at, file_size_kb). Beide enthalten ausschließlich Design-Token-Konfiguration — keine personenbezogenen Daten
- PROJ-405: UI-Komponenten-Library-Metadaten in ssot_items.data (JSONB) über neue Section 'ci_components_file' (Brand-Hub-Veröffentlichungs-Metadaten — Felder: file_url, published_at, file_size_kb, variant). Enthält ausschließlich Design-Konfiguration — keine personenbezogenen Daten. Singleton pro Kontakt (max. 1 Eintrag)
- PROJ-473: Responsive Typography Konfiguration in ssot_items.data (JSONB) über neue Singleton-Section 'ci_typography_responsive' — Felder: mobile_base_px, tablet_base_px, desktop_base_px (Integer 10–24). Enthält ausschließlich Design-Konfiguration (Schriftgrößen-Basiswerte) — keine personenbezogenen Daten. Singleton pro Kontakt (max. 1 Eintrag)
- PROJ-519 Favicon-Pipeline (ci_favicon JSONB-Felder in ssot_items.data): Speichert Original-Favicon-Upload (PNG ≥500×500) plus 8 generierte Format-Varianten (favicon-16x16.png, favicon-32x32.png, apple-touch-icon-180.png, android-chrome-192/512.png, mstile-150x150.png, favicon.ico, safari-pinned-tab.svg, site.webmanifest) im public Bucket 'ssot-media' unter Pfad {workspaceId}/{contactId}/favicon/. JSONB-Felder: source_url (Original-Upload), formats (Map: format-key → {url, file_size, generated_at}), generated_by_ai (Boolean), ai_suggestion_status ('pending' | 'approved' | 'rejected'). Enthält keine personenbezogenen Daten — nur Design-Bilddateien. Optional: KI-Berater (Claude Vision Haiku) analysiert Logo + Brand-Farben (Hex-Werte) und gibt Crop-/Background-Empfehlung zurück — Bild-Analyse ist transient (Anthropic speichert nicht persistent), keine personenbezogenen Daten in Prompt oder Response
- PROJ-519 Logo-Sync (Spiegelung ssot_items.ci_logo → brand_assets): Logos aus dem SSOT-CI-Bereich werden automatisch als brand_assets-Einträge in der Kategorie 'Logo (SSOT)' angelegt. Sync-Anker: ssot_items.data.brand_asset_id (UUID) ↔ brand_assets.source_ssot_item_id (FK). Idempotente Aktualisierung bei PATCH (Name + file_url werden synchron). Bei DELETE in der SSOT bleibt der brand_assets-Eintrag erhalten und wird mit source_removed=true markiert (AC-22, kein Auto-Delete — Verlustrisiko bei Mehrfachverwendung des Logos). Notification 'ssot_logo_synced_to_brand_assets' an den auslösenden Nutzer
- PROJ-519 Google Fonts API (server-side): Schriftarten-Auswahl im SSOT-CI-Tab nutzt einen server-side Proxy auf die Google Fonts Developer API (https://www.googleapis.com/webfonts/v1/webfonts) mit serverseitigem API-Key. Antworten (Liste aller verfügbaren Google Fonts mit Family-Name, Kategorie, Variants, Subsets) werden in Upstash Redis 24h gecacht. Keine personenbezogenen Daten werden an Google übermittelt — nur generischer Server-Request mit API-Key. Schriftschnitt-ZIP-Downloads streamen die TTF-Dateien direkt von fonts.gstatic.com (öffentliche CDN, kein Auth). Abgrenzung zu PROJ-406 (browser-seitiges @import auf fonts.googleapis.com): PROJ-519 ist server-side, leakt keine User-IPs an Google
- DSGVO-Datenexport (Art. 15/20): CI-Daten inkl. aller ssot_items-Sections (auch ci_token_context, ci_token_file, ci_components_file, ci_typography_responsive und ci_favicon mit allen PROJ-519-Sub-Feldern) sind im Workspace-Datenexport (GET /api/workspaces/data-export) als JSON enthalten sowie über GET /api/contacts/[id]/ssot/export als Markdown exportierbar. brand_assets-Einträge der Kategorie 'Logo (SSOT)' inkl. source_ssot_item_id und source_removed werden ebenfalls exportiert. Storage-Dateipfade (Original + 8 Favicon-Formate) werden im Export referenziert
- PROJ-520 Automatisches KI-Design-Erfassen (ssot_ci_analysis_jobs): Pro Kontakt speichert das System Analyse-Jobs mit den Quell-URLs (max 3) und Pfaden zu hochgeladenen Quell-Dateien (PDF/PNG/JPEG, max 5, max 20 MB pro Datei; bei Analyse-Typ Kommunikation/Beides zusätzlich TXT/MD/Word .docx, PROJ-1424) im Bucket 'ssot-media' unter Pfad {workspaceId}/{contactId}/ki-analysis/uploads/. Die Quell-Dateien werden 24 Stunden nach Job-Abschluss vom Cleanup-Cron (ssot-ci-analysis-cleanup) automatisch aus dem Bucket gelöscht (DSGVO-Datenminimierung — Brand-Manuals von Drittanbietern werden nicht persistent gespeichert). Job-Metadaten (status, urls, source_files, processing_step, attempts, result mit KI-Vorschlägen, error, created_by, created_at, started_at, completed_at, confirmed_at) bleiben für 90 Tage als Audit-Trail erhalten und werden danach via Cleanup-Cron entfernt. KI-Analyse: Quell-Inhalte (Web-Screenshots via Playwright + HTML-Hinweise via Cheerio + hochgeladene Dokumente) werden transient an Anthropic Claude Sonnet 4.5 Vision übergeben — keine Persistenz beim Provider (siehe PROCESSORS-Eintrag Anthropic). Vom Nutzer bestätigte CI-Vorschläge werden in ssot_items (ci_color, ci_font, ci_logo, ci_image, ci_moodboard, ci_favicon) bzw. ssot_ci_language (Tonalität) übernommen. RLS: SELECT für alle Workspace-Mitglieder, INSERT/UPDATE/DELETE für admin/manager. Workspace-scoped, CASCADE-DELETE bei Kontakt-/Workspace-Löschung. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse Agentur-CI-Pflege)
- PROJ-574 KI-Sprach- & Kommunikations-Erfassung (Erweiterung von PROJ-520, ssot_ci_analysis_jobs.analysis_type='communication'|'both'): Zusätzlich zum Design-Modus extrahiert die KI aus Website-Texten (gescraped via Cheerio body_text, max 24.000 Zeichen) und optional hochgeladenen PDF-Corporate-Language-Guides sowie (PROJ-1424) TXT/MD/Word-.docx-Dokumenten (PDF nativ via Sonnet-4.5-document-Block; TXT/MD/Word werden lokal zu Text extrahiert, kein Vision-Call) strukturierte Markensprache: Tonalität (2–5 Sätze), Dos & Don'ts (3–8), Beispielsätze (3–6), Wording-Whitelist und -Blacklist (je 5–20 Wörter), Alleinstellungsmerkmale/USPs (3–8). Übergabe transient an Anthropic Claude Sonnet 4.5 (KEIN Vision für reine Communication-Modi — nur Text/PDF/Word, billiger). Vom Nutzer bestätigte Vorschläge werden via Confirm-Endpoint mit Replace/Merge-Modus in ssot_ci_language (tonality, dos_donts, example_sentences, whitelist, blacklist via UPSERT auf workspace_id+contact_id) bzw. ssot_items (section='usp') übernommen. Dieselben Tabellen, Job-Worker, Cleanup-Cron und Notifications wie PROJ-520 — nur eine zusätzliche Spalte analysis_type ('design'|'communication'|'both') unterscheidet die Modi. Zusätzlich (PROJ-575) extrahiert die KI bei Communication-Analyse strukturierte Marken-Richtlinien (max 10 Einträge, max 5.000 Zeichen Content pro Richtlinie, Kategorien aus geschlossener Whitelist: brandbook, corporate_styleguide, content_styleguide, tone_of_voice, social_media_guidelines, corporate_communication, employer_branding, code_of_conduct, accessibility_guidelines, sonstiges) — übernommen werden sie als ssot_items mit section='ci_guideline' (Replace- oder Merge-Modus, mit Inline-Edit-Möglichkeit für Title/Description/Content vor Übernahme). DSGVO-Datenexport bereits via PROJ-520 abgedeckt (workspaces/data-export schreibt ssot_ci_analysis_jobs). Rechtsgrundlage analog PROJ-520: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse Agentur-CI-Pflege). Hinweis: Website-Texte können Personennamen (Testimonials, Team-Seiten) enthalten und werden als solche transient an Anthropic übermittelt — kein PII-Scrubbing, da der Workspace die Inhalte selbst kuratiert hat
Agency Brain Data Lake
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse) + explizites Opt-in durch Agentur-Admin mit schriftlicher Kundeneinwilligung (AVV-Pflicht)
- Anonymisierte Kampagnenmetriken: Branche, Kampagnentyp, Analyse-Dimension, Metrik-Schlüssel und numerischer Metrik-Wert, Beitragszeitpunkt
- Anonymisierungs-Lookup: workspace_id zu stabile anonyme UUID (nur Service-Role-Zugriff, keine regulären Nutzer)
- Teilnahme-Status: Workspace-ID, Opt-in-Datum, Opt-out-Datum, Anzahl beigetragener Datenpunkte
- Keine personenbezogenen Daten natürlicher Personen im Data Lake. Ausschließlich anonymisierte, aggregierte Kampagnenmetriken
Agency Brain KI-Analyse
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse)
- Anthropic Claude API erhält ausschließlich aggregierte, anonyme Metriken (Branche, Kampagnentyp, Metrik-Werte). Keine Workspace-IDs, keine Klarnamen, keine personenbezogenen Daten
- KI-generierte Insights: Erkenntnis-Text, Analyse-Dimension, Branche, Konfidenz-Score, Anzahl Datenpunkte, Erstellungsdatum
Asset-Tracking-IDs & Agency Brain Asset-Performance
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: werbewirksame Ressourcennutzung der Agentur)
- Asset-Tracking-IDs (brand_assets.asset_tracking_id, z. B. IMG-8492): Technische, sequentielle Kennzeichnung pro Brand-Asset zur netzwerkübergreifenden Performance-Auswertung. Kein Personenbezug
- Zähler-Tabelle (workspace_asset_counters): Pro Workspace und Asset-Typ-Präfix die letzte vergebene Nummer. Kein Personenbezug
- Tracking-Event-Anreicherung (tracking_events.event_data.asset_id): Aus UTM-Parametern extrahierte Asset-ID wird dem Event-Payload hinzugefügt — diese ist eine technische Kennzeichnung ohne Personenbezug. Die personenbezogenen Anteile des Tracking-Events selbst (IP-Hash, Session-Hash) unterliegen dem First-Party-Tracking-Eintrag (PROJ-288)
- Tägliche Aggregations-Tabelle (agency_brain_asset_stats): Pro Workspace, Asset-ID, Datum und Netzwerk (utm_source) werden Sessions, Conversions und Rage-Click-Counts aggregiert. Keine individuellen Sessions, keine Besucheridentitäten, nur summierte Zahlen
Marketing-KPI Soll-IST-Vergleich (Business-Impact-Tab, PROJ-413/PROJ-522)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: Messung der Wirksamkeit von Marketingmaßnahmen im Auftrag des Kunden). Verarbeitung ausschließlich aggregierter, nicht-personenbezogener Metriken.
- SSOT-Planungsvariablen (ssot_items.data.funnel_inputs): TCQ, QCR, CCR, ER, CTR-CTA, CR-PCT, SPI, CTR-Ad, ACV, ACF — manuelle Planungsziele der Agentur, kein Personenbezug. Workspace-scoped, CASCADE-DELETE bei Workspace-Löschung
- Abgeleitete KPIs (clientseitig berechnet, keine Persistenz): TLQ, RAU, RAI, TCV, RAS, PAS, CAI, CVR, CPR — reine Rechenergebnisse aus funnel_inputs, werden nicht in der DB gespeichert
- IST-Metriken (aggregiert aus tracking_events/tracking_sessions, nur Zähler): Engagement-Rate (Anteil Sessions mit Reading-Events), Website Conversion Rate (Leads/Sessions), CTR-CTA (Button-Click-Sessions/Sessions), CR-PCT (Form-Submit-Sessions/Sessions) — keine individuellen Sitzungen, keine Besucheridentitäten, ausschließlich aggregierte Verhältniszahlen. Rechtsgrundlage analog First-Party-Tracking-Eintrag (PROJ-288)
- Neue Verarbeitungsform (PROJ-522): SSOT-Planungsvariablen werden als Soll-Benchmarks den aggregierten IST-Metriken gegenübergestellt. Diese Kombination aus Planungsdaten und Tracking-Aggregaten ist ein eigenständiger Verarbeitungszweck (Business-Impact-Messung). Keine neue Datenspeicherung, kein neuer Personenbezug — ausschließlich Anzeigelogik aus bereits rechtmäßig verarbeiteten Quellen
SSOT Segment-Datenmodell (Kontakt → Segment → SSOT-Entitäten)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: Organisation der SSOT-Marketingdaten von Kontakten mit mehreren Marken/Bereichen). Reine B2B-Organisationsmetadaten, kein Bezug zu einer natürlichen Person des Kontakts.
- crm_segments: Neue Tabelle für frei benannte Marken-/Bereichs-Segmente pro Kontakt (id, contact_id, workspace_id, name, color, status aktiv/archiviert, position, created_by, Zeitstempel). name/color sind vom Agentur-Mitarbeiter frei gewählte Organisationsbezeichnungen (z. B. Markenname, 'Karriere') — kein Personenbezug zum Kontakt. created_by (FK auth.users) referenziert den anlegenden Agentur-Mitarbeiter — bestehende Auditing-PII-Kategorie, analog allen anderen Tabellen mit created_by im System
- ssot_items.is_global/was_global: Zwei neue Boolean-Spalten auf der bestehenden ssot_items-Tabelle. Kein neuer Datentyp, nur eine Sichtbarkeits-/Zuordnungs-Kennzeichnung bestehender SSOT-Inhalte zu Segmenten
- ssot_item_segments: Neue n:m-Zuordnungstabelle (ssot_item_id, segment_id, workspace_id, created_by, created_at) — reine Verknüpfungsdaten, keine eigenen Inhaltsfelder
- PROJ-1540: ssot_ci_language.segment_id (neue nullable Spalte auf der bestehenden Tonalitäts-Tabelle, FK auf crm_segments, ON DELETE CASCADE, live via pg_constraint verifiziert). Ermöglicht pro Kontakt eine globale Tonalitäts-Zeile (segment_id IS NULL) plus optional je eine segmentspezifische Zeile — keine neue Datenkategorie, nur eine zusätzliche Zuordnungsdimension auf bereits dokumentierten Tonalität/Dos-Don'ts/Wording-Feldern. Content-Intelligence-Cluster erhalten ihr angezeigtes Segment rein lesend abgeleitet (Cluster → zugeordnete Keywords → deren Bedarfsgruppen-Zuordnung → Segment der Bedarfsgruppe) — kein neues Feld auf keyword_clusters, keine neue Datenkategorie
- PROJ-1541 (Performance Engine Segment-Scope, 2026-07-20): paid_marketing_goals/paid_marketing_subgoals (bestehende Tabellen aus PROJ-788, ursprünglich ohne eigenen DATA_PROCESSING-Eintrag da 'keine PII, kein externer Service') bekommen contact_id (NOT NULL, FK auf contacts, ON DELETE CASCADE) und segment_id (nullable, FK auf crm_segments, ON DELETE SET NULL) — behebt den bisherigen Workspace-only-Scope-Bug. Beide Felder werden ausschließlich per DB-Trigger aus dem verknüpften SSOT-Marketingziel (ssot_items.contact_id/is_global über ssot_item_segments) abgeleitet, nie client-editierbar. Keine neue Datenkategorie — contact_id verweist wie bei ssot_items auf den B2B-Kontakt, kein Personenbezug zu einer natürlichen Person
SSOT Segment-Migrations-Wizard (einmalige Bestandsdaten-Überführung, PROJ-1539)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: geordnete, einmalige Überführung bestehender SSOT-Marketingdaten in das Segment-Modell aus PROJ-1538). Reine B2B-Organisationsmetadaten, kein Bezug zu einer natürlichen Person des Kontakts.
- crm_segment_migration_status: Neue, temporäre Buchhaltungstabelle (1 Zeile pro migrationsrelevantem Kontakt) mit id, contact_id, workspace_id, status (offen / geprueft_kein_segment / abgeschlossen), reviewed_by, reviewed_at, Zeitstempel. Der Status selbst ist ein reines Prozess-Metadatum ohne Personenbezug zum Kontakt
- reviewed_by (FK auth.users) referenziert den prüfenden Agentur-Mitarbeiter — bestehende Auditing-PII-Kategorie, analog created_by in crm_segments (PROJ-1538) und allen anderen Auditing-Spalten im System
Server-to-Server Conversion API (Meta CAPI + Google Ads Enhanced Conversions)
Rechtsgrundlage: Art. 6 Abs. 1 lit. a DSGVO (Einwilligung über Cookie-Consent-Banner). Übermittlung erfolgt nur bei vorliegender consent_given-Bestätigung der Session.
- SHA-256-gehashte E-Mail-Adressen, Telefonnummern, Vor-/Nachnamen und Postleitzahlen aus dem CRM (irreversibel gehasht, keine Klartextdaten verlassen das System)
- Event-Metadaten: Workspace-ID, Plattform (Meta/Google), Event-Typ, Status, Zeitstempel, HTTP-Statuscode (keine personenbezogenen Daten)
- Click-IDs aus Tracking-Sessions: gclid (Google), fbclid (Meta) — technische Identifikatoren ohne direkten Personenbezug
- Verschlüsselte Access-Tokens und OAuth-Credentials (AES-256-GCM) — technische Zugangsdaten, keine Endnutzerdaten
KI-Kampagnen-Analyse & Budget-Empfehlungen (AI Media Buyer)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: Optimierung von Werbekampagnen im Auftrag des Kunden). Verarbeitung ausschließlich von Kampagnen-Metadaten der verbundenen Ads-Konten — keine Endnutzer-Personendaten.
- Verschlüsselte OAuth-Credentials (Google Ads Refresh Token, AES-256-GCM) und Meta Ads System-User-Token (AES-256-GCM) — technische Zugangsdaten, keine Endnutzerdaten
- Kampagnen-Performance-Daten: Kampagnenname, externe Kampagnen-ID, täglicher Spend, Impressionen, Klicks, Conversions, CTR, CPC, CPM, Reichweite — aggregierte Metadaten ohne Personenbezug
- Kampagnen-Registry (campaign_registry, PROJ-1458): Kanonische Kampagnen-Identität pro Google-Ads-Kampagne (Kampagnenname, externe Kampagnen-ID, Netzwerk) mit intern generierter, nicht erratbarer Tracking-ID (nl_tid) als aktiver Attributions-Mechanismus (PROJ-2319, manuell je Verbindung/Entität ausgelöst) für Ad-Spend/Session/Lead-Verknüpfung — der Rückkanal (Rückschreiben der Tracking-ID als final_url_suffix ins Google-Ads-Konto) ist seit PROJ-2319 aktiv gebaut, siehe eigener Eintrag „Google-Ads Anzeigen-Tracking-ID-Provisionierung (PROJ-2319)" unten. Optionale Verknüpfung zu einem SSOT-Marketingziel (marketing_goal_id, FK ssot_items, SET NULL bei Löschung) — manuell durch Workspace-Admin/Manager in einer internen Debug-Ansicht gepflegt. Keine Endnutzer-Personendaten, ausschließlich Kampagnen-Metadaten wie im übrigen Eintrag. Kein automatisches Löschkonzept (die Kennung soll dauerhaft stabil bleiben, analog zu paid_campaigns) — nicht als Aufbewahrungsfrist-relevant eingestuft, da keine personenbezogenen Daten enthalten sind. RLS: SELECT/INSERT/UPDATE/DELETE nur admin/manager.
- Budget-Simulationsdaten aus der Google Ads API (CampaignBudgetSimulation) — aggregierte Prognosen ohne Personenbezug
- KI-generierte Budget-Empfehlungen: Empfehlungstext, Konfidenz-Score, Status-Änderungen inkl. bearbeitendem Workspace-Admin (user_id) — PII beschränkt auf interne Nutzer-ID
- Wechselkursdaten (Open Exchange Rates): öffentliche Tageskurse ohne Personenbezug
- Zeitplan & Lauf-Historie (automation_schedules / automation_schedule_runs, PROJ-1919): je Workspace ein einstellbarer Zeitplan für Kampagnen-Import und KI-Analyse (aus/stündlich/täglich/wöchentlich, Uhrzeit im Halbstunden-Raster, Europe/Berlin) inkl. updated_by (auth.users-Referenz des zuletzt ändernden Mitglieds, SET NULL bei Nutzerlöschung); je geplantem Lauf eine Protokollzeile mit Status, Erfolgs-/Fehlerzählern, Dauer und ggf. technischer Fehlermeldung — keine Endnutzerdaten. Lauf-Historie wird nach 90 Tagen automatisch gelöscht; beide Tabellen sind workspace-scoped (CASCADE) und im DSGVO-Datenexport (Art. 15/20) enthalten.
Performance Engine — Kampagnen-Konfigurator-Drafts (PROJ-931)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: Zwischenspeicherung unfertiger Kampagnen-Konfigurationen, damit Agentur-Mitarbeiter den mehrstufigen Konfigurator-Flow unterbrechen und fortsetzen können). Reine Arbeitsdaten der Agentur — keine Endnutzer-Personendaten.
- Konfigurator-Drafts (campaign_configurator_drafts): Pro begonnener Kampagnen-Konfiguration speichert das System den erstellenden Workspace-Nutzer (user_id), den gewählten CRM-Kontakt/Kunden (contact_id, Unternehmensbezug), das optionale Marketingziel (marketing_goal_id, NULL bei Expert-Override), den Modus (guided/expert), einen editierbaren Draft-Namen, den aktuellen Schritt (1–7) sowie den bisherigen Konfigurations-Fortschritt als JSON (config_data: Budget-, Targeting-, Netzwerk-Auswahl). PII beschränkt auf interne Nutzer-ID. Workspace-scoped, RLS: Nutzer sieht/ändert ausschließlich eigene Drafts. SET NULL bei Kontakt-/Marketingziel-Löschung, CASCADE-DELETE bei Nutzer-/Workspace-Löschung.
- Erweiterung paid_campaigns (PROJ-931): neue Spalte contact_id für Expert-Override-Kampagnen ohne Marketingziel (subgoal_id nun nullable, Anker-Constraint: subgoal_id ODER contact_id gesetzt) — Unternehmensbezug, kein Endnutzer-Personenbezug.
- KI-Ableitungen im Konfigurator (PROJ-955): Beim Eintippen des Kampagnenziels werden Zieltext, der durchgereichte Landingpage-Inhalt (Titel/Meta/H1/Body-Auszug — öffentlich abrufbare Seiteninhalte) und der SSOT-Kontext (Tonalität, Zielgruppen-Personas, CI, Whitelist/Blacklist) transient an Anthropic (Claude Sonnet, Auftragsverarbeiter — siehe PROCESSORS) übertragen, um Targeting-Empfehlungen und Konfigurator-Badges abzuleiten. Workspace-globaler Assistent via workspaces.campaign_config_assistant_id (FK ai_assistants, SET NULL bei Assistenten-Löschung). KEINE Persistenz: kein Chat-Verlauf, weder Prompt noch Antwort werden gespeichert; lediglich Token-Zähler in ai_token_logs (Feature campaign_configurator) ohne Inhalt. PII beschränkt auf interne Nutzer-ID des Token-Logs. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: KI-gestützte Kampagnen-Konfiguration). Bei nicht hinterlegtem Assistenten erfolgt keine Übertragung (lokale regelbasierte Engine als Fallback).
- Live-Targeting-Validierung & Cross-Network-Orchestrator (PROJ-974): Im Guided-Mode-Konfigurator werden Targeting-Begriffe und Keywords (Interessen, Job-Titel, Skills, Branchen-Keywords — reine Werbe-Targeting-Kriterien, KEINE Endnutzer-Personendaten) zur Live-Validierung serverseitig an die Werbeplattform-APIs übermittelt: Meta Graph (Targeting Search), LinkedIn Marketing API (Ad Targeting Facets/Entities), Google Ads Keyword Planner (jeweils Auftragsverarbeiter — siehe PROCESSORS). Die finale Kampagnen-Strategie (Budget-Verteilung, Funnel-Rollen pro Netzwerk, Phasierung, Targeting-Auswahl) wird als JSON in paid_campaigns.orchestrator_config persistiert — Unternehmens-/Konfigurationsbezug, kein Endnutzer-Personenbezug. KI-Funnel-Empfehlung (Anthropic, siehe oben PROJ-955) ist im UI als KI-Strategieempfehlung gekennzeichnet (EU-AI-Act-Transparenz, begrenztes Risiko). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO. Workspace-scoped, CASCADE-DELETE bei Workspace-Löschung (paid_campaigns_workspace_id_fkey); paid_campaigns ist im Workspace-Datenexport enthalten.
CRM-zentrierte Ads-Verbindungen & MCC-Verwaltung (First-Party Tracking 2.0)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: zentrale Verwaltung von Werbekonten im Kontext der Kundenbeziehung). Verarbeitung ausschließlich von technischen Verbindungsdaten und Kampagnen-Metadaten — keine Endnutzer-Personendaten.
- Verschlüsselte OAuth-Credentials (Refresh Token, Access Token — AES-256-GCM) für Google Ads, Meta Ads, Microsoft Ads — technische Zugangsdaten, keine Endnutzerdaten
- Konto-Identifikatoren: Plattform, Account-ID, Kontoname, MCC-Customer-ID — keine personenbezogenen Daten
- Zuordnungs-Metadaten: CRM-Kontakt-ID (Unternehmensbezug, kein Personenbezug), Import-Status und Zeitstempel
- MCC-Verbindungsdaten: workspace-weite Google MCC-Konfiguration mit verschlüsselten Tokens
- PROJ-737 CRM-Kontakt zu Tracking-Domain Mehrfach-Zuordnung (contact_tracking_domains): Junction-Tabelle für M:N-Beziehung zwischen CRM-Kontakten und Tracking-Domains (Spalten: id, workspace_id, contact_id, tracking_domain_id, is_primary, created_at, created_by). Pro Junction-Zeile genau eine Domain-Kontakt-Kombination; eine Zeile pro Domain darf is_primary=true sein und wird via DB-Trigger automatisch in das deprecated-Cache-Feld tracking_domains.contact_id gespiegelt (Backwards-Kompatibilität für 7 Pipeline-Consumer aus PROJ-389/PROJ-528/PROJ-653 — siehe Tech Design). Reine Zuordnungsdaten ohne Personenbezug. Workspace-scoped via FK workspace_id, RLS-Policies analog contact_ad_connections (SELECT: alle Workspace-Mitglieder; INSERT/UPDATE/DELETE: nur admin/manager).
- PROJ-737 Audit-Trail Tracking-Domain-Zuweisungen (activity_log mit entity_type='contact', event_type IN ('contact_integration_assigned','contact_integration_removed')): Pro Insert/Delete einer contact_tracking_domains-Zeile via UI wird ein Audit-Eintrag in der bestehenden, polymorphen activity_log-Tabelle geschrieben (entity_type='contact', entity_id=contact.id, actor_id=editierender User, metadata JSONB mit integration_type='tracking_domain', target_id (UUID der Tracking-Domain), target_label (Domain-Name als technische Bezeichnung — Unternehmens-Geschäftsdaten ohne Endnutzer-PII)). Append-only, RLS-geschützt, dauerhaft für Revisionssicherheit. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Audit-Transparenz analog PROJ-732). Backfill-Einträge aus der B-1-Migration werden OHNE activity_log-Eintrag erstellt (kein User-Aktor), spätere User-Aktionen erzeugen sauberen Audit-Trail. CASCADE bei Workspace-Löschung (activity_log.workspace_id); created_by/actor_id ON DELETE SET NULL bei User-Löschung — Audit-Eintrag bleibt anonymisiert.
Kampagnen-Projektzuordnung & KI-Vorschlag (PROJ-1874)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: Werbekampagnen im internen Ereignis-Verlauf dem richtigen Kundenprojekt zuordnen, statt jedes Ereignis manuell zu verschlagworten). Verarbeitung ausschließlich von Kampagnen- und Projekt-Metadaten der Agentur — keine Endnutzer-Personendaten.
- Erweiterung campaign_registry (PROJ-1874 Abschnitt 1): suggested_project_id/confirmed_project_id (FK projects, SET NULL bei Projekt-Löschung), suggestion_reason (KI-Begründungstext), suggestion_source ('einziges_projekt'|'namensaehnlichkeit'|'ki'), suggested_at/confirmed_at, assignment_state ('offen'|'bestaetigt'|'ohne_projekt'|'abgelehnt'). confirmed_by (FK profiles, ON DELETE SET NULL) ist die einzige personenbeziehbare Ergänzung — wer eine Zuordnung bestätigt hat, analog customer_timeline_events.released_by. Zusätzlich campaign_type/campaign_type_raw (Kampagnentyp/Kanal) und landing_page_url (stabile Zielseite) — reine Kampagnen-Metadaten ohne Personenbezug.
- KI-Vorschlags-Logik (Abschnitt 2, Claude Haiku, Auftragsverarbeiter — siehe PROCESSORS): nur für Kampagnen ohne eindeutigen Namens-/Laufzeit-Treffer und bei mehr als einem aktiven Projekt des Kunden. Übergeben werden Kampagnenname, Kampagnenlaufzeit, Kanal sowie Name/Beschreibung/Laufzeit der Projekte desselben Kunden — Geschäftsinhalte, keine Endnutzer- oder Kontaktdaten. Sicherheitsauflage (R-1446): alle Texte laufen als Daten, nie als Prompt-Anweisung; das Ergebnis wird gegen die echte Projekt-ID-Liste des Kunden geprüft, eine Kennung außerhalb dieser Liste wird verworfen. Kein Training, keine Persistenz des Prompts — nur suggestion_reason (die Begründung) wird gespeichert. Token-Tracking via ai_feature='campaign_project_suggestion'.
- Erweiterung customer_timeline_events (PROJ-1874 Abschnitt 1): is_cross_project/cross_project_ids (uuid[], ohne FK) — trägt ein Ereignis Kampagnen mehrerer Projekte, bleibt project_id leer und die beteiligten Projekte werden hier als Text-Referenz geführt (kein Fremdschlüssel, damit ein gelöschtes Projekt das Ereignis nicht verändert). Reine Zuordnungs-Metadaten ohne Personenbezug.
Google-Ads Anzeigen-Tracking-ID-Provisionierung (PROJ-2319)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: Kampagnen-Attribution auf Kampagnen-/Anzeigengruppen-/Anzeigen-Ebene statt nur auf Kampagnenebene wie im campaign_registry-Basisfall, PROJ-1458). Reine Werbekonto-/Konfigurationsmetadaten der Agentur — keine Endnutzer-Personendaten.
- ad_tracking_registry (nl_tid, network, external_campaign_id/external_ad_group_id/external_ad_id, level, is_provisioned, provisioned_at, last_push_error, skip_reason): Feingranulare Registry-Zeile je (Verbindung, Ebene, externe Entität) für die Tracking-ID-Rückschreibung auf Kampagnen-/Anzeigengruppen-/Anzeigen-Ebene (additiv zu campaign_registry). last_push_error/skip_reason sind normalisierte Google-Ads-Fehlertexte bzw. Skip-Begründungen (z.B. strukturell unveränderliche ETA-Anzeigen) — keine Tokens/Secrets/Kontonummern, keine Endnutzerdaten. Kein Endnutzer-Personenbezug, ausschließlich Kampagnen-/Anzeigen-Metadaten. Kein automatisches Löschkonzept (analog campaign_registry) — CASCADE bei Workspace-Löschung.
- ad_tracking_overrides (provisioning_level, created_by): Per-Entität-Übersteuerung des Provisionierungs-Verhaltens auf einem konkreten Kaskaden-Knoten (Kampagne/Anzeigengruppe/Anzeige) — feinster Override in der Eltern-Kette gewinnt, sonst der Verbindungs-Default. created_by (FK auth.users, ON DELETE SET NULL seit PROJ-2319 DSGVO-Nachbesserung F-4) referenziert den anlegenden Agentur-Mitarbeiter — bestehende Auditing-PII-Kategorie, analog created_by in anderen Tabellen.
- ad_marketing_goal_overrides (marketing_goal_id, created_by): Per-Entität-Übersteuerung des effektiven Marketingziels auf einem konkreten Kaskaden-Knoten — dieselbe Auflösungslogik wie bei ad_tracking_overrides, aber marketing_goal_id (FK ssot_items, ON DELETE CASCADE) statt provisioning_level. created_by (FK auth.users, ON DELETE SET NULL seit PROJ-2319 DSGVO-Nachbesserung F-4) wie oben.
- contact_ad_connections.tracking_provisioning_level / workspace_ad_connections.tracking_provisioning_level: Neue Konfigurationsspalten auf den bestehenden Verbindungstabellen (Default 'off') — steuern ob/auf welcher Ebene nl_tid geschrieben werden darf. Keine neue Datenkategorie, nur eine Steuerspalte auf bereits dokumentierten Tabellen.
- Erster echter Google-Ads-Schreibzugriff der Plattform (final_url_suffix-Provisionierung via AdService/CampaignService/AdGroupService.update() — siehe eigener Purpose-Text im PROCESSORS-Eintrag 'Google LLC'): Setzt final_url_suffix=nl_tid=<wert> auf Kampagnen-/Anzeigengruppen-/Anzeigen-Ebene. Merge-statt-Überschreiben-Pflicht schützt bestehende Kundenparameter im final_url_suffix. Nur durch expliziten, authentifizierten Admin-Trigger je Verbindung — kein Cron, kein Auto-Rollout.
- Landingpage-Erreichbarkeits-Check (checkLandingPageReachable): Technischer HTTP-Status-Abruf auf kundeneigene Final-URLs vor dem Schreibvorgang — verhindert Provisionierung auf nicht erreichbare Ziel-URLs. Kein Datenfluss über den Status-Code hinaus, SSRF-gehärtet (safeFetch, Blocklist/DNS-Pinning).
Team-Umfragen / Puls-Check & Pflicht-System (Fokus-Queue) — vormals „Monatliche Selbstreflexion & Pflicht-Events“
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: Team-Entwicklung und Mitarbeiter-Wohlbefinden). Der Puls-Check (monatliche Selbstreflexion) dient der Eigenwahrnehmung des Mitarbeiters und der internen Personalentwicklung.
- Selbstbewertungen: Stimmungs-Score (1–5), Arbeitslast-Score (1–5), Highlights-Freitext (max. 2.000 Zeichen), Blockaden-Freitext (max. 2.000 Zeichen), Zeitstempel — verknüpft mit User-ID und Workspace-ID
- Pflicht-Event-Completions: Event-Key, User-ID, Periode (Monat), Zeitstempel der Erledigung
- KI-Priorisierung der Fokus-Queue: offene Aufgaben-Metadaten (Titel, Priorität, Fälligkeit) und Inbox-Alert-Titel werden an Claude Haiku zur Priorisierung gesendet — keine Freitext-Inhalte, nur strukturierte Metadaten
Optimale Posting-Zeiten (Engagement-Metriken & Audience-Analyse)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Bereitstellung der Social-Media-Verwaltung als Plattform-Funktion)
- Post-Engagement-Metriken (social_post_metrics): Aggregierte Statistiken publizierter Social-Media-Posts — Impressionen, Reichweite, Likes, Kommentare, Shares, Saves. Verknüpft mit social_posts (CASCADE bei Löschung). Keine personenbezogenen Daten Dritter — nur aggregierte Plattform-Statistiken. Abruf via Plattform-APIs (Meta Graph API, LinkedIn Analytics, YouTube Data API)
- Audience-Online-Zeiten (social_audience_data): Aggregierte Stunden-Verteilung der Follower-Online-Zeiten pro Wochentag (168 Slots: 7 Tage × 24 Stunden). Verknüpft mit social_accounts (CASCADE bei Löschung). Keine personenbezogenen Daten — nur anonymisierte Aggregatwerte der Plattformen
- Posting-Scores (social_posting_scores): Berechnete Engagement-Wahrscheinlichkeit pro Stunde/Wochentag, abgeleitet aus Post-Metriken und Audience-Daten. Workspace-scoped, verknüpft mit social_accounts. Keine personenbezogenen Daten
- Datenquellen: Alle Metriken werden von den verbundenen Social-Media-Plattformen über deren offizielle APIs abgerufen. Es werden ausschließlich aggregierte Statistiken verarbeitet — keine Profilinformationen einzelner Follower oder Interagierender
Live Debugger Diagnostik — Debug-Events (PROJ-319 + PROJ-397)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: technische Diagnose der Tracking-Konfiguration durch Agentur-Admins)
- Debug-Events (tracking_debug_events): Domain-ID, Debug-Session-ID (SHA256-Hash des Debug-Tokens), Event-Typ, URL der Kunden-Seite beim Event, Event-Payload (JSONB — Domain, Pfad, UTM-Parameter), Diagnostik-Ergebnis (JSONB — Conversion-Evaluierungen und Anchor-Feldstatus). Keine personenbezogenen Daten natürlicher Personen — kein entity_hash, kein pii_hash, kein user_agent, keine IP-Adressen
- PROJ-397: Zusätzlicher Event-Typ `neuland_consent_check` — Diagnose der Consent-Integration auf Kundenwebsites. Payload: `{tracking: bool, recording: bool, tool: cookiebot|usercentrics|klaro|onetrust|manual|none, bypass: bool}`. Rein technische Flags, keine personenbezogenen Daten. Wird nur bei aktivem Debug-Token (sessionStorage `_nos_dbg_active=1`) und 11 Sekunden nach Seitenaufruf einmalig gesendet — kein Overhead im Normalbetrieb
Session Recordings — rrweb-DOM-Aufzeichnungen (PROJ-391)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an qualitativer UX-Analyse zur Optimierung von Formularen, Conversion-Flows und Nutzerführung auf Kundenwebsites). Ergänzt die quantitative First-Party-Tracking-Auswertung (PROJ-288/306) um visuelle Nachvollziehbarkeit. Rechtsgrundlage ist im Auftragsverarbeitungsvertrag mit dem jeweiligen Kunden zu dokumentieren.
- Recording-Sessions (recording_sessions): Pro aufgezeichneter Session werden Metadaten gespeichert — workspace_id, session_id (client-seitig generierter UUID v4 via crypto.randomUUID(), gespeichert in sessionStorage als _nos_rec_sid; pseudonymisiert und nicht mit anderen Session-Identifikatoren verknüpfbar), domain, page_url (Einstiegsseite), started_at / ended_at / duration_ms, chunk_count, Event-Flags (has_form_submit / has_rage_click / has_form_abandon), browser / device_type / os / country_code, is_bot (Filter aus PROJ-306). Optional: entity_hash (aus PROJ-289 Identity-Anchors, bei Kontakt-Löschung auf NULL gesetzt). Keine IP-Adressen, keine User-Agents im Klartext
- Recording-Chunks (recording_chunks): DOM-Zustand der Seite, Mausbewegungen, Klicks und Scroll-Positionen als rrweb-Events, komprimiert (zlib) in JSONB-Chunks à max. 50 KB. Eingabewerte in Formularfeldern werden durch *** maskiert, bevor die Chunks den Browser verlassen (rrweb maskInputOptions für <input>, <textarea>, <select> inkl. password/email/tel). iframe-Inhalte werden vollständig geblockt (keine Cross-Origin-Aufzeichnung). Passwörter werden durchgängig maskiert
- ⚠️ Wichtig — gerenderte DOM-Inhalte (Namen, Kundendaten, Kommentare): Das automatische Masking greift NUR bei Formular-Eingabefeldern, NICHT bei gerenderten Texten in <div>, <span>, <p>, Überschriften oder sonstigen DOM-Elementen. Enthält die Kundenwebsite sensible Inhalte außerhalb von Formularen (z.B. eingeloggter Nutzername, Kundendaten-Tabellen, User-generated Content), müssen diese Elemente vom Websitebetreiber explizit mit der CSS-Klasse `rr-block` oder dem Attribut `data-rrweb-block` versehen werden, damit rrweb sie ausblendet. Die datenschutzrechtliche Verantwortung für sensible DOM-Inhalte liegt beim Websitebetreiber
- Keine automatische Aufzeichnung bei Bot-Traffic: Wenn tracking_sessions.is_bot = true oder die client-seitige Bot-Detection (PROJ-306) positiv ist, wird kein Recording gestartet
- PROJ-397 Admin-Monitoring (Agentur-intern): Derselbe tägliche Cron (tracking-consent-gap-alert) der heatmap-Lücken erkennt, prüft auch recording-Lücken — Workspace-Admins werden per Inbox-Benachrichtigung (tracking_consent_gap) informiert, wenn eine Domain mit recording_enabled=true seit 7+ Tagen keine recording_sessions erfasst hat. Admin-Bypass möglich via tracking_domains.consent_bypass=true (nur für interne Test-Domains, DSGVO-kritisch auf öffentlichen Kundenwebsites mit sichtbarem Warnhinweis). Monitoring betrifft ausschließlich Agentur-Admin-Kommunikation — keine Datenübermittlung an Kunden oder Besucher.
- DSGVO-Datenexport (Art. 15/20): recording_sessions-Metadaten (ohne DOM-Ereignis-Inhalte) werden im Workspace-Datenexport ausgegeben — Zeitraum, Domain, Browser, Device-Typ, Event-Flags, Chunk-Count. recording_chunks-Rohdaten (rrweb-DOM-Events) werden als Gesamtanzahl (Count) exportiert. Rohdaten verfügbar auf berechtigte Anfrage über den Plattform-Admin. Fix DSGVO-1 AUDIT-2026-04-19 (R-295).
Wiedervorlagen-System — persönliche Reminder auf Entitäten (PROJ-400)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsdurchführung der Agenturplattform — Wiedervorlagen sind integraler Bestandteil der Task- und Kontaktverwaltung)
- Wiedervorlagen (follow_ups): Label (Freitext, max. 500 Zeichen — darf personenbezogene Erwähnungen enthalten wie 'Marcel zurückrufen'), Fälligkeitszeitpunkt (Datum + Uhrzeit), Entity-Referenz (polymorph: task / project / contact / company / quote / email / support_ticket / notification / free — 'free' = freistehende Wiedervorlage ohne Entity-Bezug), Ersteller-ID (created_by), zuständige Person (assignee_id — kann vom Ersteller an andere Workspace-Mitglieder delegiert werden), Status (completed), Zeitstempel (created_at, notified_at, completed_at)
- Sichtbarkeit: Ersteller und Zuständiger haben Vollzugriff (Lesen/Ändern/Löschen). Workspace-Admins und -Manager haben lesenden Zugriff auf alle Wiedervorlagen im Workspace (Audit-Zweck). Andere Workspace-Mitglieder sehen keine fremden Wiedervorlagen
- Zuweisungs-Benachrichtigungen: Bei Zuweisung an eine andere Person wird eine Inbox-Benachrichtigung vom Typ 'follow_up_assigned' erstellt (Name des Erstellers, Label der Wiedervorlage, Fälligkeit)
- Fälligkeits- und Vorab-Benachrichtigungen (PROJ-1658, Timing seit PROJ-1831 nutzerindividuell): Ein Cron-Job ('follow-up-reminders') läuft alle 15 Minuten und erstellt für den Zuständigen eine Inbox-Benachrichtigung vom Typ 'reminder_due_today', sobald die Wiedervorlage heute fällig ist, bzw. vom Typ 'reminder_advance_notice', sobald der vom Nutzer gewählte Vorlauf (1-30 Tage) erreicht ist. Beide Benachrichtigungsarten werden — sofern vom Nutzer aktiviert (profiles.reminder_notify_on_due_date / reminder_advance_notice_enabled, beide standardmäßig vorbelegt) — erst ab der vom Nutzer selbst im Inbox-Setup gewählten Uhrzeit (profiles.reminder_notify_time, Europe/Berlin) versendet, nicht mehr zu einem für alle Nutzer identischen Zeitpunkt. Optional zusätzlich macOS-Desktop-Push-Benachrichtigung via Apple Push Notification Service (APNs) — nur wenn der Nutzer die Companion-App (PROJ-168) mit aktivem Push-Opt-in (PROJ-257) installiert hat
- Snooze-Funktion für Inbox-Benachrichtigungen: Beliebige Inbox-Benachrichtigungen können per Klick bis zu einem gewählten Datum ausgeblendet werden. Technisch wird dabei eine Wiedervorlage mit entity_type='notification' angelegt, die bei Fälligkeit eine neue Reminder-Benachrichtigung auslöst. Die ursprüngliche Benachrichtigung wird aus der Liste gefiltert — keine Kopie, kein Datenzuwachs
- Keine Übermittlung an Dritte (außer bei aktivem macOS-Push an Apple APNs, in dem Fall wird ausschließlich ein Kurztitel an das Gerät übermittelt, keine Label-Inhalte im Klartext)
Mitglied-Impersonation — Audit-Log für Platform-Admin-Simulationen (PROJ-407)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Plattform-Sicherheit, Support- und Debugging-Fähigkeit für rollen- und berechtigungsbasierte Funktionen). Verarbeitung erfolgt ausschließlich durch Plattform-Administratoren. Berechtigtes Interesse überwiegt, da (a) die Verarbeitung minimal ist (nur Referenz-IDs und Zeitstempel, keine Inhalte), (b) ausschließlich Lesezugriff erfolgt — schreibende API-Aktionen sind im Simulationsmodus serverseitig blockiert, (c) die Sessions auf 30 Minuten begrenzt sind und (d) jede Simulation lückenlos im Audit-Log protokolliert wird
- Impersonation-Sessions (admin_impersonations): Plattform-Administrator (admin_user_id), simuliertes Mitglied (target_user_id), simulierter Workspace (target_workspace_id), Startzeitpunkt (started_at), Endzeitpunkt (ended_at), Endgrund (end_reason: 'manual' = Admin hat aktiv beendet, 'timeout' = 30-Minuten-Cookie abgelaufen, 'session_end' = Admin hat ausgeloggt). Die Tabelle enthält ausschließlich Referenz-IDs und Zeitstempel — keine Inhalte, keine Klartext-Daten und keine personenbezogenen Daten der simulierten Person über die Identifikator-ID hinaus
- Impersonation-Cookies (Browser, 30 Min TTL, HMAC-signiert): nos_impersonation (httpOnly, Server-State mit admin/target/workspace-Referenzen + Ablaufzeitpunkt), nos_impersonation_info (client-lesbar, Banner-Daten: Anzeigename, Rolle, Workspace-Slug). Beide Cookies werden serverseitig erstellt und sind nicht client-manipulierbar. Sie werden beim Beenden der Simulation oder nach Ablauf automatisch gelöscht
- Sicherheits-Garantien: (1) Nur Plattform-Administratoren können die Simulation starten — ein serverseitiger isPlatformAdmin-Check blockiert alle anderen Anfragen. (2) Plattform-Administratoren können sich nicht gegenseitig simulieren — das Backend lehnt das Starten einer Simulation ab, wenn das Ziel ebenfalls Plattform-Administrator ist. (3) Das simulierte Mitglied wird NICHT benachrichtigt — die Simulation ist für Tests und Debugging gedacht, nicht für Kommunikation. (4) Im Simulationsmodus sind alle schreibenden API-Aktionen (POST/PATCH/PUT/DELETE) durch die Hono-Router-Middleware blockiert — der simulierende Admin kann ausschließlich lesend zugreifen. (5) Die Simulation ist auf den Browser-Tab beschränkt und endet automatisch nach 30 Minuten
- Sichtbarkeit des Audit-Logs: Ausschließlich für Plattform-Administratoren (direkte Einsicht über /admin/impersonations) sowie für Workspace-Admins über den Workspace-Datenexport (Art. 15 DSGVO) — hier werden alle Simulationen gelistet, bei denen der jeweilige Workspace als Ziel diente (target_workspace_id). Einzelne Mitglieder ohne Admin-Rolle haben keine direkte Einsicht in das Log; sie werden über stattgefundene Simulationen nicht aktiv benachrichtigt
Shop-Kunden-Simulation durch Kundenberater (PROJ-427)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Kundenberatung, Support und Beratungsqualität im Shop-System). Kundenberater mit aktivem Shop-CRM-Zugang können die Shop-Frontend-Ansicht eines Kunden temporär simulieren, um bei Telefonberatungen gezielt durch die Oberfläche zu führen und Support-Anfragen nachzustellen. Das berechtigte Interesse überwiegt, da (a) ausschließlich die visuelle Kundensicht simuliert wird — keine Kommunikation im Namen des Kunden, (b) die Simulation strikt read-only ist (alle Schreibzugriffe sind serverseitig blockiert), (c) jede Simulation lückenlos auditiert wird (Admin-Identität, Zielkunde, Zeitstempel), (d) die Session auf 30 Minuten begrenzt ist und (e) der Kunde per Datenschutzerklärung über die Möglichkeit informiert wird.
- Cross-Repo Token-Tabelle (shop_simulation_tokens in Shop-Supabase): Einmaliger Nonce (UUID), Admin-User-ID, Admin-Workspace-ID, Ziel-Kunden-ID, Ablaufzeitpunkt (2 Min TTL), Einlösezeitpunkt (redeemed_at). Der Token wird nach einmaliger Einlösung als verbraucht markiert und kann nicht wiederverwendet werden (Replay-Schutz).
- Audit-Log (shop_customer_simulations in Shop-Supabase): Admin-User-ID, Admin-Workspace-ID, Ziel-Kunden-ID, Startzeitpunkt (started_at), Endzeitpunkt (ended_at), Endgrund (end_reason: 'manual' = Kundenberater hat aktiv beendet, 'timeout' = 30-Minuten-Cookie abgelaufen, 'session_end' = Browser-Tab geschlossen, 'target_deleted' = Kunde wurde während der Simulation gelöscht), Rücksprungs-URL zum NEULAND.-OS-Kundendatensatz (admin_return_url). Keine Inhalte, keine Klartext-Daten des Kunden — nur Referenz-IDs und Zeitstempel.
- Simulations-Cookies (Shop-Domain, 30 Min TTL): shop_simulation (httpOnly, base64-JSON mit simulation_id, customer_id, admin_user_id, expires_at) und shop_simulation_info (client-lesbar, base64-JSON mit Kundenname und E-Mail für Banner-Anzeige). Der Sicherheits-Schutz liegt im HMAC-signierten Token beim Einlösen; die Session-Cookies selbst werden ausschließlich serverseitig erstellt und lassen sich nicht manipulieren, da die Middleware alle schreibenden API-Aufrufe bei Cookie-Präsenz mit HTTP 403 blockiert.
- Technisches Verfahren: Kundenberater startet die Simulation in NEULAND. OS, der Server generiert einen HMAC-SHA256-signierten Token mit dem gemeinsamen SHOP_IMPERSONATION_SECRET und leitet in einem neuen Browser-Tab auf /admin-simulation/einloesen im Shop-System weiter. Der Shop validiert den Token, generiert einen kurzlebigen Recovery-OTP für die Kunden-Supabase-Session (so dass alle Shop-Seiten die echte Kunden-Ansicht liefern) und setzt die Simulations-Cookies. Das amber-farbene Simulations-Banner ist auf allen Shop-Seiten sticky sichtbar.
- Sicherheits-Garantien: (1) Nur Workspace-Mitglieder mit aktivem Shop-CRM-Zugang können die Simulation starten — ein serverseitiger Membership-Check über withShopClient blockiert alle anderen Anfragen. (2) Pro Admin-User gilt ein Rate-Limit von 20 Simulationen pro Minute. (3) Die Shop-Middleware blockiert im Simulationsmodus alle schreibenden Aktionen (POST/PATCH/PUT/DELETE) mit HTTP 403 und einer klaren Fehlermeldung. (4) Kunden ohne verknüpftes Shop-Konto (auth_user_id IS NULL) können nicht simuliert werden. (5) Der Kunde wird NICHT benachrichtigt — die Simulation ist ein reines Support-Werkzeug.
- Sichtbarkeit des Audit-Logs: Workspace-Admins und -Manager können alle Simulationen ihres Workspaces über /apps/shop-system/einstellungen/simulation-log einsehen. Shop-Kunden können die Simulationen ihres Kontos nach Fertigstellung des Shop-Kunden-Datenexports (PROJ-384) über ihren /konto-Bereich als JSON exportieren (Art. 15 DSGVO).
- Keine Übermittlung an Dritte: Der Token reist ausschließlich zwischen der NEULAND.-OS-Instanz und dem zugehörigen Shop-Frontend, beide unter Kontrolle des Agentur-Betreibers. Keine externen Dienste. Keine neuen Auftragsverarbeiter.
Component Lab — KI-gestützte CMS-Komponenten-Generierung (PROJ-409)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: effiziente Komponenten-Erstellung für Kundenprojekte). Component Lab ist eine interne Arbeitsumgebung ausschließlich für Agency-Admins und Agency-Manager — Kunden haben keinen Zugriff. Briefings (Prompts) und generierter TSX-Code werden kontaktbezogen versioniert in lab_components und lab_component_versions gespeichert und an Anthropic (Claude Sonnet) zur Generierung übermittelt.
- Admin-User-ID (created_by): Pseudonyme UUID des erstellenden Workspace-Mitglieds. Bei Account-Löschung über ON DELETE SET NULL auf NULL gesetzt — Komponente bleibt als Workspace-Eigentum erhalten
- Kontakt-Referenz (contact_id): Verweis auf das Kundenunternehmen (keine natürliche Person) zur Zuordnung und zum Laden der Design DNA. Bei Kontakt-Löschung auf NULL gesetzt (SET NULL)
- Komponenten-Metadaten (lab_components): Name (Freitext), Beschreibung (Freitext, optional), component_type (Interactive Tool, Form-Extension, Navigation-Element, Content-Block, Calculator, Lead-Form), status (draft/published/archived), created_at, updated_at — keine personenbezogenen Daten erwartet
- Prompts (lab_component_versions.prompt + follow_up_prompt): Admin-Freitext der Komponenten-Briefings. Kann indirekt personenbezogene Daten enthalten, wenn der Admin Kunden-Namen, Kontaktpersonen oder Persona-Beschreibungen im Prompt erwähnt. Prompts werden vom eingeloggten Admin selbst verfasst — keine Anonymisierung vor Übermittlung an Anthropic, da es sich um interne Arbeitsanweisungen handelt
- KI-generierter TSX-Code (lab_component_versions.tsx_code): Maschinell erzeugter React-Komponenten-Code — keine personenbezogenen Daten
- Design-DNA-Snapshot (lab_component_versions.dna_snapshot): JSONB mit CI-Farben, Schriften, Border-Radii, Logos zum Zeitpunkt der Generierung — Firmen-Branding-Daten des referenzierten Kontakts, keine PBD
- Generierungsmetadaten (lab_component_versions.generation_meta): JSONB mit Modell-Name, Token-Zählern, Generierungsdauer — technische Metadaten für KI-Kostenverfolgung und Optimierung, keine PBD
- Empfänger: Anthropic PBC (USA, KI-Generierung via Claude Sonnet — Auftragsverarbeiter gemäß Art. 28 DSGVO), unpkg/Cloudflare (USA, CDN für React-UMD-Bundles im iFrame-Sandbox), jsDelivr/Prospect One (EU, CDN für @babel/standalone und axe-core im iFrame-Sandbox), Supabase (EU, Frankfurt — Speicherung der Komponenten und Versionen), Vercel (EU-bevorzugt, API-Hosting). Keine Übermittlung an Dritte über diese Auftragsverarbeiter hinaus
- iFrame-Sandbox-Isolation: Die Live-Preview läuft in einem sandbox="allow-scripts"-iFrame ohne allow-same-origin — kein Zugriff auf NEULAND.-OS-Cookies oder Session-Daten aus dem generierten Code. CSS-Custom-Properties werden über Regex-Whitelist injiziert (BUG-2-Fix), postMessage ist mit Source-Check abgesichert (BUG-1-Fix)
- EU AI Act (ab 02.08.2026): Risikoklasse begrenztes Risiko (Content-Generation für Admin-Nutzung). Der System-Prompt erzwingt einen Kommentar '// Generiert von Claude am [Datum]' am Ende jeder generierten Komponente. Das Modell Claude Sonnet ist im feature-catalog.ts als 'component_lab_generation' registriert. Keine automatisierten Entscheidungen über Personen
Component Lab — PIN-geschützte Präsentationslinks (PROJ-505)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Agentur stellt Kunden-Abnahme-Oberfläche für KI-generierte UI-Komponenten bereit)
- Share-Link-Metadaten in component_lab_share_links: workspace_id, component_id (FK → lab_components mit CASCADE DELETE), Titel (max. 200 Zeichen), kryptischer UUID-Token (URL-Pfad), optionaler PIN-Hash (PBKDF2-SHA256, 100.000 Iterationen, mit Salt), Ablaufdatum (90 Tage ab Erstellung), is_active-Flag, anonymer view_count-Zähler, created_by (FK → auth.users mit SET NULL), Erstellungs- und Änderungszeitstempel. Enthält Personenbezug via component_id (verknüpft zu einem Kundenprojekt) und created_by (Agentur-Mitglied als Ersteller)
- Beim öffentlichen Aufruf des Präsentationslinks: Kein PII auf der Vorschau selbst — rendert ausschließlich KI-generierten TSX-Code mit CI-DNA-Tokens. Header zeigt Kundenname und Logo (aus contacts-Tabelle via lab_components.contact_id) wenn vorhanden
- Aufruf-Zähler view_count wird atomar pro Public-GET erhöht (anonymer Counter, keine IP/Session-Tracking)
- PIN-Brute-Force-Schutz: 5 Fehlversuche pro 5 Minuten (Redis Rate-Limiter, IP-basiert) — keine Speicherung von Fehlversuchen oder IP-Adressen
- DSGVO-Datenexport (Art. 15/20): component_lab_share_links wird im Workspace-Datenexport ergänzt (ausstehend, folgt via DSGVO-Audit) — pin_hash und pin_salt werden als 'set'/'unset'-Flag dargestellt
Visual Style Inventory — Öffentliche Design-System-Share-Links (PROJ-406)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Agentur stellt Design-System-Abnahme-Oberfläche für Kunden bereit)
- Share-Link-Metadaten in style_inventory_links: workspace_id, contact_id (nullable, FK → contacts mit CASCADE DELETE), Titel (max. 200 Zeichen), kryptischer UUID-Token (URL-Pfad), optionaler PIN-Hash (PBKDF2, mit Salt), Ablaufdatum (90 Tage ab Erstellung, konfigurierbar), is_active-Flag, anonymer view_count-Zähler, created_by (FK → auth.users mit SET NULL), Erstellungs- und Änderungszeitstempel. Enthält Personenbezug via contact_id (verknüpft zu einem Kundenkontakt) und created_by (Agentur-Mitglied als Ersteller)
- Beim öffentlichen Aufruf des Share-Links: Kein PII auf der Canvas selbst — Inventory rendert ausschließlich Design-Tokens (Farben, Fonts, Spacing, Komponenten). Am Header werden Kundenname und Logo (aus contacts-Tabelle) angezeigt
- Aufruf-Zähler view_count wird atomar pro Public-GET erhöht (anonymer Counter, keine IP/Session-Tracking)
- DSGVO-Datenexport (Art. 15/20): style_inventory_links wird im Workspace-Datenexport (GET /api/workspaces/data-export) als JSON enthalten — pin_hash und pin_salt werden aus Sicherheitsgründen nicht exportiert, sondern als 'set'/'unset'-Flag dargestellt
SEO Intelligence Platform — Google Search Console & Bing Webmaster Import
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an Analyse und Optimierung der organischen Suchleistung ihrer Kunden-Domains). Verarbeitung ausschließlich aggregierter Such-Metriken — keine Endnutzer-PII.
- Google Search Console Keyword-Daten (seo_keyword_daily): Keyword-Text, Einstiegsseiten-URL, aggregierte Klicks, Impressionen, durchschnittliche Position, Datum — importiert für die mit dem Workspace verknüpften Kunden-Domains. Keine Endnutzer-Identifikatoren (keine IP, keine Session-ID, keine User-ID aus der GSC-Response). Herkunft: Google Search Console API v1 (Read-only-Scope)
- Bing Webmaster Keyword-Daten (seo_keyword_daily): identische Metriken wie GSC, Quelle Bing Webmaster Tools API. Keine Endnutzer-PII
- Brand-Filter-Regeln (seo_brand_rules): Workspace-spezifische Brand-Keyword-Muster (Textstrings / Regex) und deren Review-Status. Kein Personenbezug
- Domain-Verbindungskonfiguration (seo_connections, seo_domain_mappings): OAuth-Refresh-Token (AES-256-GCM verschlüsselt), GSC-Property-URLs, Kontaktzuordnung, Haupt-/Zusatzaccount-Markierung (is_primary). Seit PROJ-469 werden pro GSC-Account zusätzlich gespeichert: google_account_id (Google User-ID, intern für Duplikat-Schutz), display_name (öffentlicher Google-Profilname, dient der Anzeige im Integrationen-Tab — personenbezogenes Datum des Workspace-Admins der den Account verbunden hat), avatar_url (Google-Profilbild-URL, öffentlich erreichbar — URL verweist auf Google-Infrastruktur, kein Download/Speicherung des Bildmaterials in der eigenen DB). Rechtsgrundlage für display_name + avatar_url: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Identifikation und Unterscheidbarkeit mehrerer verbundener Accounts im Verwaltungs-UI). Löschung: bei Trennung des Accounts via Integrationen-Tab sofortige Löschung aller Verbindungsdaten inkl. display_name und avatar_url
- Neuland Search Index (neuland_search_index): Agentur-weit aggregierte CTR-Kurve (Median, P25, P75) pro Suchmaschine und Position 1–10 — vollständig anonymisiert, kein Workspace-Bezug im exportierten Index
- Insight-Snooze-Einträge (seo_insight_dismissals): Welcher Workspace-Mitarbeiter welchen Alert-Typ bis zu welchem Zeitpunkt dismisst hat — enthält member_id (Fremdschlüssel auf auth.users) und domain_mapping_id. Retention: 30 Tage
- Darstellung in Kundenreports (PROJ-1825 seit 2026-07-29): Die oben genannten aggregierten Such-Metriken koennen seit PROJ-1825 zusaetzlich als Widgets in Kunden-Reports dargestellt werden (Quelle SEO und GEO im Widget-Katalog). Es werden dabei keine neuen Daten erhoben und keine neuen Datenkategorien verarbeitet — es aendert sich ausschliesslich die Darstellungsform. Jeder Kunde sieht ausschliesslich die Metriken der eigenen, ihm zugeordneten Domain; die Zuordnung wird serverseitig bei jedem Abruf geprueft
- Zeitplan & Lauf-Historie (automation_schedules / automation_schedule_runs, PROJ-1919): je Workspace ein einstellbarer Zeitplan für den GSC- und den Bing-Import (aus/stündlich/täglich/wöchentlich, Uhrzeit im Halbstunden-Raster, Europe/Berlin) inkl. updated_by (auth.users-Referenz des zuletzt ändernden Mitglieds, SET NULL bei Nutzerlöschung); je geplantem Lauf eine Protokollzeile mit Status, Erfolgs-/Fehlerzählern, Dauer und ggf. technischer Fehlermeldung — keine Endnutzer-PII. Lauf-Historie wird nach 90 Tagen automatisch gelöscht; beide Tabellen sind workspace-scoped (CASCADE) und im DSGVO-Datenexport (Art. 15/20) enthalten.
- Webmaster-Benachrichtigungen (seo_webmaster_alerts, PROJ-2010): Search-Console-/Bing-Webmaster-Meldungen zu Kunden-Domains (Indexierungsprobleme, Crawl-Fehler, Sicherheitswarnungen, manuelle Maßnahmen, allgemeine Updates), erfasst über eine neue E-Mail-Regel-Aktion (Quelle: Marketing-Postfach marketing@neuland-agentur.com) sowie über die Bing-`GetCrawlIssues`- und GSC-`URL-Inspection`-APIs. Gespeichert: Quelle (google/bing), Property-URL, Erfassungsweg (email/api), Alert-Kategorie, Titel, Beschreibung, betroffene URL, Schweregrad, Link zum Original-Bericht, Roh-Payload (JSONB — Roh-Mail-Auszug bzw. API-Antwort), Status (new/acknowledged/resolved), Erst-/Letzt-Sichtungszeitpunkt. Kontaktzuordnung (contact_id) über `seo_domain_mappings.property_url`, nullable bei nicht zuordenbarer Domain (AC-C2, kein Personenbezug einer natürlichen Person — Domain-Zuordnung zu einem Unternehmenskontakt). Kein Endnutzer-PII — die einzige personenbezogene Spur ist die interne Empfängeradresse des Marketing-Postfachs, ggf. im Roh-Payload enthalten. Erzeugt bei Neu-Erfassung eine getippte Benachrichtigung (`seo_webmaster_alert`, digest-fähig über user_notification_preferences.digest_mode) an die aktiven Admins des Workspace. Sichtbar ausschließlich für interne Rollen admin/manager (RLS-Policy, kein Kunden-Portal-Zugriff). **Retention des raw_payload noch nicht durch einen automatischen Cleanup-Cron begrenzt (offen für /dsgvo-Review)** — Alert-Kernfelder unterliegen bislang keiner Aufbewahrungsfrist.
Contao Webhook-Formular-Integration
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Bearbeitung von Kundenanfragen und Bewerbungen) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an der Optimierung des Anfrage-Managements). Die Formulardaten werden im Auftrag der Agentur-Kunden verarbeitet, deren Websites die Formulare bereitstellen (Auftragsverarbeitung gemäß Art. 28 DSGVO).
- Webhook-Request-Log (webhook_requests): Eingehende Formular-Payloads von Contao-CMS-Websites, gespeichert als JSONB-Snapshot. Inhalt: alle vom Formular übermittelten Felder (typischerweise Name, E-Mail-Adresse, Telefon, Nachrichtentext, Datei-URLs). Zusätzlich: Status (Erfolg/Fehler), customer_identifier, form_type, IP-Adresse des Senders, Timestamp. Die Felder variieren je nach Formular-Konfiguration auf der Kunden-Website. Retention: 90 Tage, dann automatische Löschung durch täglichen Cleanup-Cron (proj424_webhook_requests_cleanup, 03:00 UTC)
- Routing-Konfiguration (webhook_routing_configs): Workspace-spezifisches Webhook-Secret (SHA-256-Hash — kein Klartext gespeichert), Standard-Pipeline-Typ, sowie seit PROJ-462 eine optionale agentur_pipeline_contact_id (UUID-Referenz auf einen bestehenden CRM-Kontakt im Agentur-Workspace — markiert den Kontakt, der in der Webhook-Routing-UI als Agentur-Pipeline-Shortcut erscheint; typischerweise der agentur-eigene Unternehmens-Kontakt für Leads von der eigenen Website). Die Spalte hat ON DELETE SET NULL: Wenn der referenzierte Kontakt aus dem CRM gelöscht wird, wird die Konfiguration automatisch geleert und der Shortcut in der UI als nicht konfiguriert angezeigt. Kein eigenständiger Personenbezug — die referenzierten Kontaktdaten werden ausschließlich in der contacts-Tabelle gespeichert und unterliegen deren DSGVO-Regime
- Routing-Regeln (webhook_contact_mappings, aktualisiert 2026-04-23 durch PROJ-465): Mapping-Regeln (customer_identifier → target_workspace_id) mit sort_order-Priorität. Das Routing-Ziel ist jetzt ein Workspace (Agentur-Workspace selbst oder ein aktiv verbundener Kunden-Workspace via workspace_connections), nicht mehr ein einzelner CRM-Kontakt. Die Spalte contact_id ist seit PROJ-465 nullable und wird bei neuen Regeln nicht mehr beschrieben — bestehende Werte wurden einmalig im Rahmen der Schema-Migration auf target_workspace_id umgesetzt (contact_id eines aktiven Kunden-Kontakts → client_workspace_id aus workspace_connections; sonst → Agentur-Workspace). Enthält ausschließlich Workspace-Fremdschlüssel und Text-Identifier, keine eigenständigen personenbezogenen Daten. Die alte Tabelle webhook_workspace_mappings (customer_identifier → Ziel-Workspace) bleibt deprecated ohne aktive Nutzung erhalten
- CRM-Integration: Bei erfolgreicher Verarbeitung werden Formulardaten als eigener Lead-Eintrag in der Tabelle leads (seit PROJ-450, siehe folgender Punkt) sowie als notes-Append am gemappten CRM-Kontakt im Agentur-Workspace geschrieben. contacts.lead_source wird auf 'webhook_contao' gesetzt. Diese Daten unterliegen den regulären CRM-Lösch- und Exportrechten (Art. 17, Art. 20 DSGVO)
- Lead-Pipeline (leads, PROJ-450 seit 2026-04-22, erweitert durch PROJ-465 am 2026-04-23): Jede einzelne Formular-Einreichung erzeugt einen eigenen Lead-Eintrag (1:N zu contacts) mit vollständigen Feldern — form_data (JSONB mit allen Formular-Key-Value-Paaren, typischerweise Name, E-Mail, Telefon, Nachricht), form_type, session_id (Korrelation zur Website-Tracking-Session aus PROJ-428, siehe dortiger Eintrag), source='webhook_contao', received_at, Pipeline-stage_id, status ('accepted' = verknüpfter CRM-Lead, 'staged' = wartet auf Validierung — siehe PROJ-452-Ergänzung unten). Seit PROJ-465 zusätzlich target_workspace_id: nullable Referenz auf den Ziel-Workspace der aus der Routing-Regel ermittelt wurde (Agentur-Workspace oder aktiv verbundener Kunden-Workspace) — dient als Cross-Reference für Website-Tracking-Attribution im Ziel-Workspace. Der Lead selbst lebt weiterhin physisch im Agentur-Workspace (workspace_id=Agentur), damit der Staging-Validierungs-Flow aus PROJ-452 intakt bleibt. Ersetzt seit PROJ-450 das überschreibende Verhalten von contacts.webhook_form_data — die volle Historie aller Anfragen bleibt erhalten (keine last-wins-Überschreibung mehr). Löschung via ON DELETE CASCADE bei Kontakt- oder Workspace-Löschung, zusätzlich manuelle Einzel-Löschung durch Admins/Manager. target_workspace_id wird bei Ziel-Workspace-Löschung via ON DELETE SET NULL geleert. Die Legacy-Felder contacts.webhook_form_data / webhook_form_type / webhook_received_at werden seit PROJ-450 nicht mehr beschrieben und sind als deprecated markiert; vorhandene Werte wurden einmalig nach leads migriert
- Lead-Validierung & Staging (leads.status='staged', PROJ-452 seit 2026-04-22): Eingehende Website-Leads ohne passendes webhook_contact_mapping werden NICHT mehr als automatischer CRM-Kontakt angelegt, sondern als Staged Lead in der leads-Tabelle mit contact_id=NULL und status='staged' gespeichert. Datenminimierung: Kein neuer CRM-Kontakt bis zur manuellen Validierung. Agentur-Admins sehen Staged Leads im Eingangsbereich der Lead-Pipeline (/crm/pipeline) und entscheiden pro Lead über 'Im CRM anlegen' (atomare Kontakt-Erstellung aus form_data via /api/leads/:id/accept) oder 'Verwerfen' (unwiderruflicher DELETE via /api/leads/:id, Art. 17 DSGVO). Zusätzlich: automatischer Cleanup nach 30 Tagen (staged-leads-cleanup Cron, tägl. 03:00 UTC) — unvalidierte Leads werden datenschutzfreundlich ohne weitere Aktion gelöscht. Der Cleanup gilt NUR für status='staged', nicht für bereits als CRM-Kontakt übernommene Leads. Art. 25 Privacy by Design: Opt-in-Mechanismus für CRM-Anlage statt automatischer Datenübernahme
- Staging-Notification (lead_staged): Beim Eingang eines Staged Leads wird eine Inbox-Notification an alle aktiven Admins/Manager des Agentur-Workspaces erzeugt. Inhalt: Formular-Typ, erkannte E-Mail-Adresse (falls im Formular enthalten), lead_id, customer_identifier. Die E-Mail-Adresse erscheint sowohl im message-Text als auch in der metadata-JSONB — diese Daten sind ausschließlich für Agentur-Workspace-Admins/Manager sichtbar (gleicher Zugriffskreis wie der Lead selbst, kein erweiterter Personenkreis). Löschung gemeinsam mit dem Lead bzw. via Workspace-Notification-Cleanup
- Session-ID-Korrelation (PROJ-450, leads.session_id): Persistierung der optional übermittelten neuland_session_id aus dem snippet.js-Hidden-Field (PROJ-428). Ermöglicht die Rückverfolgung der Website-Session zum Formular-Lead (Verlinkung zum Session-Recording aus PROJ-391). Die Session-ID ist ein opaker Hash ohne direkten Personenbezug, siehe separate Datenschutz-Beschreibung unter PROJ-288/PROJ-428. Nicht mutierbar nach INSERT
- Zuordnung über customer_identifier (Bugfix 21.04.2026, aktualisiert 2026-04-23 durch PROJ-465): Die Routing-Entscheidung erfolgt über einen exakten String-Match des customer_identifier (z.B. 'www.kunden-website.de' oder ein Kundenname) gegen die Admin-konfigurierten webhook_contact_mappings. Ergebnis des Lookups ist seit PROJ-465 ein target_workspace_id (Agentur-Workspace oder verbundener Kunden-Workspace), nicht mehr ein einzelner CRM-Kontakt. Bei unbekanntem Identifier wird der Lead als staged im Agentur-Workspace abgelegt (siehe PROJ-452). Ohne passende Regel wird keine automatische Kontakt-Anlage gemacht. Zeigt target_workspace_id auf einen gelöschten oder nicht mehr aktiv verbundenen Workspace, wird dies durch die Handler-Logik erkannt und der Lead ebenfalls als staged abgelegt — ohne Attribution, für manuelle Validierung durch Admins
- Routing-Modi & Tracking-Only-Counter (PROJ-527 seit 2026-05-02): Pro Routing-Regel kann ein routing_mode definiert werden ('lead_pipeline' = Insert in leads-Tabelle, 'recruiting_pipeline' = Insert in leads mit form_type-Filter, 'tracking_only' = schlanker Counter ohne Form-Payload). Workspace-Default in webhook_routing_configs.default_routing_mode. Tracking-Only-Regeln erfordern einen Pflicht-Default-Kontakt (default_contact_id, FK auf contacts.id im Agentur-Workspace) — wird als Lead-Zuordnung verwendet wenn der Webhook-Email keinen Kontakt-Match liefert. business_impact_lead_counts (PROJ-527) speichert pro Tracking-Only-Webhook-Eingang einen schlanken Counter-Eintrag mit workspace_id, contact_id (FK auf contacts.id, ON DELETE CASCADE), source ('webhook_contao'), received_at und webhook_request_id (FK auf webhook_requests, ON DELETE SET NULL). KEIN Form-Payload (kein form_data-JSONB, kein E-Mail-Klartext) — DSGVO-Vorteil: nur der Inkrement zählt, keine personenbezogenen Klartext-Inhalte werden zusätzlich gespeichert (Art. 25 Privacy by Design). Aggregations-Quelle für /api/tracking/goal-gaps (Soll-Ist-Vergleich pro Kontakt + Zeitraum im Business-Impact-Tab). Retention 730 Tage (passend zu typischer Marketing-Reporting-Periode), automatische Löschung via täglichem Cleanup-Cron (business-impact-counts-cleanup). Workspace-CASCADE bei Workspace-Löschung; Kontakt-CASCADE bei Self-Service-Kontaktlöschung (Art. 17 DSGVO)
- Routing-Lücken-Notification (PROJ-527, webhook_no_routing_rule): Wenn ein Webhook eintrifft für den weder eine webhook_contact_mappings-Regel matched noch ein agentur_pipeline_contact_id-Default konfiguriert ist, wird (a) ein webhook_requests-Eintrag mit status='no_routing_rule' geloggt und (b) eine Inbox-Notification an alle aktiven Admins/Manager des Agentur-Workspaces erzeugt (Typ webhook_no_routing_rule, priority 'high'). Notification-Inhalt: customer_identifier, source-IP, form_type, received_at, webhook_request_id. Hinweis zur source-IP: Dies ist die IP-Adresse des aufrufenden CMS-Servers (z.B. Contao-Webserver), da der Webhook-POST vom CMS-Backend ausgeführt wird — NICHT die IP-Adresse des Website-Besuchers. De-Duplication: innerhalb 24h für identische (ip_address + customer_identifier)-Kombination wird nur EINE Notification ausgelöst (Spam-Schutz bei Webhook-Storms). Die IP verbleibt in notifications.metadata bis zur manuellen Löschung der Notification oder Workspace-Löschung. KEIN Lead-/Counter-Eintrag wird erzeugt — der Webhook wird mit HTTP 200 quittiert (externe Form-Provider sollen nicht retryen). Zugriffskreis identisch zu lead_staged: nur Agentur-Admins/Manager. Audit-Log bei routing_mode-Wechsel an bestehender Regel in system_logs (level='info', category='api')
- Multi-Mode-Routing & erweiterte Matcher (PROJ-615 seit 2026-05-11): webhook_contact_mappings erhält die Spalten routing_modes (text[]: Subset von {lead_pipeline, recruiting_pipeline, tracking_only}, mindestens 1, max 3 — ersetzt schrittweise routing_mode), pipeline_target_workspace_id und tracking_target_workspace_id (FK auf workspaces, ON DELETE SET NULL — getrennte Routing-Ziele pro Modus statt eines gemeinsamen target_workspace_id), tracking_default_contact_id (FK auf contacts, ON DELETE SET NULL — separater Default-Kontakt für tracking_only-Modus), identifier_match und form_type_match (JSONB mit {operator: equals/not_equals/in/not_in/contains/not_contains/regex/any, value?: string|string[]}). Erweiterte Matcher erlauben Mehrfachwerte (in/not_in), Substring (contains/not_contains) und regex (max. 500 Zeichen Pattern, ReDoS-Schutz). Legacy-Spalten (customer_identifier, form_type_pattern, routing_mode, target_workspace_id, default_contact_id) bleiben für Backwards-Compatibility erhalten und werden weiterhin gepflegt. Bei Multi-Mode (routing_modes enthält mehrere Werte) wird pro eingehendem Webhook für JEDEN aktivierten Modus die entsprechende Verarbeitung ausgeführt (z.B. 1× business_impact_lead_counts-Insert + 1× leads-Insert). Reine Routing-Konfiguration des Agentur-Workspace — keine PII (customer_identifier ist eine Domain wie 'www.kunde.de', identifier_match.value enthält Domain-/Form-Type-Pattern). Workspace-scoped RLS (Admin/Manager).
- Per-User Sidebar-Pin-Status (PROJ-714 seit 2026-05-19): user_webhook_routing_preferences speichert pro (user_id, workspace_id) ein Array pinned_contact_ids: uuid[] mit den vom User angepinnten Kontakten in der Webhook-Routing-Master-Detail-Sidebar. Reine UI-Personalisierung — keine PII über die contact_id-Foreign-Keys hinaus. Workspace-CASCADE bei Workspace-Löschung; User-CASCADE bei Account-Löschung. Bei Kontakt-Löschung (contacts.contact_id) verbleibt die UUID im Array bis zum nächsten User-Klick (Cleanup im UI-Read-Pfad). RLS: User darf nur eigene Zeile lesen/ändern + Workspace-Membership-Pflicht. DSGVO-Datenexport (Art. 15/20): user_webhook_routing_preferences ist als eigene Sektion im Workspace-Datenexport enthalten (workspace-scoped, alle Pin-Einträge des Workspaces inklusive user_id und pinned_contact_ids). Zusätzlich PROJ-714: FK webhook_contact_mappings.contact_id wurde von ON DELETE CASCADE auf ON DELETE SET NULL umgestellt — bei Kontakt-Löschung rutschen die zugehörigen Routing-Regeln in den 'Ohne Kontakt-Zuordnung'-Fallback-Bucket statt mitgelöscht zu werden (sicherer; Admin entscheidet manuell über Neuzuweisung oder Löschung der Regel).
- Erweiterte Feldzuordnungen + Verarbeitungsmodus (PROJ-689 seit 2026-05-18): webhook_contact_mappings.processing_mode (TEXT, CHECK: 'direct'|'requires_validation') steuert pro Routing-Regel den Spam-Schutz-Modus. 'direct' = Webhook legt Deal + CRM-Kontakt sofort an (Pre-PROJ-618-Verhalten); 'requires_validation' = PROJ-618-Workflow mit Deferred-CRM-Creation (Default für neue Regeln). Bestandsregeln stehen auf 'requires_validation'. Zusätzlich wurde die bestehende JSONB-Spalte field_mapping von einem flachen Lookup ({Formularfeld: CRM-Zielfeld}) auf ein strukturiertes Schema umgestellt: {deal: {target: {source_mode, source_value, fallback_value?}}, communication: {enabled, fields?}, task: {enabled, fields?}}. Drei Quellmodi pro Zielfeld: webhook_field_known (Payload-Key aus Dropdown der zuletzt gesehenen Felder), webhook_field_manual (Payload-Key als Freitext-Pfad mit Dot-Notation für nested Payloads, auch wenn nie im Payload vorkam — Allow-List-Regex + Prototype-Pollution-Schutz, Pfad-Tiefe-Limit 10), constant (fester Freitext-Wert wird 1:1 als Zielwert geschrieben). Reine Routing-Konfiguration — kein direkter Personenbezug in der Konfiguration selbst (Konstanten könnten theoretisch PII enthalten wenn ein Admin sie aktiv einträgt; in der Praxis sind das Default-Werte wie 'Webformular-Anfrage'). Backwards-Compat: Legacy-Flat-Map wird beim Lesen on-the-fly in das strukturierte Schema reduziert; alle bestehenden Mappings funktionieren unverändert. Symmetrisch implementiert für matelso_routing_rules (R-482). Automatische Anlage von Kommunikationseinträgen und Tasks aus Webhook-Payloads: Wenn field_mapping.communication.enabled=true ist, wird bei jeder erfolgreichen Deal-Anlage ein sales_communication_log-Eintrag erzeugt (deal_id, contact_id, channel/direction/communicated_at/subject/content aus Resolver, created_by=NULL als System-Action, participants=[], ai_extracted_signals={}). Wenn field_mapping.task.enabled=true ist, wird ein sales_tasks-Eintrag erzeugt (deal_id, assigned_user_id mit Fallback auf ältesten aktiven Workspace-Admin bei DB NOT NULL Constraint, channel/goal/priority/title/notes/due_date aus Resolver, task_origin='automatisch' als System-Marker, priority_source='manual', status='offen', created_by=NULL). Pflichtfeld-Aufbruch: DB-CHECK-Constraints auf channel/direction/goal/priority bleiben unverändert; der Resolver mappt Freitext über eine case-insensitive Mapping-Tabelle (channel-mapping.ts) auf SSOT-Enum-Werte und fällt bei nicht auflösbarem Freitext auf den System-Default zurück (DEFAULT_COMMUNICATION_CHANNEL='platform', DEFAULT_TASK_CHANNEL='recherche', DEFAULT_TASK_GOAL='lead_validieren', DEFAULT_TASK_PRIORITY='mittel'). Kein 23514-Constraint-Violation möglich. Die per Webhook erzeugten Sub-Einträge folgen den bestehenden CASCADE-Regeln aus PROJ-481 (Kommunikation) und PROJ-646 (Tasks): bei Workspace-/Deal-Löschung werden sie automatisch entfernt. Fire-and-forget: Fehler bei Sub-Entity-Inserts kippen NICHT die Deal-Anlage (R-415). Edge-Case Member-Removal: wenn der für task.assigned_user_id konfigurierte Member inzwischen aus dem Workspace entfernt wurde, wird der Task an den ältesten aktiven Workspace-Admin zugewiesen + Eintrag in system_logs (processing_status='task_assignee_fallback'). DSGVO-Relevanz: Keine Erweiterung der Verarbeitungszwecke gegenüber PROJ-462/PROJ-618 — Webhook-Daten landen weiterhin in CRM-Kontakten, Deals, Kommunikation und Tasks; PROJ-689 erweitert nur die Konfigurierbarkeit der Zuordnung. Workspace-scoped RLS (Admin/Manager) auf allen Routing-Regel-Tabellen und den erzeugten Sub-Entities.
- Dynamische Match-Bedingungen + Feld-Katalog + Softfail-Alerts (PROJ-734 seit 2026-05-21): Drei neue Tabellen erweitern das Webhook-Routing um vollständig dynamische Match-Conditions mit Dot-Notation und 9-Operatoren-Pool (equals/not_equals/contains/greater_than/less_than/regex/any/exists/not_exists). (1) webhook_routing_conditions: polymorphe Bedingungs-Tabelle mit rule_type (CHECK: webhook_contact_mapping/matelso_routing_rule) + rule_id, field_path (max 255 Zeichen, Allow-List-Regex), operator, value (max 2000 Zeichen, nullable bei any/exists/not_exists), data_type_hint (string/integer/float/boolean/any), sort_order. UNIQUE (rule_type, rule_id, field_path, operator) verhindert Duplikate. Polymorphe CASCADE via 2 AFTER-DELETE-Trigger (auf webhook_contact_mappings + matelso_routing_rules) — bei Regel-Löschung werden alle zugehörigen Conditions automatisch entfernt. Reine Routing-Konfiguration des Agentur-Workspace ohne Personenbezug (field_path und value sind Konfigurationswerte wie 'routing.customer_identifier' bzw. 'www.kunde.de'). Workspace-scoped RLS (admin+manager) via JOIN auf zugehörige Regel-Tabelle. (2) webhook_field_catalog: Auto-Discovery-Datenbank für die UI-Combobox (Vorschlags-Engine). Pro (workspace_id, source_type, field_path) ein Eintrag mit seen_count, last_seen_at, sample_value (max 100 Zeichen, truncated, oder NULL bei PII), is_pii_redacted (boolean), human_label (Auto-Generator), data_type. Source-Type ∈ contao/matelso/heyflow/manual/generic. Sample-Values sind potenziell PII: bei Pfad-Endung in {email, mail, phone, telefon, mobile, handy, firstname, lastname, vorname, nachname, birthday, geburtsdatum, ssn, iban, passport, perso} ODER bei E-Mail-/Telefon-Wert-Pattern wird sample_value=NULL gesetzt und is_pii_redacted=true. Auto-Discovery läuft fire-and-forget (R-415) nach jedem akzeptierten Webhook — extrahiert max 100 Top-Level-Keys und max 5 Verschachtelungs-Ebenen aus dem Payload. Reject-Cases: Array-Index-Notation, Buffer/ArrayBuffer, Base64-Strings über 1 KB, Keys aus reinen Sonderzeichen. Workspace-scoped RLS SELECT (admin+manager); INSERT/UPDATE/DELETE ausschließlich Admin-Client (Auto-Discovery vom Server). 30-Tage-Retention via webhook-field-catalog-cleanup-Cron (täglich 03:30 UTC) — Felder die 30 Tage nicht in einem Webhook auftauchen werden gelöscht. (3) webhook_routing_alerts: Softfail-Diagnose wenn eine Routing-Regel an einer Condition scheitert WEIL das Feld in der Payload fehlt (Operator ungleich not_exists). Spalten: workspace_id, rule_type, rule_id, webhook_request_id (FK auf webhook_requests, ON DELETE SET NULL bei 90-Tage-Retention), missing_field_path, payload_snapshot (JSONB mit PII-redactedem Payload, max 32 KB, redaktiert über dieselbe Pfad-Endung-Heuristik wie der Feld-Katalog + Wert-Pattern), resolved_at + resolved_by (FK auf auth.users, SET NULL bei User-Löschung). UNIQUE (rule_type, rule_id, missing_field_path, webhook_request_id) macht die Alert-Schreibung idempotent pro Webhook-Request. RLS: SELECT für admin+manager des Workspaces, UPDATE (resolve) für admin+manager, INSERT/DELETE nur Admin-Client. 180-Tage-Retention für resolved UND unresolved Alerts via webhook-routing-alerts-cleanup-Cron (täglich 04:00 UTC) — DSGVO-Storage-Limitation (Art. 5 Abs. 1 lit. e). Zusätzlich: webhook_requests.has_routing_alert (BOOLEAN, DEFAULT false) — wird best-effort gesetzt sobald Alerts für einen Request geschrieben wurden; Partial-Index ermöglicht effizientes Filtering der problematischen Webhooks in der Diagnose-UI. Auch der Drift-Audit-Cron (webhook-routing-conditions-drift-audit, täglich 05:00 UTC) prüft, ob jede routable Routing-Regel mindestens eine Condition besitzt (seit B-3a sind Conditions die runtime-autoritative Routing-Quelle — fehlende Conditions würden no_match auslösen); bei einem solchen Condition-Gap wird trackError ausgelöst. Backwards-Compat: B-1-Backfill hat für jede Bestand-Regel mindestens 1 Condition erzeugt (4 webhook_contact_mappings → 8 Conditions, 12 matelso_routing_rules → 12 Conditions); Legacy-Spalten bleiben für 2 Releases gefüllt und werden bei jedem POST/PATCH dual-write gepflegt. R-686-konformer CHECK-Constraint-Rollup auf notifications_type_check via Phase B-6 Migration.
Asset-Master-Pipeline (PROJ-419) + Visual Intelligence (PROJ-420) + Semantische Metadaten (PROJ-421) + Mehrsprachige Alt-Texte (PROJ-474)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an verlustfreier Medienverwaltung, automatischer Format-Konvertierung für Web- und Druck-Ausgabe, Barrierefreiheit durch KI-generierte Alt-Texte und semantische Asset-Suche). Erweitert PROJ-296 (Markenassets) um ein zweistufiges Medienmodell: verlustfreier Master-File plus automatische Derivate. PROJ-420 ergänzt KI-basierte Transformationen (Focal-Point-Erkennung, Background Removal, KI-Upscaling, SVG-Farbdynamik). PROJ-421 ergänzt KI-generierte semantische Metadaten (Alt-Texte DE/EN, semantic_description, detected_objects, mood_tags, content_rating) und pgvector-basierte Ähnlichkeitssuche via OpenAI text-embedding-3-small. PROJ-474 erweitert die Alt-Text-Generierung auf bis zu 10 Ziel-Sprachen entsprechend der pro Kontakt konfigurierten Zielmärkte (Mehrsprachig Alt-Texte für Barrierefreiheit gemäß WCAG 2.1 AA in internationalisierten Websites).
- Master-File (brand-assets-master Bucket, privat, 500 MB Limit): Verlustfreies Original im Format TIFF, PSD, AI, EPS, PNG, JPG, SVG oder PDF. Pfad-Schema: {workspace_id}/{asset_id}/{filename}. Zugriff ausschließlich für Workspace-Admins und Manager via RLS-Policies. Keine Personen-Metadaten im Dateinamen erwartet (Asset-Bezug, nicht Personen-Bezug)
- Web-Derivate (brand-assets-web Bucket, öffentlich lesbar via CDN): Automatisch generierte WebP, Avif, PNG und JPEG-Preview-Varianten + PROJ-420 Crop-Varianten (crop_16_9/1_1/4_3/4_5/9_16) + KI-Transformationen (transparent_bg, upscaled_2x/4x, dna_colored). Öffentlich zugänglich über Supabase Storage CDN — URL wird nur Workspace-Mitgliedern im UI angezeigt. Maximal 10 MB pro Derivat
- Print-Derivate (brand-assets-print Bucket, privat, 100 MB Limit): Nur bei is_print_ready=true. CMYK-Konvertierung für Druck-Workflows. Zugriff wie Master-Bucket auf Admin/Manager beschränkt
- Focal-Point-Metadaten (PROJ-420 — brand_assets.focal_point_x/y/auto): x/y-Koordinaten (0.0–1.0) des visuellen Hauptmotivs. Kein direkter Personenbezug — reine Bild-Metadaten. focal_point_auto zeigt an ob die Werte KI-erkannt oder manuell gesetzt wurden
- Verarbeitungs-Queue (brand_asset_jobs): User-ID des Auslösers (created_by), Job-Typ (generate_all/regenerate_format/pdf_preview/bulk_workspace/focal_point/background_removal/upscale/svg_dna_color), Status, Fehler-Nachricht bei Fehlschlägen. Enthält personenbezogenen Bezug via created_by → Art. 15/20 DSGVO-Datenexport
- Derivate-Status (brand_asset_derivatives): Format, URL, Datei-Größe, Abmessungen, Status (pending/processing/ready/failed), Zeitstempel. Kein direkter Personenbezug
- Externe Verarbeitung (optional, nur bei Cloudinary-Konfiguration): Dateien ≥ 50 MB oder CMYK-Jobs werden zur Transformation an Cloudinary Ltd. (EU-Region) übermittelt. Ergebnis wird zurückgegeben und in den eigenen Buckets gespeichert — keine dauerhafte Speicherung durch Cloudinary bei Verwendung der Direct-Upload-API. Siehe PROCESSORS-Eintrag Cloudinary Ltd.
- PROJ-420 externe KI-Verarbeitung (optional, jeweils eigener Opt-in über Env-Var): (1) Claude Vision (Anthropic) für Focal-Point-Erkennung — Bilder werden transient übermittelt, siehe PROCESSORS-Eintrag Anthropic PBC; (2) Remove.bg (Kaleido AI GmbH, Österreich/EU) primär für Background Removal — Raster-Bilder werden zur Verarbeitung übermittelt, Ergebnis-PNG zurück; (3) Replicate.com (USA, SCCs) als BG-Removal-Fallback und für KI-Upscaling (Real-ESRGAN) — Bilder werden an das Replicate-Modell übermittelt. SVG-Farbdynamik läuft komplett serverseitig in Node.js ohne externe APIs. Alle drei externen Dienste sind optional — ohne konfigurierte API-Keys bleiben die zugehörigen Buttons in der UI disabled
- PROJ-421 Semantische Metadaten (brand_assets.alt_text_de/en, semantic_description, semantic_caption, detected_objects, dominant_colors, mood_tags, content_rating, metadata_score, is_restricted, linked_goal_ids/target_group_ids/persona_ids): KI-generierte Metadaten für Barrierefreiheit (WCAG-Alt-Texte) und semantische Suche. Bilder werden transient an Claude Vision (Anthropic PBC) übermittelt — siehe PROCESSORS-Eintrag. Bilder können PBD enthalten wenn Personen im Motiv sind. Ergebnisse werden in brand_assets-Spalten gespeichert. NSFW-klassifizierte Assets werden mit is_restricted=true versehen und lösen eine Inbox-Notification an Platform-Admins aus. Editierbar als Freitext-Override durch Admins/Manager
- PROJ-421 Semantische Embeddings (brand_asset_embeddings.embedding vector(1536)): Text-Embedding der semantic_description via OpenAI text-embedding-3-small — ermöglicht semantische Ähnlichkeitssuche via pgvector cosine similarity. Übermittelt wird ausschließlich der KI-generierte semantic_description-Text (keine Bild-Daten, keine personenbezogenen Daten). 1 Embedding pro Asset, CASCADE-Löschung bei Asset-Löschung. ivfflat-Index für performante Ähnlichkeitssuche (Cosine Distance Operator)
- PROJ-474 Mehrsprachige Alt-Texte (brand_asset_alt_texts): Pro (Asset, Sprach-Code)-Eintrag speichert alt_text (max. 125 Zeichen, WCAG-konform), is_ai_generated (true/false), manually_edited_at (Zeitstempel manueller Bearbeitung), generated_at (KI-Generierungs-Zeitstempel), model_used (z. B. 'claude-haiku-4-5-20251001'). Sprach-Codes folgen BCP-47 (z. B. 'de', 'en', 'fr', 'es-MX'). Kein direkter Personenbezug in Metadaten — Alt-Texte beschreiben das Bild für Barrierefreiheit. Bilder selbst werden transient an Claude Haiku Vision (Anthropic PBC) übermittelt — siehe PROCESSORS-Eintrag. Bilder können PBD enthalten wenn Personen im Motiv sind. Zwei Erzeugungspfade: (1) automatisch beim Asset-Upload via Job-Queue (job_type: generate_multilingual_alt_texts) gemäß den für den Kontakt konfigurierten Zielmärkten und deren Sprach-Codes; (2) Backfill beim Hinzufügen einer neuen Zielsprache via Kontakt-Konfiguration (job_type: backfill_alt_text_language) — überspringt manuell editierte Alt-Texte (manually_edited_at IS NOT NULL) und erstellt eine Zusammenfassungs-Notification nach Abschluss. Editierbar als Freitext-Override durch Admins/Manager (setzt manually_edited_at). RLS: Workspace-Mitglieder lesen, Admin+Manager schreiben
- PROJ-495 KI-Metadaten-Suche (brand_asset_ai_metadata): Pro Asset (1:1-Beziehung via UNIQUE asset_id) speichert detected_objects (JSONB String-Array allgemeiner Objekte wie 'Person', 'Laptop' — KEINE biometrische Identifikation, keine Personenerkennung), mood_tags (JSONB String-Array, z. B. 'professionell'), dominant_colors (JSONB Objekt-Array mit hex+percentage), ai_full_description (TEXT, 150–300 Wörter Deutsch — kann nicht-identifizierende Personenbeschreibungen enthalten wie 'eine Person sitzt am Schreibtisch'), analysis_status (pending/processing/completed/failed), analyzed_at, model_used. Zusätzlich PROJ-498 color_moods (text[] — algorithmisch aus dominant_colors via HSL-Klassifikation abgeleitet, KEIN LLM-Call, kein Personenbezug; 9 Farbstimmungs-Kategorien: hell/dunkel/grau/pastell/kontrast/warm/kuehl/bunt/erdtoene). Bilder werden transient als Base64 an Claude Haiku 4.5 Vision (Anthropic PBC) übermittelt — keine dauerhafte Speicherung durch Anthropic. Der System-Prompt instruiert das Modell explizit, Personen nur als allgemeine Kategorie 'Person' zu kennzeichnen ohne biometrische Identifikationsmerkmale. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an semantischer Asset-Suchbarkeit). DSFA-Einschätzung: Nicht erforderlich, da keine biometrische Identifikation stattfindet und lediglich allgemeine visuelle Merkmale ohne Personenbezug gespeichert werden. Workspace-scoped, CASCADE-DELETE bei Asset-/Workspace-Löschung. RLS: Workspace-Mitglieder lesen, Admin+Manager schreiben. EU AI Act Art. 50: KI-generierte Inhalte sind im Asset-Detail-Sheet mit Sparkles-Icon als 'KI-generiert' gekennzeichnet
Call-Tracking & Inbound-Call-Attribution (Matelso, PROJ-418)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Vertriebsanalyse, Kampagnen-Effizienzmessung, Werbe-Attribution). Bei Offline-Conversion-Sync an Google Ads und Meta zusätzlich Art. 6 Abs. 1 lit. f (Werbe-Erfolgsmessung mit pseudonymisierten Daten). Eine DSFA nach Art. 35 DSGVO wurde durchgeführt (docs/dsfa/PROJ-418-matelso-call-tracking.md) — Risiken: systematische Cross-Session-Überwachung via phone_hash, Verknüpfung Browser-Verhalten + Anrufer-Identifikation.
- Rufnummer des Anrufers (caller_number): Transient — wird im Webhook-Handler sofort SHA-256-gehasht. Der Klartext verlässt unseren Server NIE — keine Persistierung in Datenbank, Logs oder Error-Tracking. Rechtsgrundlage für kurzzeitige transiente Verarbeitung: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Cross-Session-Verknüpfung)
- phone_hash (SHA-256): Pseudonymisierter Hash der Anrufernummer, dient als Entity-Anchor für den Identity Graph (session_entity_mapping). Ermöglicht die Verknüpfung aller Web-Sessions desselben Anrufers vor und nach dem Telefonanruf. Aufbewahrung: 180 Tage (täglicher Cleanup-Cron matelso_cleanup, 03:15 UTC)
- Call-Metriken (matelso_calls): Zielrufnummer (Unternehmensnummer — kein Personenbezug), Anrufstatus (answered/missed), Gesprächsdauer (talk_time_seconds), Klingeldauer (ring_time_seconds). Retention: 180 Tage
- Attribution-Daten: Werbe-Click-IDs (gclid, fbclid, wbraid, msclkid) und UTM-Parameter (utm_source, utm_medium, utm_campaign, utm_term, utm_content). Dienen der Kampagnen-Attribution und werden bei qualifizierten Anrufen (talk_time_seconds ≥ 30s Default, konfigurierbar pro Workspace) als Offline-Conversion an Google Ads (Enhanced Conversions for Leads via gclid/wbraid) und Meta Conversions API (via fbclid) übertragen. Retention: 180 Tage
- Journey-Daten: first_click_referrer, last_click_referrer, landing_page_url. Retention: 180 Tage
- Session-Stitching (client_session_id): Neuland-Session-ID aus sessionStorage des Nutzers, wird via matelso.setCustomData() als custom_data.neuland_session_id an Matelso übergeben und kommt im Webhook zurück. Nur gesetzt wenn `tracking_domains.matelso_stitching_enabled = true` UND `window.__neulandConsent.tracking === true` (TDDDG §25-konform). Dadurch wird der Anruf als abschließendes Event in die Session-Recording-Timeline eingebettet
- Matelso-Konfiguration (matelso_config): Partner-ID (4-stellige Matelso-Kunden-ID, Klartext — öffentliche Kennung, auch als Benutzername in der API-URL sichtbar), Partner-Passwort (AES-256-GCM verschlüsselt über einen dedizierten MATELSO_ENCRYPTION_KEY, Format iv:authTag:ciphertext base64 — wird für Query-Parameter-Authentifizierung an die Matelso XML-API https://api.matelso.com/V2/calltracking.asmx/<METHOD>?partner_id=X&partner_password=Y entschlüsselt), Webhook-Secret (zufälliger 32-Byte Hex-Token für HMAC-Validierung eingehender Webhooks), qualified_call_min_seconds (Schwellenwert für Offline-Conversion), routing_mode (PROJ-568: legacy_pool_mapping | first_match_wins | all_matches — Default für Bestand: legacy_pool_mapping), field_mapping_defaults (PROJ-568: JSONB mit Workspace-weiten Default-Mappings welches Webhook-Feld den customer_identifier liefert; reine Konfigurations-Daten, kein Personenbezug). Zugangsdaten sichtbar und bearbeitbar ausschließlich für Workspace-Admins (Partner-Passwort nur Admin via PUT, Lesen Admin/Manager — Partner-Passwort wird nie im Klartext an Clients ausgeliefert). Löschung bei Workspace-Löschung via CASCADE
- Pool-Mappings (matelso_pool_mappings, aktualisiert 2026-04-23 durch PROJ-465 + 2026-05-06 durch PROJ-568): Zuordnung Matelso-Pool-ID + Zielrufnummer → target_workspace_id (Ziel-Workspace) + Tracking-Domain. Seit PROJ-465 wird ein Workspace als Routing-Ziel gespeichert, nicht mehr ein einzelner CRM-Kontakt. matelso_calls werden direkt im Ziel-Workspace persistiert (workspace_id = target_workspace_id), damit die Call-Daten im Website-Tracking des Kunden-Workspaces erscheinen. Pool-Mappings selbst enthalten weiterhin keinen direkten Personenbezug (nur Unternehmensdaten und UUID-Referenzen). Seit PROJ-568 zusätzlich: subscriber_name + subscriber_domain (Geschäftsdaten der Matelso-Account-Inhaber, Cache aus show_subscribers-API, Sync alle 6h via Cron matelso-subscriber-sync) + subscriber_synced_at (Cache-Frische). Workspace-scoped RLS (Admin/Manager). Löschung bei Workspace-Löschung via CASCADE; target_workspace_id bei Workspace-Löschung via ON DELETE SET NULL
- Routing-Regeln (matelso_routing_rules, NEU PROJ-568, erweitert 2026-05-11 durch PROJ-615): Deklarative Routing-Regeln pro Workspace die eingehende Webhooks anhand eines Triggers (destination_number / pool_id / customer_identifier-Custom-Field) einem Ziel-Workspace + optionalen Ziel-Kontakt zuweisen. Pro Regel: Name, trigger_type, match_value, customer_identifier_field (nur bei trigger_type='customer_identifier'), target_workspace_id (FK ON DELETE SET NULL), target_contact_id (FK ON DELETE SET NULL), field_mapping (JSONB für Pro-Regel-Override des Field-Mappings — kein Personenbezug, reine Konfiguration), sort_order, is_active, routing_mode (Single-Mode-Legacy). PROJ-615 ergänzt: routing_modes (text[]: Subset von {lead_pipeline, recruiting_pipeline, tracking_only}, mindestens 1, max 3 — Multi-Mode), pipeline_target_workspace_id und tracking_target_workspace_id (separate Routing-Ziele pro Modus, FK ON DELETE SET NULL), tracking_default_contact_id (FK ON DELETE SET NULL, separater Default-Kontakt für tracking_only), identifier_match und form_type_match (JSONB-Matcher mit Operator equals/not_equals/in/not_in/contains/not_contains/regex/any — erlauben Mehrfachwerte und Substring-/Regex-Pattern). Aktivierung pro Workspace via routing_mode in matelso_config. Workspace-scoped RLS (Admin/Manager). Löschung bei Workspace-Löschung via CASCADE.
- Webhook-Sicherheit: Matelso-Webhook nutzt HMAC-timing-safe Signatur-Validierung (X-Matelso-Signature). Rate-Limit: 500 req/min per IP + 500 req/min per Workspace. Unbekannte destination_numbers werden mit HTTP 200 quittiert + trackError geloggt — niemals 5xx (würde Matelso-Retry triggern). Bei aktivem Routing-Modus first_match_wins | all_matches und 0 Routing-Regel-Treffer: processing_status='no_routing_match' im Webhook-Log + Notification matelso_webhook_no_routing_match an Workspace-Admin/Manager (PROJ-568)
- Webhook-Eingangslog (matelso_webhook_logs): Diagnose-Log aller eingehenden Matelso-Webhooks inklusive abgewiesener Requests (unbekannte Zielnummer, Signatur-Fehler, Rate-Limit-Abweisungen, no_routing_match seit PROJ-568). Persistiert: Zeitstempel, Absender-IP, Zielrufnummer, Matelso-Call-ID, SHA-256-Hash der Anrufernummer (KEIN Klartext), Gesprächs-Status und -Dauer, redigiertes Payload (caller_number=REDACTED) sowie gekürzte HTTP-Header (x-matelso-signature maskiert). Dient ausschließlich der Fehlerdiagnose durch Workspace-Admins/Manager. Retention: 30 Tage (Cleanup-Cron proj418_matelso_webhook_logs_cleanup, 03:20 UTC). Löschung bei Workspace-Löschung via CASCADE.
Content-Anlass-KI-Matching & Briefing-Vorschläge (PROJ-459)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter Redaktionsplanung und Optimierung des Content-Marketing-Workflows). Die KI-Verarbeitung verwendet ausschließlich anonymisierte Branchen- und Produktdaten — keine Klartext-Kontaktnamen oder Endkunden-PII werden an Anthropic übermittelt. Für den KI-Matching-Pfad Auftragsverarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC (siehe PROCESSORS).
- Branchen-Information des Kontakts (kategorisch, kein Personenbezug)
- Anonymisierte Persona-Namen (max. 3 Personas, keine Kontaktdaten der Endpersonen)
- Produkt-/Leistungs-Stichpunkte aus SSOT-Bedarfsgruppen (max. 5, anonymisiert)
- Anlass-Tage-Informationen (Titel, Beschreibung — öffentlich bekannte Daten, kein Personenbezug)
KI-Keyword-Seiten-Mapping (PROJ-470)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter SSOT-Marketing-Datenpflege und Reduktion manueller Mapping-Zeit von Stunden auf Minuten). Auftragsverarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC (siehe PROCESSORS-Eintrag).
- Keyword-Begriffe (z.B. industrielle additive fertigung kunststoff) — Suchbegriffe aus der SSOT-Marketing-Intelligenz, kein direkter Personenbezug
- Bedarfsgruppen-Seiten-Bezeichnungen (z.B. 3D-Druck für Industriekunden) — kunden-spezifische Seitennamen aus ssot_items.data, kein direkter Personenbezug
- Konfidenz-Scores (0–100) und KI-Reasoning (Freitext-Begründung der KI für Top-3-Vorschläge), gespeichert in keyword_page_mapping_suggestions
- Job-Lifecycle-Daten (keyword_page_mapping_jobs): Status (pending/processing/completed/failed/cancelled), Fortschritt (processed_keywords/total_keywords), created_by (User-ID), Zeitstempel — Audit-Trail wer wann welche KI-Analyse ausgelöst hat
- Anthropic-Übermittlung: System-Prompt enthält die vollständige Liste der Bedarfsgruppen-Seitennamen des Kontakts (mit cache_control: ephemeral für Token-Kostenoptimierung). User-Prompt enthält Chunks à 50 Keyword-Begriffe. Keine Kontaktdaten, E-Mails, Telefonnummern oder andere PII werden übermittelt — ausschließlich Keyword-Begriffe und Seiten-Bezeichnungen.
KI-Keyword-Marketingziel-Zuordnung (PROJ-861)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter SSOT-Marketing-Datenpflege — automatische Zuordnung von Keywords zu Marketingzielen statt manueller Analyse). Auftragsverarbeitung gemäß Art. 28 DSGVO mit OpenAI Inc. (Embedding-Modell text-embedding-3-small, siehe PROCESSORS-Eintrag).
- Keyword-Begriffe — Suchbegriffe aus der SSOT-Marketing-Intelligenz, kein direkter Personenbezug. Werden via OpenAI text-embedding-3-small in Vektoren umgewandelt (transient, kein Training).
- Marketingziel-Texte (ssot_items.section='marketing_goal': data->>'titel' + data->>'beschreibung') — vom Workspace selbst gepflegte Zielbeschreibungen, üblicherweise kein Personenbezug. Ebenfalls als Embedding an OpenAI übermittelt.
- KI-Vorschlag-Felder auf der keywords-Tabelle: marketing_goal_ai_suggestion_id (FK auf vorgeschlagenes Marketingziel), marketing_goal_ai_confidence (Cosine-Similarity 0,00–1,00), marketing_goal_ai_rejected (Boolean: Nutzer hat Vorschlag explizit abgelehnt). Die finale Zuordnung marketing_goal_id (PROJ-771) wird vom Nutzer bestätigt.
- Job-Lifecycle-Daten (keyword_goal_mapping_jobs, PROJ-887 — explizite Analyse-Steuerung): Status (queued/running/paused/completed/failed/cancelled), overwrite_existing (Boolean), Fortschritt (processed_keywords/total_keywords), Zeitstempel (started_at/completed_at/last_heartbeat_at), created_by (User-ID — Audit-Trail wer wann welche KI-Analyse ausgelöst hat), error_log (JSONB: Liste fehlgeschlagener Keywords mit keyword_name + Fehlermeldung + Zeitstempel; keyword_name ist ein Suchbegriff ohne direkten Personenbezug). Workspace-/Contact-scoped, keine Kontaktdaten/E-Mails/PII außer der auslösenden User-ID.
Autonome Tracking-Analyse (PROJ-475)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter automatischer Tracking-Einrichtung und Reduktion manueller Setup-Zeit auf Kundenwebsites). Verarbeitung ausschließlich von öffentlich sichtbaren Website-Inhalten (URL-Pfade, Button-Labels, Überschriften) ohne Personenbezug. Auftragsverarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC (siehe PROCESSORS-Eintrag). EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung bei Blueprint-Vorschlägen, Event-Mapping-Empfehlungen und Content-Theme-Clustern.
- URL-Pfade der besuchten Seiten der Kundenwebsite (ohne Query-Parameter) — aggregiert aus tracking_events zur Topologie-Klassifizierung, kein Personenbezug
- Button-Labels und href-Attribute aus button_click-Events (z.B. Jetzt anfragen, Warenkorb) — werden zum Semantic Event Matching an Claude Haiku übermittelt, keine PII
- Heading-Texte (h2/h3) aus content_engaged-Events (4-Sekunden-Viewport-Timer auf Kundenwebsite) — aggregiert und für Content-Theme-Clustering an Claude Haiku übermittelt, keine PII
- Blueprint-Daten (tracking_blueprints): erkannte Topologie-Typen, vorgeschlagene Konfigurationsregeln, Konversionsraten-Ziel (target_conversion_rate), Analyzer-Version, Status (analyzing/ready/insufficient_data/error) — workspace-scoped, keine Personendaten
- Event-Vorschläge (tracking_event_suggestions): Trigger-Beschreibung, Trigger-Signatur (Hash über Button-Label + href), vorgeschlagener Standard-Event-Typ, Konfidenz-Score (0–1), Freigabe-Status (pending/approved/approved_renamed/rejected), resolved_by (User-ID beim manuellen Akzeptieren) — Audit-Trail der KI-Empfehlungen
- Content-Themen (tracking_content_themes): Themen-Label (deutsch, max. 100 Zeichen), Beispiel-Heading-Texte (max. 5 Samples), Heading-Anzahl, Clustering-Version — keine PII, öffentliche Heading-Texte aus der Kundenwebsite
- Content-Theme-Matches (tracking_content_theme_matches): Verknüpfung zwischen content_engaged-Events (session_hash, heading_text) und Content-Theme für Dashboards — session_hash ist pseudonymisiert, heading_text ist öffentlich
- Anthropic-Übermittlung Phase 1 (Topologie-Klassifizierung): Liste der häufigsten URL-Pfade einer Domain (ohne Query-Parameter). Phase 2 (Semantic Event Matching): Button-Labels und href-Attribute unbekannter Klicks. Phase 3 (Content-Theme-Clustering): Aggregierte Heading-Texte. Keine IP-Adressen, Session-Hashes, Nutzer-Agenten, Kontaktnamen, E-Mails oder andere PII werden übermittelt.
Sales CRM Deal-System (PROJ-479)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung und -erfüllung: Dokumentation von Verkaufschancen, Angebotsnachverfolgung gegenüber potenziellen und bestehenden B2B-Kunden der Agentur) in Verbindung mit Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an strukturiertem Vertriebs-Controlling, Forecast-Genauigkeit und Lernsystem zur Abschlussoptimierung). KI-Dealwert-Schätzung basiert ausschließlich auf B2B-Firmendaten und kategorialen Merkmalen ohne direkten Personenbezug — Auftragsverarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC (siehe PROCESSORS-Eintrag).
- Deal-Stammdaten (sales_deals): Verknüpfung mit Kontakt (contact_id, ggf. contact_person_id als Ansprechpartner), Deal-Name (z.B. Website Relaunch), Leistungsbereich (kategorisch), Leadquelle, zuständiger Vertriebler (assigned_user_id), Kundenkategorie A-D/Spam, Deal-Herkunft (neukunde/bestandskunde/reaktivierung), geschätzter Deal-Wert in Cent (KI- oder manuell), Closing-Datum
- Vertriebliche Status-Tracking-Felder: Angebot-Versand-Zeitpunkt, Angebotsgespräch-Termine, Entscheidungs-Erwartungszeitpunkt, Nachfass-Flag, Preisvorwand-Flag, Kunde-prüft-intern-Flag, Budget-Status, Entscheider-bekannt-Flag — alle zum Zweck interner Vertriebssteuerung, werden dem Kunden nicht angezeigt
- Pipeline-Struktur (sales_pipelines, sales_deal_stages): Neukunden- und Bestandspipeline pro Workspace mit konfigurierbaren Stages (Neu, Kontaktiert, Qualifiziert, Angebot, Gewonnen, Verloren + Custom-Stages), Phase-Faktor für Forecast, Farbcodierung — keine Personendaten
- Erweiterbare Lookup-Listen (sales_deal_types, sales_deal_lost_reasons): adminseitig gepflegte Dealnamen (z.B. Website Relaunch, SEO Betreuung) und Verlustgründe (z.B. Zu teuer, Kein Budget) — keine Personendaten
- Verloren-Informationen: lost_reason_id (kategorisch aus Dropdown), lost_reason_detail (Freitext-Feld, max. 5.000 Zeichen, kann interne Vertriebsnotizen mit Kontext zur Kundensituation enthalten — nur für Vertrieb/GF sichtbar, niemals kundensichtbar)
- Deal-Audit-Log (sales_deal_activities): chronologische Historie aller vertriebsrelevanten Ereignisse (Status-Wechsel, Mail-Versand, Anruf, Meeting, Angebot-Versand/Angenommen/Abgelehnt, Task erstellt/erledigt, Score geändert, Merge). metadata-JSONB enthält Kontextdaten wie from_stage/to_stage, aber keine freien Kommunikationsinhalte — nur Event-Fakten
- Merge-Historie (sales_deal_merges): source_deal_id, target_deal_id, merged_by (User-ID), merged_at, merge_summary (JSONB mit Zusammenfassung der zusammengeführten Datenpunkte) — unveränderbares Audit-Log
- Deal Health Score (0–100): regelbasiert berechneter Vertriebs-Qualitätsindex pro Deal, beeinflusst Forecast, manuell überschreibbar durch Vertriebler
- Deal Health Score Verlauf (PROJ-487 — sales_deal_score_history): Immutabler Audit-Log aller Score-Änderungen mit score (0–100), score_class (kategorisch), change_type (event/daily_recompute/manual_adjustment/phase_change/manual_recompute), delta zum vorherigen Score, factors-JSONB mit Faktor-Schlüssel und Punkt-Delta (z.B. funkstille_14d: -12, angebot_geoeffnet_3x: +15) — keine Kommunikationsinhalte, nur aggregierte Verhaltensindikatoren. triggered_by (FK auf auth.users, ON DELETE SET NULL bei manueller User-Aktion). Quelle für Sparkline + Trend-Analyse im Deal-Detail. Berechnung erfolgt regelbasiert (kein LLM, keine externe Datenübermittlung).
- Manuelle Score-Anpassung (sales_deals.manual_score_adjustment): -10 bis +10 Punkte Bauchgefühl-Faktor des Vertrieblers. Wird auf den berechneten Basis-Score addiert (nicht überschreibend), mit explizitem Audit-Eintrag in sales_deal_score_history (change_type='manual_adjustment').
- Anthropic-Übermittlung KI-Dealwert-Schätzung (sales_deal_value_estimate): Leistungsbereich (kategorisch), Firmenname des B2B-Kontakts (öffentliche Unternehmensinformation), Branche und Unternehmensgröße (kategorische Ranges), historische gewonnene/verlorene Deals desselben Kontakts als anonymisierte Aggregate (Dealname + Wert in Cent + Status). Keine direkten Kontaktdaten, E-Mails, Telefonnummern oder Kommunikationsinhalte.
- Verknüpfung mit Angeboten (quotes.deal_id): Optional — ein Deal kann mehrere Angebote haben, aktueller deal_value_source kann auf Angebotswert wechseln, sobald Angebot erstellt
- PROJ-579 Lifecycle-Metadaten (sales_deals.is_draft): Boolean-Flag das anzeigt, ob ein Deal noch im Entwurf ist (kein Task vorhanden). Wird automatisch via DB-Trigger gepflegt — kein direkter Personenbezug. Begleitendes Workspace-Setting: workspaces.allow_quotes_without_deal (Boolean, Admin-Override für Edge-Case interner Kalkulationen ohne Deal-Verknüpfung).
- PROJ-599 Sales-Dashboard-Settings pro Mitarbeiter (user_sales_preferences): Pro Mitarbeiter und Workspace wird eine UI-Präferenz gespeichert (dashboard_settings.priority_sort: 'health' | 'value' | 'decision_date'), mit der die Sortierung des 'Priorisierte Deals'-Widgets auf dem Sales-Dashboard cross-device persistiert wird. Speichert keine personenbezogenen Inhalte, sondern lediglich die UI-Wahl (Enum-Wert) — Verknüpfung user_id + workspace_id. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an personalisiertem Workspace-Erlebnis). Workspace-scoped, CASCADE-DELETE bei User-/Workspace-Löschung.
- PROJ-600 Mehrfach-Ansprechpartner-Verknüpfung (sales_deal_contact_persons): M:N-Junction-Tabelle Deal ↔ Ansprechpartner (contacts) — pro Deal können mehrere CRM-Kontakte als Ansprechpartner verknüpft werden, mit Markierung des primären Ansprechpartners (is_primary). Datenkategorien: deal_id (FK sales_deals), contact_id (FK contacts), is_primary (Boolean), created_at. Keine zusätzlichen personenbezogenen Daten — sämtliche Kontaktdetails (Name, E-Mail, Telefon) bleiben in der contacts-Tabelle und werden nur über contact_id referenziert. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung mit identifizierten Ansprechpartnern). Workspace-scoped via JOIN auf sales_deals.workspace_id, CASCADE-DELETE bei Deal- oder Kontakt-Löschung. Primär-Ansprechpartner wird via Trigger zurück in sales_deals.contact_person_id gespiegelt (Legacy-Abwärtskompatibilität).
- PROJ-618 Deal-First-Webhook-Workflow (sales_deals neue Spalten): contact_id NULLABLE für anonyme Webhook-Leads (kein CRM-Match → Deal hat noch keinen Kontakt); spam_score (Integer 0–100, deterministische Heuristik aus Free-Mail-Domain + Sprach-Mismatch + Spam-Keywords + Submission-Flood — kein LLM, kein PII im Score-Algorithmus); spam_signals (JSONB mit Heuristik-Marker, PII-frei); webhook_payload (JSONB mit Original-Webhook-Body — kann Klartext-E-Mail, Telefonnummer, Firma, Nachricht enthalten; bei Matelso-Calls wird die un-gehashte caller_number im persistierten Payload als „[REDACTED]" ersetzt, der Hash bleibt in matelso_calls.phone_hash); contact_created_at (Idempotenz-Marker für die deferred CRM-Anlage beim Stage-Move zu „Validiert"); ki_prefill_meta (JSONB mit Diagnose welche Felder von KI-Pre-Fill gefüllt wurden — Modell, Latenz, Token-Counts, Fallback-Reason); created_via (manual/webhook/matelso/manual_import zur Klassifizierung der Anlage-Quelle). Anthropic-Übermittlung KI-Pre-Fill (sales_deal_prefill): Webhook-Payload (E-Mail, Telefon, Firmenname, Kontaktname, Nachricht, Form-Type) wird transient an Claude Haiku 4.5 zur Generierung von deal_name + leistungsbereich (kategorisch) + kundenkategorie (a/b/c) gesendet — keine Speicherung bei Anthropic (Zero-Data-Retention). Beim Stage-Move zu „Validiert" wird aus webhook_payload automatisch ein contacts-Eintrag erstellt, sodass die Daten ab dann unter dem regulären CRM-Datenschutz-Regime liegen.
- PROJ-618 Validiert-Stage (sales_deal_stages): Neuer stage_type='validiert' wird per Migration in alle Neukunden-Pipelines (sales_pipelines.kind='neukunden') idempotent eingefügt. Beim Move eines Webhook-Auto-Deals in diese (oder eine spätere) Stage wird die deferred CRM-Anlage getriggert (Spam-Schutz: das CRM wird nicht mit ungeprüften Anfragen geflutet). Kein direkter Personenbezug — die Stage selbst ist nur eine Pipeline-Position.
- PROJ-618 Leadquelle-Mapping (webhook_pipeline_mappings.leadquelle_field, webhook_routing_configs.default_leadquelle_field, matelso_routing_rules.leadquelle_field): Admin-konfigurierbare Mapping-Felder die einen Payload-Feldnamen auf sales_deals.leadquelle abbilden. Keine personenbezogenen Daten — speichern nur Feldnamen (z.B. „utm_source", „form_name"). Workspace-scoped, CASCADE-DELETE bei Workspace-Löschung.
- PROJ-697 Automatisierte Stage-Progression (drei DB-Trigger auf sales_tasks/sales_communication_log/sales_call_sessions): Webhook-Deals werden forward-only durch die Pipeline bewegt. Trigger 1: Auto-Task-Abschluss (task_origin=automatisch + goal=lead_validieren + status=erledigt) verschiebt Deal von Stage neu nach validiert. Trigger 2: erster outbound-Eintrag in sales_communication_log (direction=outbound + channel in email/phone/video_meeting/in_person + created_by IS NOT NULL) verschiebt Deal nach kontaktiert. Trigger 3: erste abgeschlossene sales_call_sessions (status=completed + started_at IS NOT NULL) verschiebt Deal nach kontaktiert. Bei Move zu non-neu-Stage wird die deferred CRM-Anlage aus PROJ-618 AC-14 via gemeinsamer Helper-Function fn_ensure_deal_contact transparent ausgelöst (identische webhook_payload-Verarbeitung wie der manuelle Drag-and-Drop-Pfad). Jeder Auto-Move erzeugt einen Audit-Eintrag in sales_deal_activities (activity_type=status_changed) mit metadata={auto:true, proj:PROJ-697, from_stage_id, from_stage_type, to_stage_id, to_stage_type, trigger_source (task_completion|outbound_email|outbound_phone|outbound_video_meeting|outbound_in_person|outbound_call_session), source_id (Task-/Communication-Log-/Call-Session-ID), contact_auto_created_id (UUID des ggf. neu erstellten CRM-Kontakts oder null)} und created_by=auth.uid() (auslösender User). Keine neuen Spalten auf sales_deals, keine neuen Tabellen, kein neuer externer Provider, keine LLM-Aufrufe in dieser Logik. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an automatisierter, lückenloser Vertriebsdokumentation). Trigger laufen SECURITY DEFINER + search_path=public; Workspace-Isolation bleibt durch die User-Aktion (RLS auf Task-Update/Communication-Insert/Call-Update) bestehen. Audit-Einträge werden via sales_deal_activities.deal_id zusammen mit dem Deal kaskadiert gelöscht. Trigger-Fehler werden mit RAISE WARNING geschluckt — die User-Aktion wird nie blockiert.
- PROJ-835 Auto-Stage bei Angebots-Verknüpfung (ein DB-Trigger trg_proj835_quote_linked_advance auf quotes): Wenn ein Angebot mit einem Deal verknüpft wird (INSERT mit quotes.deal_id IS NOT NULL ODER UPDATE OF deal_id, wobei OLD.deal_id IS NULL oder von NEW.deal_id verschieden ist), wird die Deal-Phase automatisch auf stage_type='angebot' gehoben — über die generische Helper-Function fn_advance_deal_stage_to() aus PROJ-697. Forward-Only: Befindet sich der Deal bereits in einer gleich- oder höher-positionierten Stage (Verhandlung, Abschluss, Gewonnen, Verloren), passiert nichts. Bei Trennung des Angebots (deal_id wird NULL) oder Löschung des Angebots passiert ebenfalls nichts (Forward-Only-Prinzip). Audit-Eintrag in sales_deal_activities (activity_type=status_changed) mit metadata={auto:true, proj:PROJ-697, trigger_source:'quote_linked', source_id:<quote.id>, from_stage_id, from_stage_type, to_stage_id, to_stage_type}. Keine neuen Tabellen, keine neuen Spalten, kein externer Provider, keine LLM-Aufrufe. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an automatisierter, lückenloser Vertriebsdokumentation). Trigger läuft SECURITY DEFINER + search_path=public; Fehler werden mit RAISE WARNING geschluckt — quote-INSERT/UPDATE wird niemals blockiert.
- PROJ-874 Verloren-Kaskade und Wiedervorlage (neue Felder + Tabellen): lost_at (Timestamp des Verlust-Ereignisses), lost_by (FK auf auth.users — Mitarbeiter der den Verlust markiert hat), pipeline_stage_at_loss (FK auf sales_deal_stages — Snapshot der Verkaufsphase zum Verlust-Zeitpunkt, für Verlustanalyse-Reporting). Audit-Log Verlustgrund-Änderungen (deal_loss_reason_changes): Unveränderbare Protokollierung jeder nachträglichen Verlustgrund-Korrektur mit old/new reason_id, old/new reason_detail (Freitext), Kommentar (optional), changed_by (FK auth.users), changed_at. Wiedervorlage-Erinnerungen (deal_reactivation_reminders): Datum-basierte Erinnerung für den zuständigen Mitarbeiter zur Reaktivierungsprüfung — deal_id, contact_id, assigned_user_id, reminder_date, loss_reason_key (kategorisch), status (pending/completed/deleted). Workspace-Konfiguration (sales_workspace_config): loss_reason_followup_config (JSONB: Verlustgrund-Key → Wartezeit in Tagen oder null), lost_deal_email_template_id (FK auf Email-Vorlagen). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an systematischer Vertriebsanalyse und Reaktivierungsmanagement). Keine neuen externen Auftragsverarbeiter. Workspace-scoped, CASCADE-DELETE bei Deal-/Workspace-Löschung.
- PROJ-1063 Preisbereich-Verweildauer (quote_price_view_signals): Beim Öffnen eines Angebots im öffentlichen Angebots-Viewer wird die längste durchgehende Verweildauer (in Sekunden, gedeckelt 0–3600) gemessen, die der Empfänger den Preisbereich sichtbar im Vordergrund hat — ausschließlich diese eine Maximal-Zahl pro Aufruf, KEIN Maus-/Scroll-/Bewegungsprofil und keine Inhalte. Gespeichert mit deal_id (FK sales_deals, ON DELETE CASCADE), quote_id (FK quotes, ON DELETE SET NULL), workspace_id, price_section_dwell_seconds (Integer), created_at. Speist als Verhaltensindikator den Deal Health Score (Faktor angebot_preis_lange_angesehen, ab konfigurierbarer Schwelle in deal_health_score_config.threshold_seconds). Erfassung nur wenn die Preise im Angebot eingeblendet sind (hidePrices=false); bei ausgeblendeten Preisen findet keine Messung statt. Übertragung beim Verlassen der Seite per same-origin Browser-Beacon an einen token-validierten, rate-limitierten Server-Endpunkt — kein Drittanbieter-Kontakt, Verarbeitung ausschließlich serverseitig in Supabase (eu-central-1). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Vertriebsintelligenz, analog zum bestehenden Angebots-Öffnungs-Tracking); Datensparsamkeit durch Speicherung nur des Maximal-Sekundenwerts. Keine DSFA erforderlich (eine minimale Einzel-Metrik, keine systematische Verhaltensüberwachung i.S.v. Art. 35 Abs. 3 lit. c). Workspace-scoped, CASCADE-Löschung mit Deal/Workspace.
- PROJ-1986 Protokoll der Deal-Zusammenführungen (sales_deal_merge_transfers): Hält je Zusammenführung fest, welche Datenarten in welcher Menge von welchem Quell-Deal auf welchen (ketten-aufgelösten) Ziel-Deal übertragen wurden. Datenkategorien: workspace_id, merge_id (FK sales_deal_merges), source_deal_id / requested_target_id / resolved_target_id (FK sales_deals, ON DELETE SET NULL), source_deal_name und resolved_target_name als Text-Kopie (damit das Protokoll aussagekräftig bleibt, wenn ein Deal später gelöscht wird — Deal-Namen enthalten typischerweise den Firmennamen des B2B-Kontakts), origin (live/backfill), status, contact_mode (keep/reassign), different_contacts (Boolean), moved_counts (JSONB mit Mengen je Tabelle — reine Zahlen, keine Inhalte), cancelled_task_count / cancelled_duplicate_count / cancelled_obsolete_count, chain_hops, error_message, executed_by (FK auth.users, ON DELETE SET NULL), executed_at. KEINE Kommunikationsinhalte, keine E-Mail-Adressen, keine Telefonnummern. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an nachvollziehbarer, prüfbarer Datenverarbeitung — der Vorgang verschiebt Kommunikation und Angebote unumkehrbar zwischen Deals). Workspace-scoped, CASCADE-Löschung bei Workspace-Löschung. Wichtig: Beim Zusammenführen zweier Deals VERSCHIEDENER Kunden entscheidet contact_mode, ob der Kundenbezug der übertragenen Korrespondenz (sales_communication_log.contact_id) beim ursprünglichen Kunden bleibt (Voreinstellung) oder auf den Kunden des Ziel-Deals umgeschrieben wird — die Korrespondenz selbst wird in beiden Fällen am Ziel-Deal sichtbar, der Kreis der Zugriffsberechtigten bleibt aber unverändert derselbe Workspace.
Kundenportal-Demo-Präsentation (PROJ-1257)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung — Demo dient der Präsentation der Agenturleistung gegenüber dem potenziellen Kunden); Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an effizienter Vertriebspräsentation für Bestandskontakte)
- Firmenname und Logo (aus CRM-Kontakt: contacts.name, contacts.logo_url)
- Dealname und Leistungsbereich (aus sales_deals — Geschäftskontext, kein direktes Personen-PII)
- Aufruf-Zähler und Zeitstempel des letzten Abrufs (view_count, last_viewed_at — kein Visitor-PII, kein IP-Logging)
- Ersteller-ID (created_by → auth.users, interner Agentur-Mitarbeiter)
System-Demo Slideshow (PROJ-1262)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung — Slideshow dient der Präsentation der Agenturleistung gegenüber dem potenziellen Kunden); Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an effizienter, personalisierter Vertriebspräsentation)
- Firmenname (aus CRM-Kontakt: contacts.name — erscheint in Slideshow-Titel und Share-Link-Seite)
- Dealname und Leistungsbereich (aus sales_deals — Geschäftskontext, kein direktes Personen-PII)
- KI-generierte Demo-Inhalte (system_demo_presentations.ai_generated_data — fiktive Beispieldaten, kein Echtdaten-Bezug, is_demo_data=true CHECK-Constraint)
- Aufruf-Zähler und Zeitstempel des letzten Abrufs (view_count, last_viewed_at — kein Visitor-PII, kein IP-Logging)
UI/UX-Präsentation im Deal — Design-Vorschau mit Share-Link (PROJ-1340/PROJ-1341/PROJ-1344, seit PROJ-1349 zusätzlich im Angebotsprozess verlinkt)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung — Designvorschau dient der Präsentation der Agenturleistung gegenüber dem potenziellen/bestehenden Kunden); Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an einer visuellen Kundenpräsentation)
- Präsentations-Metadaten (uiux_presentations): Titel, Briefing-Freitextfelder (Zielgruppe, Thema, Kampagnenziel, Inhalt, No-Gos, Inspirationslinks — können vom Mitarbeiter eingetragene Kundenwünsche/-zitate enthalten), Entwurfstyp, Status, an Deal (sales_deals) und optional an CRM-Kontakt (contacts) gebunden. Workspace-scoped via RLS
- Kundenname (aus CRM-Kontakt, contact_id): erscheint auf der Titelfolie der öffentlichen Präsentation, sofern ein Kontakt verknüpft ist
- KI-generierter Zieltext (ai_goal_text, Claude Haiku 4.5): aus Briefing-Stichworten + Kundenname erzeugter 3–6-Sätze-Fließtext für Folie 2 — transient an Anthropic übermittelt, kein Training, keine Persistenz bei Anthropic
- Hochgeladene Entwurfsbilder (uiux_presentation_images, Storage-Bucket presentations): Start- und Folgebilder, workspace-isoliert; öffentlicher Abruf über 24h-befristete signierte URLs
- Share-Links: Link aktivierbar/sperrbar (share_is_active), anonymer Aufruf-Zähler (view_count — kein IP-Logging), optionales Ablaufdatum (share_expires_at). Öffentlich geteilte Präsentationen sind ohne Login über einen nicht erratbaren UUID-Token (/public/uiux-presentations/[token]) abrufbar — bewusste Freigabe durch den Mitarbeiter. Bei Format-Mismatch oder Ablauf: 404 statt 403 (kein Info-Leak)
- IP-Adresse (Rate Limiting): Beim öffentlichen Abruf wird die IP-Adresse temporär für Rate Limiting (60 req/min) genutzt, nicht in der Datenbank gespeichert
Sales-Task-System (PROJ-480 + PROJ-646 + PROJ-711)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung und -erfüllung — vertriebsoperative Dokumentation von Handlungsaufträgen mit Kanal+Ziel-Struktur, Follow-up-Tracking) in Verbindung mit Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an strukturiertem Follow-up-Management, KI-basierter Priorisierung nach Deal-Wichtigkeit und Fälligkeits-Dringlichkeit, Verantwortlichen-Audit-Trail). KI-Priorisierung übermittelt ausschließlich anonymisierte Deal-Metadaten (kein direkter Personenbezug). Auftragsverarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC (siehe PROCESSORS-Eintrag).
- Task-Stammdaten (sales_tasks): deal_id (FK auf sales_deals), channel (kategorisch: anrufen/mail_senden/meeting/kundenbesuch/intern/recherche/sonstiges), goal (kategorisch: nachfassen/reaktivieren/entscheidung_einholen/...), title (optional, max 200), notes (optional, max 5000 — kann interne Vertriebsnotizen enthalten), due_date, expected_effort_minutes, priority + priority_source (ki|manual), completion_summary (Freitext bei erledigt, kann Gesprächsinhalte enthalten), next_action + next_action_note (Post-Close-Dialog)
- PROJ-646 Erweiterte Task-Felder (sales_tasks): assigned_user_id ist jetzt NOT NULL (Pflicht-Verantwortlicher für jede Task — keine herrenlosen Tasks mehr), task_origin (kategorisch: manuell/automatisch/ki_vorgeschlagen/folge_task — woher stammt die Task), related_entity_type + related_entity_id (polymorphe Soft-Reference auf Quell-Entität bei task_origin!='manuell', kategorisch: gespraech/angebot/kommunikation/vorherige_task/systemereignis — KEIN echter FK, dangling references erlaubt), result (kategorisch bei status='erledigt' — strukturierter Abschluss), result_note (Freitext, max 2000 — optionale Begründung des Ergebnisses, kann Gesprächsinhalte enthalten), pause_until (TIMESTAMPTZ — Task ist bis dahin pausiert; Cron sales-tasks-pause-release setzt nach Ablauf den Status zurück auf 'offen')
- PROJ-711 Geführte-Eingabe-Audit-Felder (sales_tasks): creation_used_extended_options (BOOLEAN, NOT NULL DEFAULT false — Audit-Flag ob der Toggle 'Weitere Optionen anzeigen' bei der Anlage aktiv war, also eine Goal+Channel-Kombination außerhalb der Standard-Whitelist gewählt wurde), title_source (kategorisch: auto/manual — wurde der Titel automatisch generiert oder vom User editiert), expected_effort_minutes_source (kategorisch: auto/manual — wurde der Aufwand automatisch vorbelegt oder vom User editiert), parent_task_id (UUID, NULL, FK sales_tasks(id) ON DELETE SET NULL — bei Folge-Tasks Referenz auf die abgeschlossene Vorgänger-Task). Diese 4 Felder sind operative Metadaten ohne direkten Personenbezug — sie dokumentieren die Eingabequalität und Folge-Task-Kette für interne Audit- und Adoption-Analyse.
- PROJ-711 Result-Werte erweitert (sales_tasks.result, 21 Werte gesamt): Die bestehenden 12 Werte (kunde_erreicht/kunde_nicht_erreicht/email_gesendet/rueckmeldung_erhalten/termin_vereinbart/entscheidung_vertagt/kunde_prueft_intern/offene_fragen_vorhanden/kein_interesse_mehr/deal_gewonnen/deal_verloren/kein_ergebnis_legacy) werden um 9 neue Werte ergänzt: keine_rueckmeldung_erhalten, mailbox_erreicht, gespraech_gefuehrt, rueckruf_vereinbart, entscheidungsfrist_vereinbart, lead_validiert, lead_ist_spam, lead_unklar_spaeter_pruefen, angebot_versendet. Damit erlauben Result-Listen kontext-spezifische, fachlich passende Ergebnisse (z.B. mailbox_erreicht nur bei Telefon-Tasks). Das Result lead_ist_spam triggert eine Sonderlogik (siehe Spam-Klassifikation unten).
- PROJ-711 Spam-Klassifikation (User-getriggert, keine automatisierte Einzelentscheidung Art. 22 DSGVO): Wählt ein Sales-Mitarbeiter beim Task-Abschluss das Result lead_ist_spam, wird (a) der zugehörige Deal automatisch auf eine Lost-Stage gesetzt (sales_deals.current_stage_id), (b) sales_deals.lost_reason_id zeigt auf einen workspace-spezifischen sales_deal_lost_reasons-Record mit reason='Spam' (per PROJ-711-Migration als Seed pro Workspace angelegt, idempotent), (c) sales_deals.lost_reason_detail wird mit 'auto:spam_classification' markiert, (d) ein History-Event lead_classified_as_spam wird in sales_task_history geschrieben, (e) eine Notification deal_marked_as_spam (neuer Notification-Typ in notifications) wird an Deal-Owner und Workspace-Admin/Manager geschickt. Keine algorithmische Auto-Klassifikation — die Entscheidung trifft immer der Mensch. Re-Open-Pfad (bestehender Deal-Reopen) bleibt unverändert und entfernt lost_reason_id beim Reaktivieren.
- Wiederkehrende Tasks (sales_task_recurrences): Task-Vorlage mit interval_type (daily/weekly/monthly/yearly/custom_days) + interval_value, next_occurrence_date, pause_until. Erzeugt automatisch sales_tasks-Einträge via täglichem pg_cron um 06:00 UTC (proj480-sales-task-recurrences-process)
- Snooze-Historie (sales_task_snooze_history): Unveränderbare Protokollierung jeder Task-Verschiebung mit snoozed_at, snoozed_to und optional reason (Freitext, max 500). Datenbasis für KI-Learning (welche Tasks häufig verschoben, welche Gründe, welche Muster)
- PROJ-646 + PROJ-711 Task-History (sales_task_history): Unveränderbarer Audit-Trail für ALLE Änderungen an sales_tasks-Datensätzen. Pro History-Eintrag: id, task_id (FK auf sales_tasks, CASCADE), workspace_id, deal_id (für Workspace-Scope-Query), event_type (kategorisch, 15 Werte — 7 bestehende plus 8 PROJ-711-Erweiterungen: task_created/task_updated/task_completed/task_overdue/responsible_changed/result_set/follow_up_created/extended_options_used/auto_title_overridden/auto_effort_overridden/auto_bezug_overridden/followup_suggested/followup_accepted/followup_declined/lead_classified_as_spam), field_name (optional, z.B. assigned_user_id/status/result/priority/due_date — welches Feld sich geändert hat), old_value + new_value (JSONB-Snapshot des alten und neuen Werts — kann user_id-References, Status-Enums, Freitext-Ausschnitte enthalten), user_id (FK auf auth.users, ON DELETE SET NULL — wer hat die Änderung ausgelöst, NULL bei system_actor), system_actor (Text, optional — z.B. 'pg_cron:sales-task-pause-release', 'trigger:sales_task_history_trigger' für nicht-User-getriebene Änderungen), created_at. Wird befüllt entweder via DB-Trigger (sales_task_history_trigger bei INSERT/UPDATE auf sales_tasks) ODER explizit aus Backend-Routen (logTaskHistory-Helper bei verantwortlichkeitsrelevanten Events wie responsible_changed). RLS: SELECT für Workspace-Member (history zur Task im eigenen Workspace), keine UPDATE/DELETE (immutable Audit-Log).
- KI-Priorisierung (sales_task_prioritize via Anthropic Haiku 4.5): Input = anonymisierte Task-Metadaten (channel kategorisch, goal kategorisch, due_date, Task-Alter) + anonymisierte Deal-Kontext-Daten (deal_name, stage_name kategorisch, deal_value_estimated_cents-Range, health_score, deal_herkunft kategorisch, kundenkategorie kategorisch, days_since_last_contact). KEIN Task-Titel, KEIN notes-Inhalt, KEINE Namen, KEINE E-Mails werden übermittelt. Output: priority (enum hoch/mittel/niedrig) + reasoning (max 500 Zeichen, deutsch) + factors (Array). Output wird in sales_tasks.priority + priority_source='ki' + ki_priority_reasoning (JSONB) gespeichert. EU AI Act Art. 50: ✦ KI-generiert-Kennzeichnung im Task-UI
- Zuständigkeit: assigned_user_id (NOT NULL seit PROJ-646 — Pflicht-Feld) und created_by (FK auf auth.users, ON DELETE SET NULL — Tasks bleiben bei User-Abgang anonymisiert erhalten, da nur die User-Referenz auf NULL gesetzt wird; sales_task_history-Einträge folgen demselben Pattern für user_id)
- PROJ-865 Abschluss-Bearbeiter (sales_tasks.completed_by, FK auf auth.users, ON DELETE SET NULL): Interner Verweis auf den Mitarbeiter, der die Task abgeschlossen (status='erledigt') oder storniert (status='storniert') hat — analog created_by ein reiner Bearbeiter-Audit-Verweis für Vertriebsnachvollziehbarkeit (wer hat wann was erledigt). NULL solange die Task offen ist. Es gibt bewusst keine separaten cancelled_at/cancelled_by-Spalten: der Status unterscheidet den Fall, completed_at + completed_by decken Abschluss und Storno gemeinsam ab. Der zugehörige due_date-Wechsel wird zusätzlich im sales_task_history-Trail protokolliert (field_name='due_date').
- PROJ-874 Stornierungsfelder (sales_tasks): cancellation_reason (kategorisch: deal_verloren|manuell — warum die Task storniert wurde), cancelled_by (FK auf auth.users, ON DELETE SET NULL), cancelled_at (Timestamp). Werden automatisch bei der Deal-Verloren-Kaskade gesetzt. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an lückenloser Vertriebsdokumentation). Workspace-scoped via deal_id → sales_deals.workspace_id.
- Notifications (entity_type='sales_task' bzw. 'sales_deal'): sales_task_due_today (Cron 07:00 UTC für fällige Tasks heute), sales_task_overdue (Cron 09:00 UTC für überfällige Tasks, mit Duplicate-Guard pro Tag), sales_task_auto_created_from_recurrence (bei automatischer Task-Erzeugung aus Recurrence), sales_task_responsible_changed (PROJ-646: bei jedem Verantwortlichen-Wechsel via PATCH /api/sales-tasks/:id — Empfänger ist NEUER Verantwortlicher, sofern != aktuell handelnder User; Inbox-only, kein E-Mail-Versand standardmäßig, User-Preferences pro Kanal konfigurierbar), deal_marked_as_spam (PROJ-711: bei User-getriggerter Spam-Klassifikation eines Leads via Task-Result lead_ist_spam — Empfänger sind Deal-Owner und alle Workspace-Admins/Manager; Inbox-only, Link auf den als verloren markierten Deal)
- PROJ-1057 „Keine Reaktion nötig“-Dismissals (heute_wichtig_dismissals): Pro-Nutzer-Protokoll, welcher Workspace-Mitarbeiter (user_id, FK auf auth.users, ON DELETE CASCADE) welches „Heute wichtig“-Item (source_type kategorisch: email/reaction/task/nba/…, source_id als Soft-Reference auf das Quell-Item) wann (dismissed_at) und mit welchem konfigurierten Grund (reason_id FK auf heute_wichtig_dismiss_reasons ON DELETE SET NULL, reason_label als Text-Snapshot des Grund-Labels zum Zeitpunkt der Aktion) zurückgestellt hat — optional bis zu einem Datum (snoozed_until; NULL = dauerhaft, sonst erscheint das Item nach Ablauf wieder). Zweck: der Mitarbeiter blendet bewusst Items aus, auf die er nicht reagieren muss. Enthält keine Kunden-Inhalte — nur eine Soft-Reference auf das Quell-Item plus einen Workspace-Konfigurations-Labeltext. RLS: jeder Nutzer sieht und ändert ausschließlich seine eigenen Dismissals (user_id = auth.uid()). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an persönlicher Arbeitsorganisation im Vertrieb).
- PROJ-1057 Konfigurierbare Dismiss-Gründe (heute_wichtig_dismiss_reasons): Workspace-weite Label-Liste (label max 120 Zeichen, position) ohne Personenbezug — von Admins/Managern in den Sales-Einstellungen gepflegt (anlegen/umbenennen/löschen). RLS: Lesen für alle Workspace-Mitglieder, Schreiben nur Admin/Manager.
Sales-Kommunikation & Timeline (PROJ-481)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung/Vertragserfüllung — vertriebliche Kommunikationsdokumentation: E-Mails, Telefonate, Meetings, Notizen) in Verbindung mit Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an strukturierter Kommunikations-Historie für Follow-up und Forecast). KI-Signal-Extraktion: kategorische Output-Felder (kein Volltext-Echo der Kommunikation, keine Zitate). Auftragsverarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC.
- Kommunikations-Stammdaten (sales_communication_log): channel (kategorisch: email/phone/video_meeting/in_person/note), direction (outbound/inbound/internal), subject (max 500 Zeichen), content (Volltext bis 50.000 Zeichen — kann interne Vertriebsnotizen, E-Mail-Inhalte, Call-Notes oder Meeting-Transkripte enthalten), summary (KI- oder manuell, max 2.000 Zeichen), duration_minutes, communicated_at, is_internal_note (boolean: nicht kundensichtbar)
- Beteiligte (participants JSONB): Array { name, email, role: internal|customer } — kann Klartext-E-Mail-Adressen Dritter (z.B. Cc-Empfänger) enthalten, Eingabe durch Vertriebsmitarbeiter
- KI-extrahierte Signale (ai_extracted_signals JSONB via Anthropic Claude Haiku 4.5): pain_points (Array bis 5 kategorische Schlagworte, max 60 Zeichen pro Eintrag), objections (Array bis 5), next_steps (Array bis 5), competitor_mentioned (boolean) — KEINE Volltext-Zitate, nur kategorische Aggregate. Fire-and-forget bei content-INSERT >= 200 Zeichen oder On-Demand-Trigger durch User
- Anhänge (sales_communication_attachments): file_path (Storage-Pfad in Bucket sales-email-attachments — historisch so benannt aus PROJ-686 Phase 2, faktisch der gemeinsame Composer-Bucket für E-Mail-Anhänge UND manuelle Kommunikations-Einträge inkl. Datei-Eintrag PROJ-750; NICHT signierte URL), file_name, mime_type, file_size_bytes — Storage-RLS mit workspace-folder-scoping (foldername[1]=workspace_id, 3 Policies: SELECT/INSERT/DELETE), Cleanup-Cron bei Eintragslöschung sowie synchroner Storage-Cleanup im DELETE-Handler vor DB-CASCADE (PROJ-750, R-455)
- Audit-Felder: created_by (FK auf auth.users), created_at, updated_at — Vertriebs-Nachvollziehbarkeit
- PROJ-603 System-versendete Angebots-Mails (channel='quote_interaction'): Beim Versand eines Angebots über die Inbox-Composer-UI wird ein Eintrag in sales_communication_log mit direction='outbound', channel='quote_interaction', subject + content (HTML-Body der versendeten E-Mail, max 50.000 Zeichen) und participants (To/CC/BCC inkl. Empfänger-E-Mails) angelegt. Sichtbar im Deal-Kommunikations-Tab UND im CRM-Kontakt-Kommunikations-Tab (via deal_id und contact_id). Rechtsgrundlage Art. 6 Abs. 1 lit. b/f DSGVO. Aufbewahrung: identisch zur restlichen sales_communication_log (HGB §257). Backfill bestehender quote_activities-Versand-Records ist NICHT Teil von PROJ-603 — nur neue Versendungen ab Deploy werden geloggt.
- PROJ-751 Manuell hinterlegte E-Mails: User können extern versendete/empfangene Mails (Outlook, private Adresse, Handy-App) als gleichwertigen Communication-Log-Eintrag dokumentieren (channel='email', match_reason='manual_external'). Speicherung in sales_communication_log analog automatisch gesyncten Mails — gleiche Felder (subject, content, participants, communicated_at, is_internal_note), gleiche CASCADE-Lösch-Regeln, gleiche Datenexport-Pflicht (R-241). Bei direction='inbound' wird reply_status='unbeantwortet' + reply_status_source='manual' gesetzt (paired-CHECK). Body wird beim Speichern serverseitig in sicheres <p>-gewrapptes HTML konvertiert (Plaintext-Escape + Newline-zu-<br>) und beim Rendern durch die bestehende sanitizeEmailHtml()-Pipeline geleitet. Kein externer Auftragsverarbeiter beim Speichern — Daten landen direkt in Supabase. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (Vertriebsdokumentation). RLS: Workspace-Member mit Deal-Zugriff dürfen anlegen/lesen, created_by oder admin/manager dürfen editieren, admin only löschen. Workspace-scoped, CASCADE-DELETE bei Deal-/Kontakt-/Workspace-Löschung identisch zu automatischen Mails.
Sales CRM E-Mail Inbox-Sync (PROJ-578)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an strukturierter Vertriebs-Kommunikation: automatische Zuordnung eingehender und ausgehender E-Mails zu CRM-Kontakten und aktiven Deals zur Steigerung der Datenqualität und Vermeidung doppelter Datenpflege). Verarbeitung der E-Mail-Postfach-Daten erfolgt nach expliziter OAuth-Einwilligung des Postfach-Inhabers (Art. 6 Abs. 1 lit. a DSGVO als zusätzliche Rechtsgrundlage). Auftragsverarbeitung gemäß Art. 28 DSGVO mit Google LLC (Gmail-API).
- Postfach-Konfiguration (sales_email_inbox_config): pro Workspace ein verbundenes Gmail-Postfach via user_google_token_id (FK auf user_google_tokens), is_active (boolean), last_sync_at, last_error/last_error_at — keine PBD direkt, sondern Verweise.
- E-Mail-Inhalte (sales_communication_log mit channel='email'): subject (max 500 Zeichen), content (seit PROJ-1145 wird die HTML-Fassung bevorzugt gespeichert, Volltext bis 500.000 Zeichen — kann interne und externe Personenbezüge in Klartext enthalten), participants (JSONB mit from/to/cc — Klartext-E-Mail-Adressen + Namen), communicated_at, gmail_thread_id (RFC-Thread-ID), external_message_id (Gmail-Message-ID — Dedup-Key). PROJ-1145 (DSGVO F-1): Beim Anzeigen einer HTML-Mail im gesandboxten iframe werden EXTERN verlinkte Bilder (<img src="https://…">, inkl. unsichtbarer Tracking-Pixel) standardmäßig NICHT geladen, sondern erst nach explizitem Klick auf „Bilder anzeigen“ (Opt-in, Datenschutz-Standard wie Gmail/Outlook). Dadurch erkennt der Absender das bloße Öffnen der Mail nicht. Eingebettete Bilder aus eigenem Supabase-Storage (cid-Auflösung, Signed-URL) laden sofort. Skripte bleiben generell blockiert (kein allow-scripts). Hinweis: Der serverseitige Mail-Sanitizer (rehype-sanitize) entfernt KEINE 1×1-Pixel — der Tracking-Schutz erfolgt clientseitig über das Opt-in-Blocking im Renderer.
- Anhänge & eingebettete Bilder (sales_communication_attachments + Storage-Bucket sales-email-attachments, seit PROJ-1145): Seit PROJ-1145 werden die Datei-INHALTE der von Kunden mitgeschickten Anhänge UND die eingebetteten Bilder (cid:-Inline-Grafiken, z.B. Signatur-Logos) beim Sync via Gmail messages.attachments.get heruntergeladen und dauerhaft im privaten Bucket sales-email-attachments unter {workspace_id}/synced/{log_id}/{uuid}-{dateiname} gespeichert; pro Anhang eine Zeile in sales_communication_attachments (file_name, file_path, file_size_bytes, mime_type, is_inline, content_id). Hintergrund der Änderung: Anhänge sind für die Vertriebsarbeit am Deal erforderlich (zuvor nur Metadaten in participants.attachments — Datensparsamkeit zugunsten Verarbeitungszweck aufgegeben, Auftraggeber-Entscheidung). Rechtsgrundlage Art. 6 Abs. 1 lit. b/f DSGVO. Auslieferung nur über kurzlebige Signed-URLs (1h) aus dem privaten Bucket. Löschung/Aufbewahrung identisch zu sales_communication_attachments (CASCADE über log_id; synchroner Storage-Cleanup im DELETE-Handler PROJ-750 + Cleanup-Cron für verwaiste synced/-Dateien).
- Match-Metadaten: match_reason (kategorisch: matched/unknown_sender/multiple_active_deals/no_active_deals/manual/domain_only/rejected_system/composer/thread_match/thread_match_override/manual_external/contact_only/contact_person_match/outbound_recipient_match/quote_number_match — PROJ-716 ergänzt thread_match + thread_match_override; PROJ-751 ergänzt manual_external (extern hinterlegte Mail); PROJ-765 ergänzt contact_only (Mail manuell beim Kontakt abgelegt, kein Deal-Bezug); PROJ-1988 ergänzt contact_person_match (Kunde über eine in contact_persons gepflegte Ansprechpartner-Adresse erkannt) und outbound_recipient_match (ausgehende Mail, über den ersten externen Empfänger statt über den Absender aufgelöst); der PROJ-1988-Nachtrag ergänzt quote_number_match (Zuordnung über eine im Betreff erkannte Angebotsnummer im Format AN-JJJJ-NNNNNNN, aufgelöst gegen die Angebote des eigenen Workspace mit Deal-Bezug — greift auch, wenn die Absenderadresse unbekannt oder privat ist)), provider ('gmail'), Sender→Contact→Deal-Score (transient, nicht persistiert). PROJ-1988: Der Adressabgleich prüft zusätzlich zu contacts.email und contacts.additional_emails auch die E-Mail-Adressen gepflegter Ansprechpartner (contact_persons.email → contact_persons.company_id); der Ansprechpartner ist dabei nie selbst Zuordnungsziel, sondern verweist ausschließlich auf seinen Kunden. Dieselbe Adresse bei mehreren Kunden führt bewusst zu keiner automatischen Zuordnung. Der Domain-Rückfall (Kunden-Vorschläge anhand der Firmen-Domain der Absenderadresse; über die Domain allein wird nie automatisch zugeordnet) berücksichtigt seit dem PROJ-1988-Nachtrag zusätzlich die Domains gepflegter Ansprechpartner-Adressen; Freimailer-Domains bleiben dabei weiterhin ausgeschlossen. Die Richtungserkennung (eingehend/ausgehend/intern) erfolgt über die eigene Firmendomain statt über eine einzelne Postfach-Adresse; rein interne Mails (Absender und alle Empfänger auf eigener Domain) werden als direction='internal' geführt bzw. nicht mehr als Kundenkontakt abgelegt. PROJ-765 ergänzt Audit-Spuren assigned_by_user_id (FK auth.users, ON DELETE SET NULL — User der manuell zugeordnet hat; NULL für Auto-Zuordnungen) und assigned_at (Zeitstempel der manuellen Zuordnung).
- Thread-Match-Header (PROJ-716): in_reply_to (Inhalt des In-Reply-To-Headers der eingehenden Mail, max 500 Zeichen, kann eine vom System versendete System-Message-ID enthalten — keine direkten PBD, nur Mail-Routing-Identifier), references (text[] — chronologische Liste der References-Header-Werte, max 500 Zeichen pro Eintrag), is_quote_reply (boolean — markiert Angebotsantworten via Header- oder Recency-Fallback). Zweck: zuverlässige Zuordnung von Kundenantworten zum richtigen Deal ohne LLM-Einsatz.
- Sync-Diagnose-Protokoll (sales_email_sync_log, PROJ-716): Pro Sync-Iteration ein Eintrag mit workspace_id, started_at, ended_at, processed/inserted/skipped/rejected/errors (numerische Counts), status (ok/partial_error/failed) und error_message (max 2.000 Zeichen). KEINE Mail-Inhalte oder Empfänger-Daten enthalten — nur technische Diagnose-Metriken. RLS: nur Admin+Manager des Workspaces. Retention: 30 Tage via pg_cron Job 226 (sales-email-sync-log-cleanup, täglich 05:15 UTC). Zweck: Sichtbarkeit über Sync-Stabilität, Erkennung von Token-Verlusten und automatische Eskalation bei wiederholten Fehlern.
- Anthropic-Übermittlung (zukünftig in Phase 2 wenn KI-Subject-Matching ergänzt wird): Phase 1 = vollständig regelbasiert (Token-Overlap-Score), KEINE externe Übermittlung an LLM-Provider. Falls Phase 2 LLM einführt, wird DATA_PROCESSING-Eintrag erweitert.
- E-Mail-Vorlagen (sales_email_templates, PROJ-686 + PROJ-762): Workspace-spezifische und private Vorlagen mit name (max 100 Zeichen, eindeutig pro Workspace), subject_template (max 250 Zeichen, Fix F-6 PROJ-762) und body_html_template (Rohtext mit optionalen Variablen wie {{contact.first_name}}). PROJ-762 ergänzt 7 Felder: category (Pflicht-Freitext-Kategorie, max 100 Zeichen, z.B. Erstkontakt, Nachfassen), deal_stage_ids (UUID[] — Soft-Reference auf sales_deal_stages, kein FK; gelöschte Stages bleiben als Stub erhalten), tonality (Enum: du|sie|auto), language (z.B. de, en, max 10 Zeichen), is_active (boolean, Default true), internal_note (max 500 Zeichen, nur in Vorlagen-Verwaltung sichtbar), ai_prompt (max 1.000 Zeichen, Steuerungs-Prompt gespeichert — wird erst durch PROJ-764 KI-Personalisierung an Anthropic PBC übermittelt; in PROJ-762 nur Speicherung ohne externe Übermittlung). Keine zwingenden PBD im Vorlagentext, jedoch kann der Nutzer PBD-haltige Inhalte in subject_template/body_html_template/internal_note eintragen. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Vertriebseffizienz). RLS: Sales-Member SELECT (shared + eigene private); INSERT/UPDATE/DELETE nur Admin/Manager (PROJ-762 verstärkt: Member sind Read-only). Workspace-scoped. CASCADE bei Workspace-Löschung. DSGVO-Datenexport (Art. 15/20): alle Felder via Workspace-Datenexport (R-241, Fix F-11 PROJ-762).
- User-E-Mail-Signatur (profiles.email_signature_html, PROJ-686): Optionale HTML-Signatur des eingeloggten Vertriebsmitarbeiters (text, nullable, max 5.000 Zeichen). Kann Name, Kontaktdaten, Unternehmensangaben und externe Bild-URLs enthalten. Wird beim Composer-Versand serverseitig in den E-Mail-Body eingefügt (Priorität vor Workspace-Default).
- Workspace-Standard-Signatur (workspaces.default_email_signature_html, PROJ-686): Optionale workspace-weite Standard-Signatur (text, nullable). Greift wenn der User keine eigene Signatur hinterlegt hat. Admin/Manager-Recht für Schreiben, alle Sales-Member leseberechtigt (implizit via Workspace-Zugehörigkeit).
- Composer-Anhänge Staging (Storage-Bucket sales-email-attachments, PROJ-686): Temporäre Anhänge die der User vor dem Versand hochlädt (max 25 MB gesamt, max 10 Dateien). Pfad-Schema: {workspace_id}/composer-staging/{user_id}/{uuid}-{filename}. Retention Staging-Files: 7 Tage — nicht-versendete Drafts werden automatisch durch pg_cron-Job 225 (sales-email-attachments-cleanup, täglich 04:45 UTC) gelöscht, sofern sie nicht in sales_communication_attachments referenziert sind. Gesendete Anhänge: Metadaten (file_path, file_name, mime_type, size_bytes) werden in sales_communication_attachments referenziert; der Datei-Blob verbleibt im Storage bis Kontakt-/Deal-/Workspace-Löschung.
- Bearbeitungs-Status eingehender Kunden-Mails (sales_communication_log.reply_status*, PROJ-733): Workflow-Metadaten für eingehende E-Mails — reply_status (Enum: unbeantwortet|beantwortet|folge_task_erstellt|erledigt, Default unbeantwortet bei Inbound-Email), reply_status_source (auto|manual: ob Status durch System-Auto-Detection oder manuellen User-Override gesetzt), reply_status_updated_at (Timestamp des letzten Wechsels), reply_status_updated_by (FK auth.users — User, der den Wechsel ausgelöst hat; NULL bei Auto-Detection ohne klaren Actor). Keine neuen personenbezogenen Inhalte — nur abgeleitete Workflow-Klassifikation auf bestehenden Mail-Inhalten. Zweck: zuverlässige Steuerung offener Kundenantworten via 'Heute wichtig' (Bereich 1..168 Stunden Schwellenwert, Workspace-konfigurierbar). Auto-Detection-Trigger: bei Outbound-Mail im selben Gmail-Thread (siehe applyAutoReplyStatusOnOutbound) und bei Folge-Task-Anlage mit related_entity_type='kommunikation' (applyAutoTaskCreatedStatus). Manueller Override gewinnt dauerhaft — Auto-Detection überschreibt nie eine manuelle Setzung.
- Audit-Log für Status-Wechsel (sales_communication_reply_status_log, PROJ-733): Append-only-Tabelle mit einer Zeile pro reply_status-Wechsel (auto oder manuell). Felder: communication_log_id (FK auf sales_communication_log mit CASCADE), from_status, to_status, source (auto|manual), actor (FK auth.users, ON DELETE SET NULL — Audit-Eintrag bleibt revisionssicher), reason (optional, max 500 Zeichen), created_at. Keine direkten Mail-Inhalte. RLS: SELECT für Workspace-Mitglieder, kein INSERT/UPDATE/DELETE für nicht-Service-Role (Append-only-Semantik). Zweck: Nachvollziehbarkeit von Workflow-Wechseln gemäß Art. 5 Abs. 1 lit. f / Art. 32 DSGVO (Integrität der Verarbeitung).
Automatische CRM-Zuordnung von Postfach-Mails (PROJ-1134 Teil A)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an strukturierter Vertriebs-Kommunikation). Beschäftigtenbezug: Der Cron `postbox-crm-assign` verarbeitet Kopfdaten und Vorschautexte aus den dienstlichen Gmail-Postfächern ALLER Mitarbeitenden, die ihr Konto mit `sync_gmail=true` angebunden haben (Stand 07.08.2026: 20 Konten) — nicht nur aus dem einen zentralen Sales-Postfach. Für die Verarbeitung von Beschäftigtendaten ist zusätzlich § 26 BDSG einschlägig; die Betroffenen sind nach Art. 13 DSGVO zu informieren, eine Betriebsvereinbarung ist zu prüfen. Datensparsamkeit als Positivliste umgesetzt (kein Ausschlussverfahren): Abgelegt wird AUSSCHLIESSLICH, wenn die Gegenstelle einem bekannten CRM-Kontakt zugeordnet werden kann — Mails ohne Kontakt-Treffer werden übersprungen und nicht gespeichert. Rein interne Mails (Absender und alle Empfänger auf eigener Firmendomain) werden seit PROJ-1988 als solche erkannt und nicht als Kundenkontakt abgelegt.
- Gelesene Quelle (gmail_messages_cache, befüllt von gmail-inbox-sync): gmail_message_id, thread_id, subject, from_email, from_name, to_email, snippet (Vorschautext), received_at. Der Cron liest ausschließlich aus diesem bereits bestehenden Anzeige-Cache und ruft die Gmail-API nicht selbst auf.
- Erzeugte Zuordnung (sales_communication_log, channel='email'): workspace_id, contact_id, deal_id, direction (inbound/outbound/internal), subject (max 500 Zeichen), content (Vorschautext aus dem Cache, nicht der Volltext), participants (from/to), external_message_id, gmail_thread_id, match_reason, created_by (Token-Eigentümer:in).
- Zuordnungs-Grundlage: Abgleich der Gegenstellen-Adresse gegen contacts.email, contacts.additional_emails und — seit PROJ-1988 — contact_persons.email (der Ansprechpartner ist dabei nie selbst Zuordnungsziel, sondern verweist auf seinen Kunden). Seit PROJ-1988 wird die Richtung über die eigene Firmendomain bestimmt; bei ausgehenden Mails wird der erste externe Empfänger statt des Absenders ausgewertet. Wirkung der PROJ-1988-Erweiterung im Bestand: 413 zwischengespeicherte Mails aus 18 der 20 Postfächer (51 unterschiedliche Absender) treffen einen Kunden erstmals über eine Ansprechpartner-Adresse.
- Fortschritts-Marker: user_google_tokens.last_crm_match_at je Konto. Beim ersten Lauf eines Kontos wird ausschließlich der Marker gesetzt — es findet KEIN rückwirkender Import älterer Mails statt.
- Keine Übermittlung an Dritte, keine KI-Verarbeitung, keine Profilbildung, keine automatisierte Entscheidung im Sinne des Art. 22 DSGVO.
Sales-Reporting & Sales Cockpit (PROJ-485)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an interner Vertriebs-/Management-Reporting auf aggregierten Daten — keine direkten Nutzer-Aktionen, nur statistische Auswertungen aus bereits erhobenen Sales-Daten gemäß PROJ-479/480/481/487). Reporting verarbeitet ausschließlich Daten, die der Workspace bereits rechtmäßig auf Basis Art. 6 Abs. 1 lit. b/f erhoben hat. Keine zusätzlichen Datenkategorien.
- Funnel-Snapshot (sales_funnel_snapshot): tägliches Aggregat pro (Workspace × Pipeline-Kind × Stage-Type) mit Stage-Counts, Total-Values (Cents), Avg-Score (0-100). Keine direkten Personenbezüge — alle Werte sind Aggregations-Counts/Sums abgeleitet aus bestehenden sales_deals-Daten.
- Aggregierte Reports (transient, nicht persistiert): Funnel-Konversionsraten pro Stage, Verlustanalyse gruppiert nach Stage/Reason/Industry/Leadquelle/Vertriebler, Forecast-Berechnungen für Monat/Quartal/Jahr (Dealwert × phase_factor × health_score), Sales-Velocity (Durchschnittstage von Deal-Erstellung bis Won), Lead-Source-Analyse, Industry-Analyse, Top-Sellers-Ranking. Aggregate können einzelne Vertriebler-IDs (assigned_user_id) und Display-Namen enthalten (Performance-Reporting), unterliegen aber Workspace-Membership-Berechtigungsprüfung.
- Dashboard-Metriken (transient): Counts (Deals total/won/lost/active), Forecast-Cents aktueller Monat, Top-5-Sellers (user_id + display_name + won_count + total_value_cents), Hot-Deals-Count (health_score >= 76), Overdue-Tasks-Count, Silent-Deals-Count (aktive Deals ohne outbound communication ≥14 Tage), Top-Industries, Top-Lead-Sources. Berechnung pro API-Call aus aktuellen sales_deals/sales_tasks/sales_communication_log — keine separate Datenpersistenz.
ABM → Sales-CRM-Übergabe (PROJ-490)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Brücke zwischen anonymer Website-Besucher-Erkennung im ABM-Dashboard und konkreten Sales-Deals; Workflow-Tracking Verstehen → Warmup → Kontakt → Konvertiert). KI-Intention-Klassifizierung anonymisiert (nur Domain + URL-Pfade, keine PII) gemäß Art. 28 DSGVO mit Anthropic PBC.
- Handoff-Stammdaten (abm_to_deal_handoff): abm_domain (Firmen-Domain — kein direkter Personenbezug, B2B), company_name (öffentlich), intention_class (kategorisch enum), intention_signals (JSONB mit URL-Pfad-Aggregaten ohne Query-Parameter)
- Empfehlungen: recommended_contact_role (kategorisch wie 'HR/Personalleitung', 'Marketing'), ki_outreach_text (max 2000 Zeichen, KI-generierter Vorschlag — wird durch Vertriebler vor Versand reviewt)
- Warmup-Workflow: warmup_status (kategorisch), warmup_started_at, warmup_completed_at, contact_initiated_at
- Verknüpfungen: deal_id (FK auf sales_deals nach Konvertierung), contact_id (FK auf contacts nach Erstkontakt), created_by (User-Tracking)
- Vertriebs-Notizen (notes, max 5000 Zeichen): interne Vertriebsperspektive, kann interne PII enthalten
- Anthropic-Übermittlung (abm_intention_classification): nur Domain-Name + Liste besuchter URL-Pfade (ohne Query-Parameter) + Verweildauer-Aggregate. KEINE Personennamen, E-Mails, IP-Adressen, Session-Hashes
Sales Bestandskunden-Lead-Mining (PROJ-484)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — automatisierte Erkennung von Vertriebs-Anlässen bei Bestandskunden basierend auf bereits vorhandenen Aktivitäts-Mustern und Vertragsdaten; Effizienz im Cross-Sell und Reaktivierungs-Workflow).
- Lead-Mining-Signale (sales_lead_mining_signals): contact_id (FK auf bestehenden CRM-Kontakt), signal_type (kategorisch enum: long_silence/contract_ending_soon/cross_sell_opportunity/up_sell_opportunity/reactivation_candidate/churn_risk/expansion_signal), signal_strength (weak/medium/strong), description (max 1000 Zeichen — generierte Beschreibung des Anlasses, kein Klartext-Communication-Inhalt), metadata (JSONB mit Aggregat-Werten wie days_since_last_contact, last_deal_value, related_contact_id), status (open/converted_to_deal/dismissed/snoozed), Verknüpfung converted_deal_id zu sales_deals nach Konvertierung
- Subscription-Konfigurationen (sales_lead_mining_subscriptions): pro Workspace + signal_type aktivierbare Detection-Regeln mit threshold_config (JSONB mit Schwellwerten wie days_silence_min), notification_priority (low/medium/high)
- Detection-Quellen: aggregierte Daten aus sales_communication_log (last_activity-Aggregat), sales_deals (last_won_at, total_value), contacts (Workspace-Membership) — alles aus bestehenden DSGVO-konformen Tabellen, keine zusätzliche Datenerhebung
- Bearbeiter-Tracking: handled_by (auth.users → SET NULL bei User-Löschung), handled_at, dismissal_reason (max 500 Zeichen, interne Begründung)
Sales KI-Brain & Daily Next Best Action (PROJ-486)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — KI-priorisierte Tagesempfehlungen + Coaching-Feedback für Vertriebsmitarbeiter zur Steigerung der Verkaufseffektivität). KI-Coaching-Verarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC.
- NBA-Recommendations (sales_nba_recommendations): pro Vertriebler täglich bis zu 10 priorisierte Empfehlungen — recommendation_type (kategorisch enum: call_customer/reactivate_silent_contact/close_deal_now/follow_up_quote/check_stale_deal/address_at_risk_deal/cross_sell_opportunity/review_won_deal/review_lost_deal), title (max 200 Zeichen — generierte Beschreibung), description (max 1000 Zeichen), ki_reasoning (max 500 Zeichen — regelbasierte Begründung), entity_type/entity_id (FK auf deals/contacts/tasks/lead_mining_signals), status, metadata (Aggregat-Werte wie deal_value_cents, score, days_silent)
- Coaching-Feedback (sales_coaching_feedback): KI-generierte Stichpunkte und Verbesserungsvorschläge nach Won/Lost-Deals oder Communication-Events — deal_id (FK), communication_id (FK), coaching_trigger (kategorisch), feedback_text (max 2000 Zeichen Deutsch), key_observations (max 5 Stichpunkte), improvement_suggestions (max 5 Stichpunkte), ki_model_used (Modell-Name)
- Anthropic-Übermittlung (sales_coaching_feedback): kategorische Deal-Aggregate — Dealname (intern, kein Endkunden-Personenbezug — referenziert Workspace-Begriff), stage_type (kategorisch), deal_value_cents, deal_herkunft (kategorisch), customer_industry (kategorisch optional), customer_size_range (kategorisch optional), total_communications_count, days_in_pipeline, ai_extracted_signals (kategorische Aggregate aus PROJ-481 Signal-Extraction). KEINE Volltext-Kommunikationsinhalte, KEINE Endkunden-Personennamen, KEINE E-Mails, KEINE Telefonnummern.
- Daily-NBA-Generator (Phase 1 vollständig regelbasiert): Pure-Function buildNbaCandidates() mit 7 Heuristiken (close_deal_now, check_stale_deal, address_at_risk_deal, follow_up_quote, reactivate_silent_contact, cross_sell_opportunity, review_won/lost_deal). Keine externe Datenübermittlung, keine LLM in Phase 1.
Sales Call-Maske & Gesprächsführung (PROJ-482 + PROJ-649)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — KI-gestützte Vorbereitung und Nachbereitung von Vertriebsgesprächen zur Steigerung der Verkaufseffektivität und Dokumentationsqualität; strukturierte Erfassung qualitativer Vertriebssignale als Grundlage für Deal-Bewertung und Forecast). KI-Briefing- und Summary-Verarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC. PROJ-649 Phase 1: Pre-Call-Briefing wird als rein datenbankseitige Aggregation umgesetzt — KEIN LLM-Call.
- Call-Sessions (sales_call_sessions): pro Vertriebsgespräch ein Eintrag mit deal_id (FK auf sales_deals, optional), contact_id (FK auf contacts, Pflicht), communication_log_id (FK auf sales_communication_log, optional), call_type (kategorisch enum: erstgespraech/angebotsgespraech/nachfass/reaktivierung/bestandsentwicklung/cross_sell/up_sell/strategie), channel (phone/video/in_person), scheduled_at, started_at, ended_at, duration_seconds, status (PROJ-649: 5 Werte — planned/completed/postponed/cancelled/no_show_customer), postponed_to (TIMESTAMPTZ, NULL-fähig — neues Datum bei Verschiebung), evaluation_draft (JSONB, NULL-fähig — Zwischenstand offener Auswertungsdialoge, kann Pflichtfelder wie Budgethöhe enthalten und wird beim Final-Save geleert).
- Pre-Call-Briefing (pre_call_briefing JSONB, max ~5000 Zeichen): KI-generierte Agenda + offene Themen + Fragen-Vorschläge + Warnsignale (Deutsch). pre_call_checklist (JSONB-Array, max 20 Punkte): manuelle Checkboxen des Vertrieblers (Unternehmen vorgestellt, Vorgehen erklärt etc.).
- Post-Call-Summary (post_call_summary, max 5000 Zeichen): KI-generierte Zusammenfassung des Gesprächs. talking_points (TEXT[], max 50 Einträge à 2000 Zeichen): Vertriebler-Notizen während des Gesprächs (kann interne PII enthalten — vom eingeloggten Vertriebler selbst erstellt). pain_points_extracted, objections_extracted, next_steps_extracted, decision_makers_mentioned (TEXT[]): KI-extrahierte Aggregate aus Summary. new_score_after_call (0–100): Snapshot der Health-Score-Anpassung.
- Anthropic-Übermittlung Pre-Call-Briefing (sales_call_briefing): kategorische Aggregate — Gesprächstyp, Branche, Unternehmensgröße-Bereich, Deal-Wert-Bereich, Health-Score, Pipeline-Tage, letzte 5 Communication-Typen mit days_ago, aggregierte Pain-Points/Einwände/NextSteps aus PROJ-481-Signal-Extraction. KEINE Endkunden-Personennamen, KEINE E-Mails, KEINE Telefonnummern, KEINE Volltext-Kommunikationsinhalte.
- Anthropic-Übermittlung Post-Call-Summary (sales_call_summary): OPTIONAL Live-Transkript-Volltext (transcript_text, max 50.000 Zeichen). Wenn der Vertriebler ein Transkript explizit hochlädt/übergibt, wird es transient an Anthropic gesendet. Das Transkript KANN Endkunden-PII enthalten (Namen, Telefonnummern, gesprochene E-Mail-Adressen). Die Übermittlung erfolgt explizit auf Initiative des Vertrieblers. Alternative: nur talking_points (vom Vertriebler selbst notiert) ohne Transkript — dann KEIN externes Endkunden-PII. Zusätzlich kategorischer Kontext: Gesprächstyp, Branche.
- PROJ-649 Strukturierte Gesprächsauswertung (sales_call_evaluations, 1:1 zu sales_call_sessions): Pro abgeschlossenem Gespräch genau ein Eintrag mit evaluation_type (spiegelt call_type zum Auswertungszeitpunkt, kategorisch). Erstgespräch-Felder: bedarf_erkannt (Boolean), budget_vorhanden (ja/nein/unklar), budget_hoehe_eur (Integer, NULL wenn budget_vorhanden!=ja — kann konkrete EUR-Beträge enthalten und ist damit B2B-Vertriebssensitiv), entscheider_bekannt + entscheider_im_gespraech (Boolean), zeitrahmen_bekannt (Boolean), erwarteter_projektstart (Date, optional), angebot_gewuenscht (Boolean), allgemeines_interesse (niedrig/mittel/hoch). Angebotsgespräch-Felder: angebot_verstanden (Boolean), positive_reaktion (niedrig/mittel/hoch), preisvorwand_vorhanden + kunde_prueft_intern + wettbewerber_im_rennen + entscheidung_direkt_moeglich (Boolean), erwartetes_closing + entscheidung_erwartet_bis (Date), abschlusschance (niedrig/mittel/hoch). Gemeinsam: notizen (Freitext, max 10.000 Zeichen — KANN Endkunden-PII wie Namen einzelner Ansprechpartner, gehörte Aussagen, Konkurrenten-Hinweise enthalten; nur intern für Vertrieb sichtbar), ergebnis_zusammenfassung (max 2.000 Zeichen, optional), follow_up_task_id (FK auf sales_tasks — Pflicht-Folge-Task), closed_via_deal_outcome (won/lost — alternativ zur Folge-Task). created_by (FK auf auth.users). Workspace-scoped via workspace_id, CASCADE-DELETE bei Workspace-/Session-/Deal-/Contact-Löschung. Kein KI-Provider — Auswertung wird manuell durch den Vertriebler ausgefüllt.
- PROJ-649 Audit-Trail (sales_call_session_history, append-only): Pro Statuswechsel und Auswertungs-Operation ein Eintrag mit event_type (status_changed/evaluation_created/evaluation_updated/postponed/follow_up_task_created/deal_outcome_set), event_data (JSONB mit strukturierten Kontextdaten — z.B. {from, to} bei Statuswechsel, {evaluation_id, evaluation_type} bei Auswertung; keine Volltext-Notizen, nur Event-Fakten), actor_user_id (FK auf auth.users mit ON DELETE SET NULL — anonymisierter Audit-Eintrag bleibt bestehen). Inserts ausschließlich via SECURITY-DEFINER-Function log_sales_call_session_event — keine direkten INSERTs aus User-Sessions möglich (unveränderbares Vertriebs-Audit). Workspace-scoped, CASCADE bei Workspace-/Session-Löschung.
- PROJ-649 View sales_deals_with_last_evaluation (security_invoker): LATERAL-Join der zuletzt erstellten Auswertung an jeden Deal. Liefert last_evaluation_*-Felder als read-only Ableitung für die Deal-Übersicht. Keine eigene Persistenz — nur Lese-Aggregation aus sales_deals + sales_call_evaluations.
- Phase 1 NICHT enthalten: Live-Transkript-Streaming (kommt in Phase 2 mit Telefonie-Integration), Live-Side-Panel-UI (Phase 3), kontinuierliches Coaching während des Calls (PROJ-486 Trigger='communication_analyzed' deckt das ab), KI-Bewertung der Auswertungs-Felder (Auswertung erfolgt in Phase 1 ausschließlich manuell durch den Vertriebler).
- PROJ-732 Stammdaten-Korrekturen an Sales-Call-Sessions (contact_id, deal_id, scheduled_at, started_at, ended_at, call_type, channel) werden zusätzlich im Audit-Trail Gesprächs-Stammdaten-Edits (siehe eigenen DATA_PROCESSING-Eintrag) festgehalten — alt/neu-Werte, Editierender, Zeitpunkt. Bei Kontakt-Wechsel wird parallel ein Activity-Log-Eintrag am alten und neuen CRM-Kontakt erzeugt.
- PROJ-749 Interne Team-Gespräche (sales_call_sessions mit call_type='intern'): Workspace-interne Termine ohne CRM-Kontakt-Bezug — internal_title (max. 200 Zeichen, Pflichtfeld nur bei intern, ersetzt den Kontakt-Bezug als Identifikator), contact_id IMMER NULL (Partial-CHECK), deal_id IMMER NULL. Reduzierter Status-Set planned/completed/cancelled (kein postponed/no_show_customer — semantisch nicht anwendbar). KEIN KI-Pre-Call-Briefing, KEINE strukturierte Auswertung (Endpoint antwortet 422 not_applicable_for_internal — Defense-in-Depth). Post-Call-Notiz (post_call_summary) und Talking-Points bleiben für beide Welten nutzbar.
- PROJ-749 Teilnehmer-Junction (sales_call_internal_participants, n:m): Pro interne Session 1..N Einträge mit call_session_id (FK auf sales_call_sessions ON DELETE CASCADE), user_id (FK auf auth.users ON DELETE CASCADE), workspace_id (FK auf workspaces ON DELETE CASCADE), created_at. UNIQUE (call_session_id, user_id). FK-Covering-Indexes auf alle drei FK-Spalten (R-510). Der Owner (sales_call_sessions.user_id) ist IMMER in der Teilnehmer-Liste enthalten — Backend mergt ihn beim Create automatisch ein, PATCH lehnt Owner-Removal ab (owner_must_be_participant). Workspace-Membership aller Teilnehmer wird pre-Insert geprüft (participant_not_in_workspace bei fremden User-IDs). RLS: admin+manager dürfen alle Junction-Zeilen im Workspace lesen, member dürfen Zeilen mit user_id=auth.uid() lesen — und sehen dadurch über die erweiterte Eltern-SELECT-Policy auch die zugehörigen internen Sessions. Insert auf Junction: admin+manager oder Owner-self. Update/Delete: admin+manager. Workspace-Isolation doppelt (RLS + explizites .eq workspace_id).
Audit-Trail Gesprächs-Stammdaten-Edits (PROJ-732)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an revisionssicherer Datenkorrektur — Mitarbeitende sollen Stammdaten von Gesprächen (Meetings, Sales-Calls, Telefonate) nachträglich korrigieren können, ohne dass die Korrektur-Historie verloren geht; Plattform-Admins können Korrekturen nachvollziehen).
- PROJ-732 Gesprächs-Stammdaten-Edits (activity_log mit entity_type='meeting'|'sales_call'|'call_log'): Pro Stammdaten-Änderung an einem Gespräch wird ein Eintrag in der bestehenden, polymorphen activity_log-Tabelle geschrieben. Gespeicherte Felder: workspace_id, entity_type (kategorisch: meeting/sales_call/call_log — Enum comm_entity_type wurde in der PROJ-732-Migration um diese drei Werte erweitert), entity_id (UUID des geänderten Gesprächs), actor_id (User-ID des editierenden Mitarbeiters), event_type='stammdaten_edited', metadata JSONB ({changes: {feld: {old, new, old_label?, new_label?}}, change_reason?: Text max 500 Zeichen}), created_at. Die metadata.changes enthält den alten und neuen Wert pro geändertem Feld; bei UUID-Feldern (contact_id, deal_id, project_id) wird zusätzlich der aufgelöste Anzeigename als old_label/new_label gespeichert, damit die Historie auch nach Kontakt-/Deal-/Projekt-Löschung lesbar bleibt. Append-only — keine UPDATE/DELETE-Operationen für Endnutzer.
- PROJ-732 Kontakt-Wechsel-Activity-Einträge (activity_log mit entity_type='contact'): Wird bei einer Stammdaten-Änderung der zugeordnete Kontakt eines Gesprächs gewechselt, werden zusätzlich 0–2 Activity-Log-Einträge am alten und/oder neuen Kontakt geschrieben: event_type='conversation_unlinked' am alten Kontakt + event_type='conversation_linked' am neuen Kontakt. metadata enthält conversation_type (meeting/sales_call/call_log), conversation_id und ein optionales lesbares Label (z.B. Telefonat 14:32, Sales-Call mit Kunde XY, Quartalsmeeting). Diese Einträge erscheinen in der Kommunikationshistorie am jeweiligen Kontakt, damit ersichtlich ist, wann ein Gespräch zugeordnet oder entfernt wurde.
- Sichtbarkeit: Alle Workspace-Mitglieder mit Lesezugriff auf das jeweilige Gespräch können den Audit-Trail im Edit-Dialog einsehen (letzte 10 Einträge). Der Read-Endpoint GET /api/conversation-history/:type/:id setzt Workspace-Mitgliedschaft + Workspace-Type 'agency' voraus, prüft die Existenz des Gesprächs im aktiven Workspace, aber erzwingt keinen zusätzlichen Owner-/Rollen-Filter (read-only Audit-Daten ohne hochsensible Inhalte — Actor-Display-Name + alt/neu-Werte + Zeitstempel). Schreib-Operationen am Audit-Trail sind über RLS technisch ausgeschlossen (append-only).
- Berechtigung: Edits werden nur in Agentur-Workspaces (workspaces.type='agency') zugelassen — Client-Portale erhalten HTTP 403. Pro Edit-Pfad gilt zusätzlich Owner-OR-Admin/Manager-Check (siehe Spec PROJ-732 AC-G5).
Sales Closing Engine & Forecast (PROJ-483)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — strukturiertes Closing-Tracking + Forecast-Aggregation für Vertriebssteuerung). Phase 1B aktiv: Closing-Score-Engine regelbasiert; KI-Followup-Generator über Anthropic PBC (Auftragsverarbeitung gemäß Art. 28 DSGVO, siehe PROCESSORS-Eintrag).
- Closing-Workflows (sales_closing_workflows): pro Deal — closing_score (0-100), closing_label (kategorisch enum), forecast_probability/forecast_value_cents, manual_forecast_override (User-Override), next_follow_up_recommended_at + channel (call/email), detected_objections/buying_signals (kategorische Aggregate aus PROJ-481-Signal-Extraction), state_class (heiss/offen/funkstille/preisvorwand/...). Keine Endkunden-PII direkt in Closing-Workflow-Tabelle.
- Followup-Drafts (sales_followup_drafts): pro Deal — Subject (max 200), Body-Text (max 10.000 Zeichen, kann interne Vertriebs-Sprache und ggf. Endkunden-Anrede enthalten), Tone (kategorisch), Status (draft/sent/dismissed/edited_and_sent), Sent-Timestamp, Communication-Log-Referenz nach Versand. ki_reasoning (max 500 Zeichen) dokumentiert die Begründung des KI-Vorschlags.
- Closing-Score-Engine: regelbasierte Pure-Function ohne externe API-Calls. Aggregiert aus deal.health_score (PROJ-487), Quote-Activity (last_opened_at, open_count), Communication-Aggregate (objections, buying_signals, customer_replied_recently). Täglicher Cron (Mo-Fr 04:00 UTC) recomputed alle aktiven Deals + sendet Notifications bei state_class-Wechsel auf 'heiss' oder bei Deal-Stagnation > 14 Tage.
- Anthropic-Übermittlung Followup-Generator (sales_followup_draft): On-Demand-Call bei expliziter User-Anforderung über POST /api/sales-followup/drafts. Übermittelt werden ausschließlich kategorische Aggregate — deal_name (intern, Workspace-Begriff), draft_type (kategorisch enum), tone (kategorisch), contact_industry (kategorisch optional), detected_pain_points + detected_objections (max 3 je, aggregiert aus sales_communication_log.ai_extracted_signals), days_since_last_contact, optional last_communication_summary (max 1000 Zeichen — kann PII enthalten wenn vom User selbst übergeben). KEINE Endkunden-Personennamen, KEINE E-Mails, KEINE Telefonnummern direkt. Bei Anthropic-Fehler graceful Fallback auf Manual-Entwurf ohne LLM-Call.
Sales Referenz-PDF-Creator (PROJ-489)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — strukturierte Referenz-Datenbank für Vertrieb mit personalisierten Portfolios). Kundenstimmen werden nur mit ausdrücklicher Zustimmung der zitierten Person hinterlegt. KI-Empfehlungs- und Text-Generierung gemäß Art. 28 DSGVO mit Anthropic PBC.
- Referenz-Datenbank (sales_references): Projektname, Kundenname (Workspace-interne Geschäftsdaten — Marketing/Kreation pflegt), Branche, Größenklasse, Region, Service-Kategorien, Story-Felder (Ausgangslage/Zielsetzung/Lösung max je 5.000 Zeichen), Ergebnisse (KPI-Aggregate JSONB), Kundenstimme (max 1.000 Zeichen) + Autor + Position (mit Zustimmung), Tags, Designstil, Screenshots-URLs, project_date.
- Portfolio-Datensätze (sales_portfolios): pro Deal erstellte Portfolios mit Empfänger-Name + E-Mail (Endkunden-PII), portfolio_type (kategorisch), title, intro_text/closing_text (KI-personalisiert, max 5.000 Zeichen je), selected_reference_ids, sent_at, sent_to (Array von E-Mail-Adressen), Communication-Log-Referenz nach Versand, pdf_storage_path + pdf_generated_at + pdf_template_version (Phase 3 — generierte PDF-Datei im Storage-Bucket), resend_email_id + email_opened_at + email_open_count (Phase 4 — E-Mail-Versand- und Open-Tracking via Resend).
- Portfolio-PDF-Files (Storage-Bucket sales-portfolios, privat): Pro Portfolio gerenderte PDFs enthalten Empfänger-Name, Empfänger-E-Mail (sichtbar im PDF), Workspace-Branding, ausgewählte Referenz-Cases mit Kundenstimmen + Autoren-Namen + Featured-Images. Zugriff nur mit Sales-Read-Access (vertrieb/gf/marketing_intern) via 1-Stunden Signed-URL. Pfad: <workspace_id>/<portfolio_id>/<ISO_timestamp>.pdf.
- Resend-Übermittlung E-Mail-Versand Phase 4 (Resend, Inc., USA): Empfänger-E-Mail-Adresse, Empfänger-Name (im E-Mail-Body sichtbar), Reply-To-Adresse des Vertrieblers, Betreff, HTML- + Text-Body, PDF-Anhang (siehe Portfolio-PDF). Resend speichert Message-ID + Open-/Click-Events bis zu 30 Tage zur Zustellüberwachung. Standardvertragsklauseln (SCC) liegen mit Resend Inc. vor. Kein Tracking-Pixel-Embed in den E-Mails — Open-Tracking erfolgt nur über Resend's natives Webhook-System ohne zusätzliche Browser-Speicherung beim Empfänger.
- Anthropic-Übermittlung KI-Reference-Recommender (sales_reference_recommendation): kategorische Aggregate aus Deal-Kontext (industry, company_size_range, region, service_category) + anonymisierte Referenz-Liste (project_name, industry, services). KEINE Empfänger-E-Mail, KEIN customer_name als Input.
- Anthropic-Übermittlung KI-Portfolio-Text (sales_portfolio_text): kategorische Aggregate (Workspace-internes customer_company_name, industry, deal_service_category, detected_pain_points), optional recipient_name (B2B-Kontakt — Workspace-Admin entscheidet ob übergeben). KEINE E-Mail, KEINE Telefonnummer. UI/UX-Präsentation Zieltext (sales_uiux_goal_text, PROJ-1341, Claude Haiku 4.5 — generiert aus den vorausgewählten Briefing-Zielen (briefing_goals als Schlagwort-Liste), der Entwurfsart (briefing_type) und dem Workspace-internen Kundennamen einen 3–6-Sätze-Fließtext für Folie 2 der Kundenpräsentation; transient an Anthropic, kein Training, Ergebnis persistiert in uiux_presentations.ai_goal_text; KEINE E-Mail, KEINE Telefonnummer, keine personenbezogene Bewertung).
Sales Deal Health Score Engine (PROJ-487)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — automatisierte Bewertung der Erfolgswahrscheinlichkeit von Vertriebs-Deals für effiziente Vertriebssteuerung). Vollständig regelbasierte Scoring-Engine — keine externe Datenübermittlung, keine KI-Auftragsverarbeiter.
- Score-Snapshots (sales_deal_score_history): pro Deal historischer Audit-Trail mit score (0-100), recomputed_at, breakdown_json (Aggregat-Werte pro Score-Faktor wie last_activity_days_ago, days_in_stage, communication_count, customer_replied_recently). Immutable Audit-Tabelle.
- Score-Adjustments: sales_deals.health_score (aktueller Wert), sales_deals.manual_score_adjustment (User-Override ±10/±5), sales_deals.last_score_recomputed_at.
- Berechnungsquellen: sales_deals.last_activity_at, sales_deals.created_at, sales_communication_log.created_at + direction (aggregiert), sales_tasks.completed_at — alles Workspace-interne Daten ohne externe Auftragsverarbeiter.
Sales CRM Rechte & Rollen (PROJ-488)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — granulare Sales-Rollen-Trennung zwischen Vertrieb / Geschäftsführung / Marketing-Intern für Datenschutz interner Vertriebsdaten). Workspace-interne Berechtigungssteuerung — keine externen Auftragsverarbeiter.
- workspace_members.sales_role (TEXT enum: vertrieb/gf/marketing_intern oder NULL für Default-Mapping aus workspace_role) — pro Workspace-Mitglied gespeichert.
- Datenbank-Helper-Functions: get_effective_sales_role, has_sales_read_access, has_sales_full_access — keine Datenpersistenz, nur Berechnungen.
- Internal-Notes-Markierung: sales_communication_log.is_internal_note (BOOLEAN, Default false), sales_deals.internal_notes (TEXT, optional, Workspace-interne Vertriebsnotizen — kann Endkunden-PII via Vertriebler-Notes enthalten, RLS-geschützt vor Marketing-Intern).
- Audit-Notification: sales_role_assigned (Inbox-Notification an betroffenen User mit kategorischer role_label).
Terminbuchungen-Modul (Calendly- & Google-Kalender-Integration) (PROJ-766, PROJ-1024, PROJ-1355, PROJ-1370)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — automatisierte CRM-Pflege im Rahmen der Kundenakquise: eingehende Calendly-Terminbuchungen sowie keyword-erkannte Google-Kalender-Termine werden automatisch CRM-Kontakten, Kunden und Deals zugeordnet und als Vertriebsgespräche dokumentiert). Calendly LLC fungiert als unabhaengiger Datenuebermittler — wir empfangen die Buchungsdaten via Webhook nach Zustimmung des Buchenden zur Calendly-Datenschutzerklaerung. Google-Kalender-Termine werden ueber die bereits per OAuth angebundene Google Calendar API v3 gelesen (Verantwortlicher fuer den Kalender ist der jeweilige Workspace-Mitarbeiter). Keine externen KI-Provider in der Verarbeitungskette — das Keyword-Matching ist ein deterministischer Substring-Vergleich.
- Terminbuchungsdaten (eingehende Calendly-Webhooks): Name und E-Mail-Adresse des Buchenden, Termin-Titel, Datum/Uhrzeit (Start- und Endzeit), Location-Typ (URL fuer Zoom/Teams/Meet → channel=video; Telefonnummer-Format → channel=phone; sonst in_person), UTM-Parameter (utm_source, utm_content fuer Deal-Verknuepfung). Datensubjekt: der Buchende (externe Person mit Vertriebs-Interesse).
- Google-Kalender-Termindaten (PROJ-1024): Termine aus dem per OAuth angebundenen Google-Kalender werden auf hinterlegte Keywords im Titel geprueft. Bei Treffer werden Termin-Titel, Start-/Endzeit und Teilnehmer (Name + E-Mail, soweit im Kalender hinterlegt) verarbeitet. Workspace-Mitglieder als Teilnehmer werden vor der Verarbeitung herausgefiltert (nur externe Teilnehmer werden gegen das CRM gematcht). Identische Zuordnungslogik wie bei Calendly (E-Mail-/Domain-/Namens-Match). Ein einmaliger Rueckwaerts-Import ab 01.04.2026 kann durch einen Workspace-Admin angestossen werden. Datensubjekt: der externe Termin-Teilnehmer.
- Idempotenz-Protokoll (calendar_event_processing_log, PROJ-1024): Pro verarbeitetem Google-Kalender-Termin ein Eintrag mit workspace_id, calendar_event_id (undurchsichtige Google-Event-ID, kein Klartext-PII), processed_at und result (assigned/unassigned/skipped_no_keyword/skipped_duplicate/skipped_internal/error). Verhindert Doppelverarbeitung. Enthaelt KEINE personenbezogenen Daten — weder Name noch E-Mail noch Titel. Workspace-scoped, CASCADE bei Workspace-Loeschung.
- Verknuepfungsdaten: Zuordnung der Buchung zu CRM-Kontakt (contacts.id), Kunde (customers.id) und Deal (sales_deals.id) nach Matching-Signalen 1-5 (E-Mail-Match, Domain-Match, Namens-Match, Titel-Aggregat, UTM-Deal-Match). Pro automatisch angelegtem Gespraech: sales_call_sessions-Eintrag mit source='booking' (Calendly) bzw. source='google_calendar' (PROJ-1024), calendar_event_id (Calendly Event URI bzw. Google-Event-ID fuer Deduplication), external_event_id, calendly_reschedule_url + calendly_cancel_url (PROJ-922: Calendly-Buchungs-Links zum Verschieben/Stornieren des Termins — enthalten eine undurchsichtige Invitee-UUID, kein Klartext-PII; nur bei source='booking' befuellt und nur fuer Admin/Manager sichtbar), scheduled_at, duration_seconds, channel.
- Konfigurationsdaten (appointment_keyword_rules): Pro Workspace n Eintraege mit keyword (max 100 Zeichen — Workspace-interner Begriff, keine PII), call_type (kategorisch aus CALL_TYPES-Whitelist), priority (Integer), is_active (Boolean). Workspace-scoped, keine PII.
- Konfigurationsdaten (appointment_booking_settings, 1:1 pro Workspace): unknown_appointment_mode (default_type/queue/ignore/known_contact_only — PROJ-2030), default_call_type (kategorisch, nullable), deal_assignment_mode (auto_single/manual_always/queue_multiple/queue_no_deal). Workspace-scoped, keine PII.
- Erweiterter Adressabgleich (PROJ-2030): Zur Zuordnung einer Terminbuchung werden zusaetzlich zu den Firmendaten (contacts) die gepflegten Ansprechpartner gelesen (contact_persons: Vor-/Nachname, E-Mail-Adresse, Zweitadressen, Firmenzuordnung). Grund: Eine Terminbuchung liefert die Adresse einer PERSON, waehrend die Firmensaetze ganz ueberwiegend keine E-Mail-Adresse tragen. Der Ansprechpartner ist dabei nie selbst Zuordnungsziel — er verweist ausschliesslich auf seinen Kunden; dieselbe Adresse bei mehreren Kunden fuehrt bewusst zu keiner automatischen Zuordnung. Zusaetzlich wird die Firmen-Domain der Adresse gegen die Domains gepflegter Ansprechpartner geprueft (Freimailer-Domains ausgenommen). Adressen der eigenen Firmendomain werden vom Abgleich vollstaendig ausgeschlossen, damit interne Termine nicht als Kundentermine gelten — die eigenen Domains werden dafuer aus den verbundenen Postfaechern der aktiven Mitglieder abgeleitet. Der Abgleich findet ausschliesslich im Arbeitsspeicher statt; es werden dabei keine zusaetzlichen personenbezogenen Daten gespeichert.
- Datensparsamkeit (PROJ-2030, Modus known_contact_only): In diesem Modus wird ein Termin ohne Vertriebs-Keyword im Titel und ohne bekannten Ansprechpartner GAR NICHT mehr gespeichert — es entsteht kein Warteschlangen-Eintrag, keine Benachrichtigung und keine E-Mail, lediglich ein Verarbeitungs-Protokolleintrag mit dem Grund der Abweisung. Zuvor wurde jeder Termin ohne Keyword-Treffer gespeichert, einschliesslich rein interner Besprechungen.
- Queue-Daten (appointment_booking_queue): Pro nicht zugeordneter Buchung ein Eintrag mit source (calendly/google_calendar, PROJ-1024), calendar_event_id, external_event_id, title, start_time, end_time, attendee_name (Klartext — Anzeige in Queue-UI noetig), attendee_email_hash (SHA-256-Hash, keine Klartext-E-Mail in DB), attendee_email_encrypted (Phase 3 AES-verschluesselt fuer spaeteres Matching ohne Klartext-Persistenz), detected_call_type, matched_contact_id/matched_customer_id/matched_deal_ids, status (pending/assigned/ignored). Rechtsgrundlage Hash + Verschluesselung: Pseudonymisierung gemaess Art. 4 Nr. 5 DSGVO. Retention: 90 Tage nach Statuswechsel auf assigned/ignored (Cleanup-Cron).
- Interne Benachrichtigung bei nicht zugeordnetem Google-Kalender-Termin (PROJ-1024, F-3): Wird ein keyword-erkannter Google-Kalender-Termin keinem Deal zugeordnet, erhalten die Workspace-Admins/-Manager eine Inbox-Benachrichtigung (Typ unassigned_google_calendar_event) und eine E-Mail (via Resend). Beide enthalten Termin-Titel, Datum und Teilnehmer-Name sowie — als Fallback wenn kein Name vorliegt — die Teilnehmer-E-Mail im Klartext (notifications.metadata JSONB bzw. E-Mail-Body). Datenminimierung: Empfaenger sind ausschliesslich interne, RLS-geschuetzte Workspace-Admins/-Manager (keine Drittuebermittlung); Zweck ist die manuelle Zuordnung. Aufbewahrung: Standard-Notification-Retention; CASCADE-Loeschung bei Workspace-Loeschung.
- Diagnose-Protokolldaten (calendly_webhook_logs): Pro eingehendem Webhook ein Eintrag mit event_type (invitee.created/invitee.canceled/unknown), processing_status (accepted/duplicate/unknown_event/invalid_signature/no_config/ignored/queued/error/no_match — 'no_match' seit PROJ-1370: Termin wurde verarbeitet, blieb aber final unzugeordnet in der Queue; der Status wird nach Abschluss der Verarbeitung serverseitig nachgezogen, keine neuen Datenkategorien), received_at, source_ip, calendar_event_id, payload JSONB (bereinigt — E-Mail-Klartexte werden vor Persistenz durch Hash ersetzt; keine Telefonnummern oder weitere PII im persistierten Payload), error_message. Retention: 90 Tage via Cleanup-Cron.
- Buchungslink-Sharing (Signal 5): Beim Klick auf 'Buchungslink teilen' im Deal-Detailbereich wird die persoenliche Calendly-URL des eingeloggten Vertrieblers (aus booking_page_members.member_token) um UTM-Parameter (utm_source=neuland_crm, utm_content=deal_<deal_id>) ergaenzt. Es entsteht KEIN persistierter Datensatz in NEULAND. OS — die Deal-ID liegt ausschliesslich als UTM-Parameter im Link und wird beim Webhook-Eingang aus dem Calendly-Payload (invitee.tracking) gelesen. Deal-IDs sind UUIDs (nicht ratbar) und allein kein sensitives Datum; der Webhook-Handler prueft zusaetzlich, ob der per UTM uebergebene Deal zum empfangenden Workspace gehoert.
- Zugriffskreis-Praezisierung (PROJ-1355): Vertriebsmitarbeiter der Rolle 'member' koennen ihre eigenen unzugeordneten Termine (owner_user_id = eigene Nutzer-ID) in der Queue-UI einsehen, zuordnen und ignorieren — bislang war das auf Admin/Manager beschraenkt. In der Member-Ansicht werden ausschliesslich attendee_name (Klartext) sowie Termin-Metadaten (Titel, Zeiten, Status, erkannter Gespraechstyp, Match-Verknuepfungen) ausgegeben; attendee_email_hash und attendee_email_encrypted sind NICHT Teil der Member-SELECT-Spalten (Live-Code-Verifikation PROJ-1370: GET-SELECT-Spaltenliste enthaelt kein attendee_email_hash/_encrypted-Feld). Zusaetzlich (PROJ-1355): ein einmaliger, admin-ausgeloester Calendly-Backfill (runCalendlyBackfill) reprozessiert ausschliesslich bereits in appointment_booking_queue vorhandene pending-Eintraege mit start_time ab 2025-05-01 durch die reparierte Matching-Engine — es erfolgt KEIN erneuter Abruf externer Calendly-/Google-Kalender-APIs und keine neue Datenerhebung. Da E-Mail-Adressen nur als Hash vorliegen, greifen beim Reprocess nur Name-/Titel-Signale auf Bestandsdaten (Signal 1/2 nicht rekonstruierbar). Idempotent via calendar_event_id (kein doppeltes sales_call_sessions). Bestehende 90-Tage-Retention unveraendert (pending-Eintraege waren nie Teil des Cleanups; ein promoteter Eintrag folgt der sales_call_sessions-Retention gemaess PROJ-482). Zugriffskreis-Erweiterung (PROJ-1370, Cluster R, loest die PROJ-1355-Einschraenkung ausdruecklich ab): Der zuvor admin/manager-exklusive Sammel-Eingang fuer besitzerlose Termine (owner_user_id IS NULL) ist jetzt fuer ALLE aktiven Workspace-Rollen sichtbar, also auch 'member' — server-seitiger Filter erweitert von 'nur eigene' auf 'eigene ODER besitzerlos' (owner_user_id = eigene Nutzer-ID OR owner_user_id IS NULL), kein Client-Override moeglich. Sobald ein 'member' einen besitzerlosen Termin zuordnet, wird owner_user_id auf diesen Nutzer gesetzt (Termin 'gehoert' danach ihm). Live-DB-Stichprobe 2026-07-02 (Workspace bdbfef89-3d17-41f7-a7df-09f6ae7a82fd): 9 aktive 'member' erhalten dadurch Zugriff auf attendee_name + Termin-Metadaten von aktuell 61 besitzerlosen, pending Warteschlangen-Eintraegen — zusaetzlich zu den bisherigen 6 Admin/Manager-Nutzern desselben Workspaces. Weiterhin KEINE neuen Datenkategorien und KEIN neuer externer Betroffenenkreis (Datensubjekt bleibt der externe Buchende) — es handelt sich um eine interne Zugriffskreis-Erweiterung innerhalb desselben Workspaces auf bereits bestehende, bereits verarbeitete Daten, mit unveraendertem Spaltenumfang (weiterhin ohne E-Mail-Felder). Rechtsgrundlage unveraendert Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an funktionierender, arbeitsteiliger CRM-Pflege) — die Erweiterung folgt direkt aus dem urspruenglichen PM-Auftrag ('jeder eingeloggte Nutzer soll besitzerlose Termine zuordnen koennen'). Fremde, einem anderen konkreten Nutzer gehoerende (bereits zugeordnete) Termine bleiben fuer 'member' weiterhin unsichtbar (403).
HAWEGO-Shopware-Synchronisation (Kunden + Bestellungen + Kategorien, PROJ-398)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung gegenüber den Shop-Kunden, deren Verträge und offene Vorgänge weiterhin bedient werden müssen) in Verbindung mit Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Migration des bestehenden Shop-Systems ohne Datenverlust und mit einheitlicher Kundenhistorie). Bestehende Kunden-Einwilligungen aus dem Shopware-Betrieb bleiben gültig — es erfolgt keine Zweckänderung, die Verarbeitung beschränkt sich auf die identische Shop-Zweckbindung. Rechtliche Prüfung der Bestandskunden-Einwilligung vor Go-Live vorbehalten.
- Identifikations- und Kontaktdaten (Shopware-Kundennummer, Vorname, Nachname, E-Mail-Adresse, Telefon, Firma, Umsatzsteuer-ID, Geburtsdatum falls im Shop erfasst)
- Adressdaten (Rechnungs- und Lieferanschrift: Vorname, Nachname, Firma, Straße, PLZ, Stadt, Land, Telefon) — pro Kunde mehrere Adressen möglich
- Bestelldaten (Shopware-Bestellnummer, Bestellzeitpunkt, Bestellstatus, Zahlungsstatus, Netto-/Brutto-Beträge, Versandkosten, Währung)
- Bestellpositionen (Produktname, SKU, Menge, Einzelpreis, MwSt-Satz) — Produktreferenzen bleiben null, wenn Produkt nicht in NEULAND. OS existiert (nur Snapshot aus Shopware)
- Kategoriehierarchie (Shopware-Kategorie-IDs, Namen, Beschreibungen, HAWEGO-Kategorie-URLs, parent-Beziehungen)
- Technisches Audit-Feld source='shopware' zur Kennzeichnung importierter Datensätze
- Agent-Heartbeat-Metadaten (token_hash, last_seen_at, last_seen_ip, Agent-Version) — pro Push-Agent-Instanz, keine Endkunden-Daten
PROJ-743 HAWEGO Produktdaten-Import & Sheet-Sync
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an einheitlicher Produktdatenpflege im Shop-System statt fragmentierter Lieferanten-Sheets — Reduktion von Fehlerquellen, Validierungslücken und manueller Doppelpflege). Auftragsverarbeitung gemäß Art. 28 DSGVO mit Google LLC (siehe PROCESSORS-Eintrag — Drive API v3 + Sheets API v4). Lieferanten-Kontakt-E-Mails sind Geschäftsdaten juristischer Personen, kein End-User-Personenbezug.
- shop_drive_import_config (PROJ-398 Phase 2 wiederverwendet): Pro Workspace eine Konfiguration — drive_folder_id, google_token_id (FK auf user_google_tokens in Haupt-DB), enabled, column_mappings (JSONB), sheet_tab_name, last_checked_at. RLS via Service-Role über withShopClient.
- shop_drive_sheets (PROJ-743 Phase 1, NEU): Pro erkannter Importliste ein Eintrag — workspace_id, config_id (CASCADE), drive_file_id, file_name, manufacturer_slug (abgeleitet aus Dateiname), status (erkannt/aktiv/pausiert/fehler/drive_removed/pattern_mismatch/auth_error), last_modified_drive, last_sync_at, last_sync_log_id, tab_validation (JSONB Pflicht-Tab-Check), product_count, warnings_count, sync_in_progress + sync_lock_acquired_at (15-Min-Lock-Timeout), Zeitstempel. KEIN PII (technische Metadaten).
- shop_sync_overrides (PROJ-743 Phase 4, NEU): Audit-Trail für Felder, die durch den Sheet-Sync überschrieben wurden — workspace_id, product_id (CASCADE), sheet_id (FK SET NULL), sync_log_id (Soft-Ref), field_path (z.B. base_price_cents, field_values.material), old_value/new_value (JSONB), last_manual_edited_by (auth.users), last_manual_edited_at, overwritten_at. 90-Tage-Retention via proj743-override-cleanup-Cron. Personenbezug nur über last_manual_edited_by (Agentur-Mitarbeiter — wer hat zuletzt manuell editiert).
- products-Erweiterungen (PROJ-743 Phase 1): Neue Spalten auf bestehender products-Tabelle — manufacturer_id (FK manufacturers), marketplace_release (JSONB Google/Mercateo/aimondo-Freigaben), pricing (JSONB Pseudopreis/Listenpreis/EK/Rabatte), shipping (JSONB Versandkosten/Lieferzeit/Verpackung/Lieferanten-E-Mail), media (JSONB max 14 Bildmetadaten — storage_url=null bis Bild-Migrations-Folge-Spec), source_sheet_id + source_row_index (Audit), unresolved_category_ids (JSONB Retry-Puffer), deactivation_reason + deactivated_at (Soft-Delete-Audit). PII: shipping.supplier_email als Lieferanten-Geschäfts-E-Mail (Art. 6 Abs. 1 lit. f).
- shop_sync_pending_attributes (PROJ-398 Phase 2 wiederverwendet): Unbekannte Sheet-Spalten warten auf Admin-Bestätigung vor PIM-Feld-Anlage. KEIN PII (Spalten-Namen + Sample-Werte).
- shop_sync_logs-Erweiterung: Neue sync_type-Werte `drive_folder_scan` (Discovery-Lauf) + `drive_product_import` (Initial-Migration + Recurring-Sync). 90-Tage-Retention bereits aus PROJ-398. summary-JSONB enthält sheet_id, manufacturer_slug, product_groups_created/_updated/_removed, axes_inserted, members_inserted etc.
- Google-Übermittlung: Drive-Folder-Listing + Sheets-Lese-Calls erfolgen ausschließlich mit dem User-OAuth-Token des Admins, der den Folder konfiguriert hat (Wiederverwendung der bestehenden OAuth-Verbindung aus PROJ-28). NEULAND. OS sendet keine Workspace-Daten in Gegenrichtung — Sync ist strikt read-only auf Sheet-Seite.
- Notification-Typen (PROJ-743 Phase 5): drive_sync_error (Sync fehlgeschlagen), drive_sheet_drive_removed (Sheet aus Folder verschwunden), drive_pending_attribute_discovered (neue Sheet-Spalte gefunden), drive_sheet_property_set_conflict (Set-Konflikt zwischen Sheets) — Inbox-Empfänger Workspace-Admins+Managers. Notifications enthalten keine Kunden-Daten (nur Sheet-Namen + Sync-Status-Codes).
PROJ-1920 ZUGFeRD-E-Rechnung für Shopware 5 (hawego)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Ausstellung einer ordnungsgemäßen Rechnung an den Shop-Kunden) in Verbindung mit Art. 6 Abs. 1 lit. c DSGVO (rechtliche Verpflichtung — GoBD/handelsrechtliche Rechnungsanforderungen, perspektivisch gesetzliche E-Rechnungspflicht). Auftragsverarbeitung im Sinne von Art. 28 DSGVO: NEULAND. OS verarbeitet die Käuferdaten hier ausschließlich weisungsgebunden im Auftrag von hawego als datenschutzrechtlich Verantwortlichem für seine Shop-Kunden.
- Käuferdaten aus der Rechnung (Name, Rechnungsadresse, ggf. USt-IdNr.) — werden vom Shopware-Plugin an den neuen Endpunkt POST /api/integrations/shopware-hawego/zugferd-invoice übermittelt und AUSSCHLIESSLICH transient zur XML-Erzeugung verarbeitet: keine Speicherung, kein Logging dieser Felder in NEULAND. OS.
- Rechnungsdaten (Rechnungs-/Bestellnummer, Datum, Positionen, Beträge, Steuersätze) — ebenfalls nur transient verarbeitet.
- shopware_zugferd_invoice_logs (NEU, Migration 20260804094619): Protokolliert jeden Integrationsaufruf für Nachvollziehbarkeit/Debugging — ausdrücklich OHNE Käufer-PII, nur workspace_id, Rechnungs-/Bestellnummer, Status (success/missing_fields/validation_failed/…), serverseitig formulierte Fehlertexte, Validator-Report-Auszug.
- hawegos eigene Verkäufer-Stammdaten (Firmenname, Anschrift, USt-IdNr., Bankverbindung) — bereits bestehende Felder auf hawegos NEULAND. OS-Workspace (workspaces.*, aus PROJ-49/PROJ-48), keine neue Datenkategorie.
PROJ-500 Knowledge Layer (pgvector-RAG-Foundation)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an einer einheitlichen, semantisch durchsuchbaren Wissensbasis für SOPs, Hilfe-Artikel und Lektionen — Reduktion von Suchzeit, konsistente App-Antworten und KI-Assistenten-Wissen). Auftragsverarbeitung gemäß Art. 28 DSGVO mit OpenAI Inc. (siehe PROCESSORS-Eintrag) für die Embedding-Generierung via text-embedding-3-small.
- knowledge_documents (gechunkte indexierte Wissensartikel — id, workspace_id NULL/UUID, source_type ('sop_article'|'help_article'|'lesson'), source_id, title, content_plain, chunk_index, embedding vector(1536), metadata JSONB, last_embedded_at, created_at, updated_at) — pro Quell-Artikel typischerweise 1-10 Chunks. Inhalt ist generische Produktdokumentation, Prozessbeschreibungen oder Hilfe-Artikeltexte ohne personenbezogene Daten. workspace_id NULL = plattformweit (Standard-Hilfe-Artikel), sonst Workspace-spezifisch.
- knowledge_embedding_queue (Job-Queue für Background-Worker — id, source_type, source_id, workspace_id, status (pending/processing/completed/failed), attempts, error_message, Zeitstempel) — interne Queue-Metadaten ohne personenbezogene Daten.
- OpenAI-Übermittlung (Embedding-Generierung): Pro Chunk wird der Titel + Klartext-Inhalt des Wissensartikels (max. ~3.200 Zeichen, ~800 Tokens) an OpenAI text-embedding-3-small übermittelt. Wissensinhalte sind technische Produktdokumentation und Prozess-Beschreibungen ohne personenbezogene Daten. OpenAI verarbeitet die Daten transient (kein Training auf API-Daten gemäß OpenAI API Data Usage Policy). Token-Tracking via logTokenUsage(feature='knowledge_embedding').
PROJ-501 Prozess-/SOP-Modul (Internes Wiki)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — interne Prozess-Dokumentation für Agenturmitarbeiter und ihre Kunden im Sinne von Effizienz und Qualitätssicherung). Auftragsverarbeitung gemäß Art. 28 DSGVO mit OpenAI Inc. (siehe PROCESSORS-Eintrag) für die Embedding-Generierung via PROJ-500 Knowledge Layer.
- sop_categories (Bereiche/Themen pro Workspace — id, workspace_id, name, description, icon, sort_order, archived_at, Zeitstempel) — generische Konfigurationsdaten ohne personenbezogene Daten.
- sop_articles (SOP-Artikel — id, workspace_id, category_id, title, content_json (TipTap-Editor-JSON), content_plain (Plain-Text-Spiegelung für Knowledge-Layer-Indexierung), template_used, owner_user_id (FK auf auth.users mit ON DELETE SET NULL), created_by, updated_by, is_mandatory, mandatory_target_audience, review_due_date, published, archived_at, has_style_deviations (PROJ-504: Cache-Flag für SOP-Liste, TRUE wenn der letzte Konsistenz-Check Stilabweichungen ergab), Zeitstempel) — Inhalte sollen generische Prozess-Beschreibungen sein. owner_user_id und created_by sind die einzigen personenbezogenen FKs.
- PROJ-504 workspace_settings.sop_consistency_check_enabled + sop_consistency_check_strict_mode (Workspace-Konfigurationsfelder ohne PII): Toggle zum Aktivieren des SOP-Konsistenz-Checks und Hinweis-Mode für offene Stilabweichungen beim Speichern. Beide Felder default FALSE — Feature ist opt-in pro Workspace. Speicherung im JSONB-freien Spaltensatz von workspace_settings.
- PROJ-504 Konsistenz-Check Anthropic-Übermittlung: Bei jedem User-Klick auf den 'Konsistenz prüfen'-Button wird der aktuelle SOP-Inhalt (transient zu Markdown serialisiert, max 5.000 Zeichen) gemeinsam mit der workspace_settings.sop_style_config an Claude Haiku 4.5 gesendet (siehe PROCESSORS-Eintrag — Anthropic). Vorschläge werden NICHT in der DB gespeichert — sie existieren nur während der Browser-Session und werden vom User entweder übernommen oder ignoriert. Token-Tracking via logTokenUsage(feature=sop_consistency_check). Rate-Limit 20 req/min/Workspace + 200 req/24h/Workspace.
- sop_read_confirmations (Lese-Bestätigungen für Pflichtlektüre — id, sop_article_id, user_id (FK auf auth.users), workspace_id, confirmed_at) — User-bezogene Audit-Trail-Daten. UNIQUE (sop_article_id, user_id). Unveränderlich (kein UPDATE per RLS).
- sop_article_shares (Cross-Workspace-Sharing Agency → Client — id, sop_article_id, target_workspace_id, shared_by, shared_at) — Sharing-Metadaten ohne PII. Aktiviert PROJ-500 Permission-JOIN.
- PROJ-502 sop_article_permissions (granulare Per-User-Berechtigung — id, sop_article_id, user_id (FK auf auth.users mit ON DELETE CASCADE), workspace_id, role (read|write), granted_by, expires_at, Zeitstempel). Ermöglicht selektive SOP-Freigabe an einzelne Personen unabhängig von Workspace-Rolle (Hierarchie überschreibt Workspace-Rolle). UNIQUE (sop_article_id, user_id). Workspace-Mitgliedschaft Pflicht (R-456).
- PROJ-502 sop_article_invitations (externe E-Mail-Einladungen ohne Workspace-Account — id, sop_article_id, workspace_id, email, role, token_hash (SHA-256), invited_by, expires_at, accepted_at, accepted_by, revoked_at, created_at). Plain-Token wird ausschließlich in der Einladungs-E-Mail an die Empfängeradresse versendet (Resend, siehe PROCESSORS), niemals in DB oder Logs gespeichert (R-100). Standard-Ablaufzeit 30 Tage, max. 90 Tage.
- PROJ-1733 sop_category_permissions (bereichs-weite Per-User-Berechtigung — id, sop_category_id, user_id (FK auf auth.users mit ON DELETE CASCADE), workspace_id, role (read|write), granted_by, expires_at, Zeitstempel). Additiv zur Artikel-Berechtigung (ODER-Logik): Zugriff gilt automatisch für alle aktuellen und zukünftigen Artikel des Bereichs. UNIQUE (sop_category_id, user_id). Workspace-Mitgliedschaft Pflicht (R-456).
- PROJ-1733 sop_category_invitations (externe E-Mail-Einladungen auf Bereichs-Ebene — id, sop_category_id, workspace_id, email, role, token_hash (SHA-256), invited_by, expires_at, accepted_at, accepted_by, revoked_at, created_at). Identisches Token-Modell wie sop_article_invitations: Plain-Token nur in der Einladungs-E-Mail (Resend), niemals in DB oder Logs (R-100). Standard-Ablaufzeit 30 Tage, max. 90 Tage.
- PROJ-513/PROJ-1730 SOP-Mediathek (sop_media): Workspace-Mitglieder (Admin/Manager) laden Bilder (JPG, PNG, GIF, WebP, SVG — max. 10 MB), Videos (MP4, WebM — max. 100 MB) und Dokumente (PDF, Word, Excel, PowerPoint, TXT, ZIP — max. 20 MB, PROJ-1730) hoch, um SOPs zu erlaeutern bzw. Dateien im Beitragstext zu verlinken. Datensatz pro Datei: id, workspace_id (CASCADE), filename (sanitized Original-Dateiname), display_name (editierbarer Anzeigename), storage_path (privat im EU-Supabase-Bucket sop-media), media_type (image|video|file), mime_type, file_size_bytes, created_by (auth.users), Zeitstempel. Inhalte sind prozess-interne Erklaerbilder/Screenshots bzw. Prozess-Dokumente ohne erwarteten Personenbezug (hochgeladene Dokumente KOENNEN je nach Inhalt personenbezogene Daten enthalten — Verantwortung liegt beim hochladenden Workspace, Zugriff bleibt workspace-scoped). Upload-Sicherheit: Magic-Byte-Verifikation (R-228) + aktive Ablehnung ausfuehrbarer Formate (.exe/.sh/ELF/Mach-O — Blocklist vor Allowlist). Speicherung im privaten Supabase-Storage (EU-Region), Auslieferung im Reader ausschliesslich per signed URL (TTL 1h) — kein indexierbarer Public-Link. Workspace-eigene Medien werden ausschliesslich in EU-Supabase-Storage gespeichert und per signed URL ausgeliefert (loest den fruehe externe-URL-Stand-in von PROJ-502 ab). Cross-Workspace-Lesezugriff nur, wenn die SOP per sop_article_shares an den Ziel-Workspace freigegeben ist UND das content_json die sop_media.id enthaelt. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an verstaendlicher Prozess-Dokumentation).
- PROJ-516 SOP-Vorlagen (sop_templates): Pro Workspace gespeicherte Vorlagen-Definitionen (Titel, Beschreibung, TipTap-Struktur als JSONB) zur konsistenten Erstellung neuer SOPs. Felder: id, workspace_id (NULL fuer System-Vorlagen, sonst FK auf workspaces mit CASCADE), template_key, title, description, structure (JSONB TipTap-Doc), sort_order, is_system, archived_at, created_by (FK auf auth.users mit ON DELETE SET NULL), created_at, updated_at. System-Vorlagen (workspace_id IS NULL, is_system=TRUE) sind unveraenderliche Standard-Vorlagen ohne Personenbezug — sie sind plattformweit verfuegbar und nicht workspace-personenbezogen. Workspace-Vorlagen enthalten created_by als einzigen personenbezogenen FK; Inhalte (title, description, structure) sind generische Prozess-Vorlagen ohne erwarteten Personenbezug. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Agentur-interne Dokumentations-Standards). RLS: Admin/Manager schreiben workspace-eigene Vorlagen, alle Workspace-Mitglieder lesen workspace-eigene und plattformweite System-Vorlagen. Workspace-scoped, CASCADE-DELETE bei Workspace-Loeschung; System-Vorlagen sind unabhaengig vom Workspace und bleiben bestehen.
- OpenAI-Übermittlung: Erfolgt indirekt via PROJ-500 Knowledge Layer — sop_articles werden über den sop_articles_knowledge_sync-Trigger in die knowledge_embedding_queue eingereiht. Wissensartikel sind generische Prozess-Beschreibungen ohne personenbezogene Daten. Token-Tracking via PROJ-500.
- Resend-Übermittlung (PROJ-502): Externe Einladungs-E-Mails (Empfänger-E-Mail + SOP-Titel + Zugangs-Link) werden an Resend Inc. (siehe PROCESSORS-Eintrag) zur Zustellung übermittelt. Rechtsgrundlage Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Wissensvermittlung).
- PROJ-515 sop_feedback (Inline-Feedback + KI-Vorschlag — id, sop_article_id (CASCADE), workspace_id (CASCADE), submitted_by (FK auth.users SET NULL — Audit-Eintrag bleibt anonymisiert bei User-Löschung), message (Pflichtfeld 10-2000 Zeichen — Mitarbeiter-Freitext der personenbezogene Inhalte enthalten kann, da Verbesserungsvorschläge konkrete Personen, Projekte oder Kunden referenzieren können), reason (optional, max 500 Zeichen), ai_proposal_json (KI-generierter content_json-Vorschlag, JSONB), ai_proposal_summary (max 300 Zeichen), ai_run_status (pending/succeeded/failed/timeout), ai_run_error, status (open/in_review/applied/dismissed), dismiss_reason (optional, max 200 Zeichen), resolved_by (FK auth.users SET NULL), resolved_at, Zeitstempel) — Workspace-scoped via FK. RLS: SELECT für Owner+Admin/Manager+Submitter, INSERT für aktive Workspace-Member, UPDATE/DELETE nur Owner+Admin/Manager. Feedback-Submission wird per Inbox-Notification 'sop_feedback_received' an Owner+Admin/Manager gemeldet (NOTIFICATION_TYPES + notifications_type_check).
- PROJ-515 sop_feedback_proposal Anthropic-Übermittlung: Bei jedem POST /api/sop/articles/:id/feedback wird async (fire-and-forget) der aktuelle sop_articles.content_json (transient als JSON serialisiert, max 60.000 Zeichen — Truncation mit head+tail bei längeren SOPs) gemeinsam mit workspace_settings.sop_style_config und dem Feedback-Text an Claude Haiku 4.5 gesendet (siehe PROCESSORS-Eintrag — Anthropic). Modell-Output (content_json + Kurz-Zusammenfassung) wird in sop_feedback gespeichert. Inhalte können personenbezogene Daten enthalten — Mitarbeiter beschreibt Freitext-Verbesserungsvorschläge die konkrete Personen, Projekte oder Kunden referenzieren können. Timeout 60s. Rate-Limit 10 Submits/h/User + 5 Retry/h/User. Token-Tracking via logTokenUsage(feature=sop_feedback_proposal). Bei Fehler/Timeout: ai_proposal_json bleibt NULL, ai_run_error gesetzt, ai_run_status='failed'/'timeout'.
- PROJ-515 workspace_settings.sop_feedback_enabled (Boolean DEFAULT true) + sop_feedback_hint_text (Plaintext, max 500 Zeichen, Default mit {{owner_name}}-Platzhalter): Workspace-weite Feedback-Konfiguration. Toggle aktiviert/deaktiviert die Feedback-Funktion (Hint-Block + Sheet im Reader). Hint-Text ist Plaintext, kein HTML, kein Personenbezug erwartet — Admin kann eigenen Wording-Text setzen.
PROJ-506 KI-gestützte Übersetzung der Signing-Seite
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragsanbahnung — Empfänger eines Angebots benötigt verständliche Inhalte vor Vertragsschluss) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an inklusiver, mehrsprachiger Geschäftsanbahnung). Auftragsverarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC (siehe PROCESSORS-Eintrag).
- quote_translations (Übersetzungs-Cache pro Angebot — id, quote_id, workspace_id, language_code (BCP-47, z.B. 'en', 'fr-CA'), language_label (Anzeigename), content_hash (SHA-256 der Original-Texte zur automatischen Cache-Invalidierung), translated_fields (JSONB mit Schlüssel→übersetzter-Text-Map), model_used (Claude-Modell-ID), created_at, expires_at). Workspace-scoped, CASCADE-DELETE bei Angebots-/Workspace-Löschung. UNIQUE auf (quote_id, language_code, content_hash) verhindert doppelte Cache-Einträge.
- Anthropic-Übermittlung: Bei jedem User-Klick auf eine Zielsprache (≠ Deutsch) im Sprach-Switcher der Signing-Seite werden die textuellen Inhalte des Angebots an Claude Haiku 4.5 (siehe PROCESSORS-Eintrag) übermittelt: Titel, Notes, Projektbeschreibung (Plain-Text-Extraktion aus JSONB), Audio-Zusammenfassungs-Text, Anrede, sowie Name und Beschreibung der Plan-Items (max. 40 Items, max. 8.000 Zeichen pro Feld). Quelle ist bei signierten Angeboten der signing_snapshot (R-318), bei Entwurf/gesendet die Live-Felder. Diese Inhalte können personenbezogene Daten enthalten (z.B. Kundennamen in projektbezogenen Beschreibungen). Der System-Prompt instruiert Claude ausdrücklich, Eigennamen, Firmennamen, Markennamen, Preise, Zahlen, Datumsangaben, E-Mail-Adressen, URLs und Produktcodes unübersetzt zu lassen. Token-Tracking via logTokenUsage(feature=signing_translation). Rate-Limit 30 Übersetzungen/24h pro IP. Timeout 30s. Modell-Output ist transient — keine Datenpersistenz bei Anthropic.
- quote_activities-Eintrag (event_type='translation_requested'): Pro Übersetzung wird ein Eintrag in der bestehenden quote_activities-Tabelle erzeugt mit metadata={language_code, language_label, source_key_count}. Sichtbar im Angebots-Aktivitäts-Tab (PROJ-335) für Workspace-Mitglieder mit Lesezugriff auf das Angebot.
- Browser-localStorage (Client-Side-Cache, kein Server-Speicher): Das Frontend hält die zuletzt gewählte Sprache und das letzte Übersetzungsergebnis im localStorage des Empfänger-Browsers vor (Schlüssel: signing_translation_<token>_<lang>). Liegt ausschließlich auf dem Endgerät des Empfängers — kein PII auf eigenen Servern. Wird beim Browser-Cache-Reset gelöscht.
PROJ-510 Coding Operations Platform (Phase 1A — Daten-Schicht)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an einem skalierbaren, multi-tenant-fähigen Coding-Werkzeug, das Plattform-Admins und Workspace-Mitglieder bei der Weiterentwicklung von NEULAND. OS und Custom-Modulen unterstützt — ersetzt langfristig das aktuelle Claude-Code/Bridge-Daemon-Setup auf Mac-Mini durch eine in NEULAND. OS integrierte Lösung). Auftragsverarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC (Coding-Agent-Konversationen via Anthropic Agent SDK) und OpenAI Inc. (Embedding-Generierung für die Wissensbasis via PROJ-500 Knowledge Layer). Phase 1A enthält ausschließlich die Daten-Schicht (Tabellen + Trigger + RLS); echte Anthropic-Calls werden in Phase 1C aktiviert.
- coding_ops_rules (strukturiertes Regelwerk — id, rule_key (z.B. R-510), title, body (Volltext der Regel inkl. Beispiel-Patterns), severity (hard_blocker/recommendation/hint), category (backend/frontend/security/navigation/workflow/general/ui_pattern/branching/dsgvo/qa), trigger_pattern, related_feature_keys (Array, z.B. ['PROJ-260', 'PROJ-417']), source_retro, is_active, Zeitstempel) — interne technische Dokumentation, KEIN PII. Plattform-weit verfügbar, nicht workspace-scoped. Plattform-Admin-only RLS in Phase 1.
- coding_ops_features (strukturierte Feature-Übersicht — id, feature_key (z.B. PROJ-510), title, status, summary, dependencies (Array), spec_path, last_synced_at, Zeitstempel) — importierte Spiegelung von features/INDEX.md + Feature-Specs. Interne Software-Dokumentation, KEIN PII. Plattform-Admin-only RLS in Phase 1.
- coding_ops_code_index (Live-Code-Inventar — id, entity_type (api_route/hono_route/db_table_reference/react_component/cron_job/rls_policy), entity_key, file_path (relativ zum Repo-Root), line_number, metadata (JSONB für Zod-Schema/Export-Name/Props/related_tables), last_indexed_at, Zeitstempel) — strukturierte Code-Repräsentation des neuland-os-Repos, befüllt durch ts-morph-Indexer. KEIN PII (nur Code-Struktur-Metadaten). Plattform-Admin-only RLS in Phase 1.
- coding_ops_sessions (Multi-Turn-Konversations-Sessions — id, workspace_id (CASCADE), user_id (CASCADE auf auth.users), title, task_description (User-Eingabe, max. 50.000 Zeichen — kann betriebsinterne Inhalte und ggf. Endkunden-Bezug enthalten wenn Bug-Report einen Kunden-Workflow betrifft), status, permission_mode (junior/trusted/admin), Token-Counts (input/output/cache_read/cache_creation), total_cost_eur, estimated_cost_eur, cost_limit_eur, branch_name, pull_request_url, failure_reason, started_at, completed_at, Zeitstempel) — Workspace-scoped. RLS: User sieht eigene Sessions, Workspace-Admin/Manager alle im Workspace, Plattform-Admin alles.
- coding_ops_session_messages (Konversations-Historie — id, session_id (CASCADE), sequence_number, role (user/assistant/tool/system), content (JSONB strukturierte Daten), tool_name, tool_input (JSONB), tool_output (JSONB), model_used (claude-haiku-4-5/claude-sonnet-4-6/claude-opus-4-7), Token-Counts pro Message, Zeitstempel) — Quelle der Wahrheit für Session-Resume. INSERT/UPDATE/DELETE nur via Service-Role (Agent-Runner) — keine User-Manipulation der Konversations-Historie. SELECT folgt Session-Sichtbarkeit.
- coding_ops_quality_gate_runs (programmatische Hard-Blocker-Check-Ergebnisse — id, session_id (CASCADE), rule_key (z.B. R-510), status (pass/fail/warn/skipped), file_path, line_number, message, details (JSONB), run_at) — Software-Diagnose-Daten ohne PII. SELECT folgt Session-Sichtbarkeit.
- Anthropic-Übermittlung (Phase 1C aktiviert): Multi-Turn-Konversationen mit Coding-Agent. Übermittelt werden User-Task-Beschreibungen, Code-Snippets aus dem Repository, Konversations-Historie der laufenden Session und strukturierte Knowledge-Graph-Auszüge (Top-K relevante Regeln + Code-Index-Einträge). Modelle: Claude Haiku 4.5/Sonnet 4.6/Opus 4.7 mit Multi-Modell-Routing. Token-Tracking via logTokenUsage(feature=coding_ops_session). Cost-Estimate vor Session-Start, Hard-Stop bei Workspace-Budget-Überschreitung. Inhalte können betriebsinterne Daten und gelegentlich Endkunden-Bezug enthalten (wenn Bug-Reports konkrete Kunden-Workflows beschreiben), kein automatisches PII-Scrubbing — Workspace-Admin entscheidet welche Tasks an Plattform delegiert werden. Konversations-Historie liegt ausschließlich in eigener DB (coding_ops_session_messages), kein Anthropic-API-side Memory. Transient bei Anthropic.
- OpenAI-Übermittlung (Phase 1A aktiviert via Trigger, echte Indexierung in Phase 1B): Pro Rule (Title + Body) und Feature (Title + Summary) wird der Text an OpenAI text-embedding-3-small (1536-dim) übermittelt um semantische Vektor-Repräsentationen für die Knowledge-Graph-Suche zu erzeugen. Inhalte sind interne technische Dokumentation ohne PBD. Embeddings werden in knowledge_documents persistiert (PROJ-500-Wiederverwendung). Token-Tracking via logTokenUsage(feature='knowledge_embedding', source='coding_ops').
- PROJ-510 Phase 3.4 coding_ops_pending_decisions (Approval-Cards — id, session_id CASCADE, decision_type (architecture/migration/permission/external_api), question, options JSONB, status (pending/answered/auto_resolved), answered_by, answered_at, answer JSONB, created_at): Vom Coding-Agent erzeugte Entscheidungs-Anfragen die der eingeloggte Mitarbeiter im UI per Click-Auswahl beantwortet. Inhalte: technische Frage + 2-4 Antwort-Optionen vom Agent generiert. Workspace-scoped via Session-FK. RLS folgt Session-Sichtbarkeit.
- PROJ-510 Phase 7.3 coding_ops_workspace_budgets (Tagesbudget — workspace_id PRIMARY KEY CASCADE, daily_budget_eur (Default 50€), alert_threshold_pct (Default 80), hard_stop_enabled (Default true), last_alert_sent_at, last_alert_pct, Zeitstempel): 1 Row pro Workspace, Plattform-Admin-only Write, Workspace-Admin/Manager Read. Steuert ob Coding-Ops-Sessions bei Tagesbudget-Überschreitung blockiert werden + ab welchem Schwellwert Inbox-Alerts an Plattform-Admins gehen.
- PROJ-510 Phase 8.2 coding_ops_repositories (Plattform-Repo-Registry — id, repo_key, display_name, local_path, github_repo, default_branch, framework (nextjs/swift/node/other), is_active, is_default, last_indexed_at, entries_count, Zeitstempel): Plattform-weite Tabelle (kein workspace_id), Plattform-Admin-only RLS. Bestimmt cwd für Bash/Read/Write/Edit-Tools und scope für query_code_index. KEIN PII (interne Repo-Metadaten).
- PROJ-510 Phase 6.2 coding_ops_session_templates (Plattform-Default-Templates — id, workspace_id NULLABLE, name, task_template, default_permission_mode/cost/model, is_platform_default, sort_order): Plattform-weite Vorlagen + ggf. Workspace-spezifische Erweiterungen. Plattform-Admin-only Write. Inhalte: technische Task-Texte ohne PII.
- PROJ-510 Phase 8.2 coding_ops_sessions.preferred_model + repository_id: Spalten-Erweiterung der bestehenden Sessions-Tabelle für Multi-Modell-Routing und Multi-Repo-Auswahl. Kein neues PII.
- PROJ-510 Phase 15 coding_ops_auto_review_configs (Auto-PR-Review pro Repo — repository_id PRIMARY KEY CASCADE, enabled, only_authors[], required_labels[], target_workspace_id CASCADE, target_user_id CASCADE, permission_mode (Default trusted), cost_limit_eur, preferred_model, Zeitstempel): Plattform-Admin-only Read+Write. Kontrolliert ob ein GitHub-PR-Webhook automatisch eine Coding-Ops-Auto-Review-Session anlegt.
- PROJ-510 Phase 15 coding_ops_github_webhook_logs (Audit für GitHub-Webhook-Aufrufe — id, received_at, source_ip, github_event/action, github_delivery_id, pr_number, repo_full_name, repository_id FK SET NULL, session_id FK SET NULL, processing_status (10 Werte: accepted/invalid_signature/.../session_create_failed), error_message, payload_excerpt JSONB): Plattform-Admin-only SELECT. Speichert IP, GitHub-Login (im payload_excerpt) und PR-Metadaten 30 Tage zur Diagnose. Webhook-Receiver-Log gemäß R-666.
- PROJ-510 Phase 19 Daily-Digest-Email an Plattform-Admins: Täglich 06:00 UTC fasst der coding-ops-daily-digest-Cron die Vortags-Aktivität zusammen (Sessions-Counts, Top-Spending-Workspaces, Modell-Verteilung, Failed-Sessions mit failure_reason, Auto-PR-Review-Trigger-Stats, Budget-Warnungen). Die HTML-Mail wird via Resend (Auftragsverarbeiter) an die hinterlegten E-Mail-Adressen aller Plattform-Admins (Lookup via auth.users.email) versandt. Inhalte: aggregierte Statistiken + max 10 fehlgeschlagene Sessions mit Workspace-Name, Title und failure_reason (kann betriebsinterne Hinweise enthalten). Kein Versand wenn 0 Sessions UND 0 Webhook-Trigger im Window (R-639). Tracking via email_delivery_logs (PROJ-Email-System). Die Mail enthält keine PII von Endkunden — nur Workspace-Namen und interne Coding-Ops-Stats.
PROJ-569 Werbekonten-Zentralisierung (Manager-Account-Discovery + CRM-Tab-Picker)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizientem Agentur-Setup ohne manuelle Eingabe von Werbekonto-IDs pro Kunde + skalierbare Pflege wachsender Kundenportfolios). Auftragsverarbeitung gemäß Art. 28 DSGVO mit Google LLC, Microsoft Corporation, Meta Platforms Inc. und LinkedIn Corporation (siehe PROCESSORS) — bestehende AVVs aus PROJ-17/PROJ-135/PROJ-136/PROJ-272/PROJ-367 gelten unverändert. Die Manager-Account-Discovery transferiert ausschließlich Geschäftsdaten der Account-Inhaber (Account-IDs, Account-Namen, Währung) — kein End-User-Personenbezug.
- workspace_ads_manager_connections (PROJ-569, seit PROJ-1994 mehrere Manager pro Provider möglich): Pro Workspace + Provider EIN oder MEHRERE Manager-Account-Verbindungen. Spalten: id, workspace_id (CASCADE), provider (google_mcc | microsoft_agency | meta_business_manager | linkedin_campaign_manager), manager_account_id (Provider-spezifischer Identifier wie Google MCC Customer ID oder Microsoft Customer ID — seit PROJ-1994 auch bei Microsoft direkt beim Connect gesetzt), manager_account_name, source_oauth_connection_id (FK SET NULL → social_oauth_connections — bei Meta/LinkedIn Reuse), source_mcc_connection_id (FK SET NULL → workspace_mcc_connections — bei Google Reuse), refresh_token_encrypted + access_token_encrypted (AES-256-GCM — für Microsoft direkt gespeichert mit MICROSOFT_OAUTH_ENCRYPTION_KEY; seit PROJ-1472 zusätzlich für Meta-System-User-Tokens mit eigenem META_SYSTEM_USER_ENCRYPTION_KEY bei auth_method=system_user, sonst NULL), auth_method (PROJ-1472: oauth | system_user — kennzeichnet ob die Verbindung über einen Human-OAuth-Login oder einen manuell hinterlegten, langlebigen Meta-System-User-Token läuft; System-User-Tokens werden vor dem Speichern serverseitig gegen die Meta Graph API validiert, niemals im Klartext geloggt und niemals in API-Responses oder im Datenexport ausgegeben), token_expires_at, scopes_granted (TEXT[]), is_active, connected_by (FK auf auth.users SET NULL), last_synced_at, last_error, Zeitstempel. UNIQUE auf (workspace_id, provider, manager_account_id, source_oauth_connection_id, source_mcc_connection_id) NULLS NOT DISTINCT (PROJ-1994 — erlaubt mehrere Manager pro Provider, verhindert Doppel-Connects desselben Managers). RLS: nur Workspace-Admin (SELECT/INSERT/UPDATE/DELETE).
- workspace_ads_accounts (PROJ-569 + PROJ-667): Discovery-Cache aller im Manager-Account verfügbaren Werbekonten — Spalten: id, workspace_id (CASCADE), manager_connection_id (CASCADE), provider (google_ads | microsoft_ads | meta_ads | linkedin_ads), provider_account_id, account_name, local_label (PROJ-667 — workspace-lokales Anzeige-Override, max 200 Zeichen, vom Admin manuell gepflegt; wird vom Discovery-Sync NICHT überschrieben), currency, metadata (JSONB für provider-spezifische Felder wie Account-Status, Time-Zone), is_available, last_synced_at, created_at. UNIQUE auf (manager_connection_id, provider_account_id). Befüllt durch Discovery-Cron (PROJ-570 — pro Provider eigener Cron alle 6h) und durch User-getriggerten Refresh-Endpoint (PROJ-667 POST /ads/discovered-accounts/:id/refresh-name — nur google_ads). RLS: SELECT für Admin/Manager, Schreibpfad für Discovery nur via Service-Role; PATCH /ads/discovered-accounts/:id für Admin+Manager. Inhalt: Geschäftsdaten der Account-Inhaber (juristische Personen) + technische Workspace-Bezeichnung (local_label) — kein End-User-Personenbezug.
- contact_ad_connections.manager_connection_id + discovered_account_id (PROJ-569 Erweiterung der bestehenden Junction-Tabelle, R-707): FK SET NULL auf workspace_ads_manager_connections / workspace_ads_accounts. Bestehende Einträge bleiben als Legacy-Direct-OAuth-Konten lesbar (NULL beider Spalten); neue Einträge nutzen die Manager-Verknüpfung. Bei Trennung der Manager-Verbindung werden zugehörige Zuweisungen auf is_active=false gesetzt — keine harte Löschung der Junction-Einträge (Audit-Erhalt).
- Notification matelso-ähnlich: ads_manager_connection_reauth_required (Token abgelaufen oder Permission entzogen — Empfänger Workspace-Admin, Inbox + Email), ads_account_no_longer_available (Konto im Provider-Backend gelöscht/deaktiviert — Empfänger Workspace-Admin/Manager, nur Inbox).
- Microsoft-OAuth-Tokens: AES-256-GCM verschlüsselt mit dediziertem MICROSOFT_OAUTH_ENCRYPTION_KEY (separater Schlüssel zur Trennung von INTEGRATION_ENCRYPTION_KEY). Format iv:authTag:ciphertext base64. R-630-Preflight-Check vor jedem Encrypt-/Decrypt-Call. Microsoft hat keinen public Revoke-Endpoint — bei Disconnect erfolgt nur DB-Markierung is_active=false; Token bleibt encrypted in der DB bis Workspace-Löschung.
- OAuth-State-Parameter: HMAC-SHA256-signiert (Schlüssel: OAUTH_STATE_SECRET, Fallback MICROSOFT_OAUTH_ENCRYPTION_KEY). State enthält workspace_id + user_id + provider + nonce. Verhindert CSRF beim Microsoft-Callback. State-Parameter ist transient — wird nicht persistiert.
- campaign_snapshots (PROJ-893, erweitert PROJ-1612): Tagesgenaue Performance-Snapshots je verbundenem Werbekonto/Kampagne — Spalten: id, workspace_id (CASCADE), connection_id, platform (google_ads | meta_ads | linkedin_ads | microsoft_ads — LinkedIn/Microsoft seit PROJ-1612), campaign_id, campaign_name, snapshot_date, spend_original/spend_converted, impressions, clicks, conversions, ctr, cpc, cpm, reach, budget_daily, extra_metrics (JSONB, PROJ-1612 — Auffangbecken für netzwerkspezifische Zusatzkennzahlen jenseits der festen Spalten, initial ungenutzt). Befüllt durch täglichen Cron (ads-import.ts, seit PROJ-1612 letzte 3 Tage Recency-Refresh statt nur 'gestern') sowie On-Demand-Backfill (POST /api/ads/backfill, GET /api/ads/campaign-snapshots/ensure-range). RLS: SELECT für Workspace-Mitglieder, Schreibpfade nur Admin-Rolle bzw. Service-Role. Inhalt: reine Geschäfts-/Kampagnen-Kennzahlen (Spend, Impressions, Klicks etc.) — kein End-User-Personenbezug.
- campaign_snapshot_backfill_jobs (PROJ-1612): Lazy-Load-Warteschlange für große Tages-Nachlade-Lücken — Spalten: id, workspace_id (CASCADE), connection_id, connection_source, platform, start_date/end_date, status, processed_until, attempts, last_error, requested_by (FK auf auth.users SET NULL — Agentur-Mitglied das den Report-Aufruf ausgelöst hat), Zeitstempel. RLS: SELECT für Workspace-Mitglieder (Nachlade-Fortschritt sichtbar), Schreibpfade nur Service-Role. Automatische Löschung abgeschlossener/fehlgeschlagener Jobs nach 30 Tagen durch den Worker-Cron selbst (kein separater Retention-Cron nötig).
- PROJ-2293 Meta-Ad-Analyse — Video-Insights + Zielgruppen-Segmente: Zusätzlich zu den bestehenden Performance-Kennzahlen werden für Meta-Video-Anzeigen zwei additive, nullable Spalten auf ad_snapshots befüllt (video_3_sec_views, video_thruplay_watched — reine Zähl-Kennzahlen ohne Personenbezug, Creative-Wirkung-Funnel AC-7). Zusätzlich wird über die neue Tabelle ad_audience_segments je Meta-Anzeigengruppe/Tag die Verteilung der Impressionen/Reichweite nach den von Meta gelieferten Alter×Geschlecht-Buckets gespeichert (Zielgruppen-Sektion AC-8) — aggregierte Bucket-Kennzahlen auf Anzeigengruppen-Ebene, keine Einzelperson-Datensätze, kein Profiling (DSFA-Prüfung: NEIN). Schema/RLS von ad_audience_segments spiegeln bewusst die bestehende, bereits erfasste ad_placement_snapshots 1:1. Kein neuer externer Auftragsverarbeiter (dieselbe Meta Graph API `/insights`, nur erweiterter fields-/breakdowns-Parameter, kein neuer OAuth-Scope). Retention: täglicher Cleanup-Cron cleanup-ad-audience-segments (13 Monate, analog ad_snapshots/ad_placement_snapshots).
- PROJ-2200 Anzeigen-Inhalt + Creative-Thumbnails (ad_creatives): Anzeigen werden ab PROJ-2200 zusätzlich zu den reinen Performance-Kennzahlen inhaltlich identifizierbar gemacht — je Anzeige (connection_id + ad_id + platform) werden Anzeigentyp-Label, Landingpage-URL (final_url), RSA-Headlines/Descriptions (rsa_assets, Google) sowie Produkt-Titel/Item-ID (Shopping/PMax) gespeichert. Zusätzlich wird das Meta-/Display-Creative-Thumbnail beim Ingesten von der externen, flüchtigen CDN-URL in den privaten Supabase-Storage-Bucket ad-creatives (EU) gespiegelt (thumbnail_path) — dauerhafte Vorschau statt ablaufender Fremd-URL. Thumbnails sind fremde, von Google/Meta/Microsoft ausgelieferte Werbe-Creatives und können Personenabbildungen (Models/Personen) enthalten. Lesezugriff ausschließlich über kurzlebige signierte URLs (3600s), kein öffentlicher Bucket-Zugriff. RLS: SELECT für Workspace-Mitglieder, INSERT/UPDATE/DELETE nur Admin-Rolle bzw. Service-Role (Enrichment-/Cleanup-Cron). Kein neuer externer Auftragsverarbeiter — Bild-Download erfolgt von denselben, bereits als PROCESSOR erfassten Werbeplattformen (Google/Meta/Microsoft), Speicherung nutzt bestehende Supabase-Storage-Infrastruktur. Retention: verwaiste Bild-Objekte (Zeile gelöscht oder beim Refresh ersetzt) werden nach ≤14 Tagen vom täglichen Cleanup-Cron proj2200-ad-creatives-cleanup entfernt. PROJ-2233: Die Anreicherung wird vertieft — zusätzlich zur bisherigen Text-/Thumbnail-Ebene wird je Anzeige eine platform-diskriminierte Creative-Struktur (creative_payload, JSONB) persistiert: Google RSA-Headlines/Descriptions mit Pinning/Label, Meta Primary-Text/Headline/Description/Carousel-Karten inkl. object_story_spec-Seiten-/Akteurs-Referenzen und Media-Verweisen, Microsoft Titel-/Beschreibungsteile + Landingpage-URL. Diese Inhalte sind fremde Werbe-Creatives und können personenbezogene Daten tragen (Personenabbildungen/Namen/Testimonials in Bild/Video/Text, personenbezogene Landing-/Tracking-URLs). Kein neuer externer Auftragsverarbeiter (dieselben bereits erfassten Werbeplattformen Google/Meta/Microsoft, Meta-/Microsoft-Anreicherung nur auf dem Prod-Worker mit gesetztem INTEGRATION_ENCRYPTION_KEY). Ein Pro-Anzeige-Zustandsmodell (enrichment_status) unterscheidet erfolgreich/teilweise/fehlgeschlagen/nicht-mehr-abrufbar. Zusätzliche Retention (PROJ-2233 F-3): Zeilen, deren Quell-Anzeige nicht mehr existiert (enrichment_status='deleted_at_source'), werden nach 90 Tagen ohne neuen erfolgreichen Abruf vom selben Cleanup-Cron samt gespiegeltem Thumbnail gelöscht — der letzte bekannte Stand wird nicht unbegrenzt vorgehalten.
PROJ-1876/PROJ-1894/PROJ-1895 Werbekonten-Änderungshistorie als Ereignisquelle (Google Ads, Microsoft Ads, Meta Ads)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an der Nachvollziehbarkeit der eigenen Vermarktungsarbeit sowie an der Unterscheidung agenturseitiger von kundenseitigen Eingriffen — ohne diese Zuordnung ist eine Leistungsentwicklung im Werbekonto nicht erklärbar). Für die Auslieferung einzelner, ausdrücklich freigegebener Ereignisse an den Kunden zusätzlich Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung — Transparenz über Agenturtätigkeit). Soweit die eingestufte Person ein Agentur-Beschäftigter ist: § 26 Abs. 1 Satz 1 BDSG i.V.m. Art. 6 Abs. 1 lit. f DSGVO (Durchführung des Beschäftigungsverhältnisses). Eine Verhaltens- oder Leistungskontrolle von Beschäftigten ist ausdrücklich NICHT Zweck dieser Verarbeitung; die Zweckbindung ist im Löschkonzept festgehalten. Auftragsverarbeitung gemäß Art. 28 DSGVO mit Google LLC (siehe PROCESSORS-Eintrag `Google LLC`, Abschnitt Google Ads API) — bestehender AVV aus PROJ-17/PROJ-272/PROJ-569 gilt unverändert —, mit Microsoft Corporation (siehe PROCESSORS-Eintrag `Microsoft Corporation`) — bestehender AVV aus PROJ-569/PROJ-1612 gilt unverändert — sowie mit Meta Platforms Inc. (siehe PROCESSORS-Eintrag `Meta Platforms Inc.`) — bestehender AVV aus PROJ-135/PROJ-569 gilt unverändert.
- Bei Google und Microsoft — Urheber-Adresse im Klartext: bei Google `change_event.user_email`, bei Microsoft `ChangedBy` (E-Mail-Adresse; bei `ChangedBy = Administrator` gilt die Zeile als Systemänderung und wird verworfen, nicht als Person eingestuft). Wird von der jeweiligen Werbeplattform mit jeder Änderung mitgeliefert und daher zwangsläufig verarbeitet (Erheben/Auslesen), aber NICHT GESPEICHERT: Sie wird ausschließlich an den gemeinsamen Einstufungs-Baustein `src/lib/ads/actor-classification.ts` übergeben, dort mit den Adressen der aktiven Workspace-Mitglieder verglichen und danach mit dem Ende der Cron-Verarbeitung verworfen. Sie erscheint weder im Ereignis (Titel, Beschreibung, Zusatzangaben) noch in Anwendungs- oder Fehlerprotokollen — für Google verifiziert im DSGVO-Lauf 01.08.2026 (AC-E1), für Microsoft im DSGVO-Lauf 02.08.2026 (AC-E1) inkl. der Erstlauf-Diagnosemeldung `MsChangeHistoryFirstRunValues`, die die Adresse ausdrücklich nicht mitprotokolliert. `src/lib/ads/actor-classification.ts` wird für Meta NICHT verwendet (bewusst unverändert, Tech Design PROJ-1895) — der nächste Absatz beschreibt Metas eigenständigen, abweichenden Mechanismus.
- Bei Meta — Urheber-Klarname (`actor_name`): anders als bei Google/Microsoft liefert Meta hier keine E-Mail-Adresse, sondern einen echten Klarnamen. Er wird bei jeder Zeile mitgeliefert (Erheben/Auslesen), aber von KEINER Funktion des Feature-Codes gelesen oder weiterverarbeitet — der Vergleichs-/Einstufungsschritt (`classifyMetaActor()`) ist bei Meta eine feste Konstante ohne Eingabeparameter und benötigt den Namen nicht. Verifiziert im DSGVO-Lauf 03.08.2026 (AC-E1) per repoweitem Grep auf `.actorName` — außer der einen Zuweisung beim Einlesen der Antwort (`meta-activity-log.ts`) gibt es keine einzige Lesestelle; er erscheint in keinem Log, keiner Fehlermeldung, keinem Ereignis und keiner Zusatzangabe.
- Bei Meta — numerische Urheber-Kennung (`actor_id`): wird, anders als der Klarname, tatsächlich zur Laufzeit ausgewertet — aber nur flüchtig und nur als Zähl-/Vergleichswert, nie als gespeicherter Identifikator. Pro Cron-Lauf und Konto sammelt `crons/meta-change-history.ts` die `actor_id`-Werte der durchgelassenen (menschlichen) Zeilen in einer reinen Arbeitsspeicher-Menge (`distinctActorIds`); enthält diese Menge mehr als einen Wert, wird NUR die Anzahl (`distinct_actor_count`) in eine interne Beobachtungsmeldung (`MetaChangeHistoryMultipleActors`) geschrieben, niemals die Kennung selbst. Die Menge wird am Ende jedes Laufs verworfen — es gibt kein Datenbankfeld, in dem `actor_id` über einen Lauf hinaus fortbesteht (Tech Design: „Datenbank-Änderung: genau eine“ — nur die Quellen-Liste, kein neues Feld). Einordnung: Damit ist `actor_id` Gegenstand einer Verarbeitung im Sinne von Art. 4 Nr. 2 DSGVO (Erheben, Vergleichen), aber nicht des Speicherns.
- Abgeleitete Urheber-Einstufung (`customer_timeline_events.metadata.actor`): bei Google und Microsoft genau drei Werte — `agentur`, `kunde`, `unbekannt`, per zweistufiger Ableitung über die Adresse des Urhebers (1. aktives Workspace-Mitglied, 2. Domain-Übereinstimmung mit einem aktiven Mitglied, Freimail-Domains ausgenommen), sonst `kunde`; fehlt die Angabe, `unbekannt` — es wird in keine Richtung geraten. Bei Meta ist der Wert IMMER `agentur` (Entscheidung 03.08.2026: kein `kunde`-Zweig, da Meta keine Adresse liefert, an der die zweistufige Ableitung ansetzen könnte, und der Automatik-Filter — Vorhandensein von `application_name` — bereits maschinelle Änderungen aussortiert; ein bislang ungesehener Urheber löst stattdessen die oben beschriebene reine Beobachtungsmeldung aus, KEINE Reklassifizierung zu `kunde`/`unbekannt`). ⚠️ NACHTRAG 03.08.2026 (Post-Deploy-Bugfix): Die ursprüngliche Begründung „die Live-Zählung fand genau einen menschlichen Urheber“ ist widerlegt — in einem Konto arbeiteten zwei Personen (117 bzw. 2 Zeilen in 28 Tagen). Beide werden weiterhin als `agentur` geführt; ob die zweite zur eigenen Agentur, zu einer fremden Agentur oder zum Kunden gehört, kann derzeit nicht entschieden werden. Behoben ist bislang nur, dass der Fall nicht mehr unbemerkt bleibt (Meldung beim ersten Auftreten statt nur bei zwei Urhebern im selben 3-Tage-Fenster). Eine belastbare Unterscheidung braucht eine gepflegte Zuordnungsliste eigener Kennungen und ist als eigenes Vorhaben offen — bis dahin gilt die Einstufung bei Meta ausdrücklich als ANNAHME, nicht als Feststellung. Einordnung: Der gespeicherte Wert allein identifiziert niemanden, ist aber bei Google/Microsoft in Verbindung mit Zeitpunkt, Werbekonto und Kampagne durch Zusatzwissen (Zuständigkeit im Team, plattformseitige Änderungshistorie mit Klarnamen für 30 Tage bei Google bzw. bis zu 6 Monate bei Microsoft) einer Person zuordenbar und wird deshalb als PSEUDONYM und nicht als anonym behandelt (ErwG 26 DSGVO). Bei Meta ist der Wert ein reiner, für alle Zeilen identischer Konstantentext ohne individualisierende Information und damit selbst kein Personenbezug — der Personenbezug bei Meta entsteht ausschließlich in der flüchtig verarbeiteten `actor_id` (siehe oben), nicht in diesem gespeicherten Feld.
- Ads-Ereignisse in `customer_timeline_events` (PROJ-1860): Quelle `google_ads`, `microsoft_ads` oder `meta_ads`, dieselben elf plattform-neutralen Ereignistypen für alle drei Netzwerke (`ads_campaign_created`, `ads_campaign_status_changed`, `ads_campaign_removed`, `ads_budget_changed`, `ads_bidding_changed`, `ads_targeting_changed`, `ads_ad_group_created`, `ads_ad_group_removed`, `ads_ad_group_status_changed`, `ads_creatives_changed`, `ads_settings_changed` — Entscheidung 02.08.2026: kein netzwerkeigener Ereignistyp, das Netzwerk steht ausschließlich in `source`), Ereigniszeitpunkt (echter Änderungszeitpunkt beim Werbenetzwerk — bei Meta bereits mit Zeitzonen-Versatz geliefert, keine separate Zeitzonen-Auflösung nötig; bei Microsoft mangels verlässlicher Kampagnen-Zeitzone dokumentierter GMT-Rückfall), Titel und Beschreibung (Kampagnen-, Anzeigengruppen-, Budget- und Kontoname sowie alter/neuer Betrag). Sichtbarkeit entsteht IMMER als `intern`; kundensichtbar wird ein einzelnes Ereignis nur durch die ausdrückliche Freigabe eines angemeldeten Agentur-Mitglieds über den bestehenden Freigabe-Weg aus PROJ-1860. Es gibt keinen automatischen Pfad zu `visibility = kunde`.
- Interne Zusatzangaben je Ereignis (`metadata`): Werbekonto-Kennung, Kontoname, Kampagnen-Kennung(en) — bei Budget-Ereignissen als Liste —, Budget-Kennung, alter und neuer Betrag, Anzahl gebündelter Einzeländerungen sowie die Urheber-Einstufung. Diese Angaben werden dem Kunden AUCH NACH FREIGABE nie ausgeliefert: Die Kunden-Route baut jedes Element über eine Positivliste von Feldern neu auf, in der `metadata`, `source_id` und `source_type` nicht enthalten sind — für Microsoft im DSGVO-Lauf 02.08.2026 zusätzlich am Smoke-Test (`scripts/proj1894_microsoft_mapper_smoke.ts`, Test #18) in beide Richtungen belegt, für Meta im DSGVO-Lauf 03.08.2026 durch unveränderte Positivliste (`client-visible.ts`, Tech Design: „Ausdrücklich nicht angefasst“) in beide Richtungen bestätigt.
- Bei Microsoft zusätzlich serverseitig ausgeschlossen, bevor die Daten überhaupt bei NEULAND. OS ankommen (`ItemChanged`-Filter `Campaign AdGroup Ad Keyword`): die Objektart `User` (E-Mail-Adresse, Vor- und Nachname von Personen im Klartext) und die Objektart `Account` (Zahlungsart, Rechnungsempfänger, Finanzstatus, Ausgabenlimit des Kunden). Ein Nachlauf-Check (`MsChangeHistoryForbiddenItem`) protokolliert, falls eine dieser Objektarten den Filter dennoch passiert — dann nur die Objektart als Zeichenkette, nie die enthaltenen Werte. Bei Meta gibt es keinen serverseitigen Objektart-Filter (die Schnittstelle liefert diesen nicht) — hier übernimmt stattdessen der clientseitige, VOR jeder Zuordnung greifende Positivlisten-/Ausschlusslisten-Filter aus `meta-activity-mapper.ts` (AC-B1–B4) dieselbe Aufgabe für Abrechnungs- und Konto-Ereignisse.
- Vergleichsbasis für die Einstufung bei Google/Microsoft: E-Mail-Adressen der aktiven Mitglieder des Agentur-Workspace, einmal je Cron-Lauf und Workspace über die bestehende Datenbankfunktion `get_user_emails` (auth.users, Admin-Client) geladen. Sie werden ausschließlich im Arbeitsspeicher des Laufs gehalten, nicht persistiert und nicht protokolliert. Kann die Liste nicht geladen werden, meldet der Baustein für alles `unbekannt` (fail-safe, keine Vermutung). Bei Meta entfällt dieser Schritt vollständig (keine Vergleichsbasis nötig, siehe oben).
- `contact_ad_connections.change_history_last_success_at`: technischer Zeitstempel des letzten erfolgreichen Historie-Abrufs je Verbindung (Erstlauf- und Lücken-Erkennung), gilt für alle drei Netzwerke. Kein Personenbezug.
- `contact_ad_connections.change_history_known_actor_hashes` (nur Meta, seit dem Post-Deploy-Bugfix 03.08.2026): Liste bereits gesehener Urheber je Verbindung, gespeichert NICHT als Meta-Kennung, sondern als je Verbindung gesalzener SHA-256-Auszug davon (Salz = die Verbindungs-UUID, gekürzt auf 16 Hex-Zeichen, höchstens 200 Einträge). Zweck ist ausschließlich die Frage „in DIESER Verbindung schon einmal gesehen?“ — nötig, weil die zuvor gebaute Meldung nur zwei Urheber im SELBEN 3-Tage-Fenster erkannte und dadurch faktisch nie auslöste (live belegt: ein zweiter Mensch verursachte 2 von 179 Zeilen in 28 Tagen). Einordnung: Ohne die Verbindungs-UUID ist der Auszug nicht auf die Kennung rückrechenbar, und dieselbe Person erzeugt in zwei Verbindungen unterschiedliche Auszüge — eine Wiedererkennung über Konten, Kunden oder Workspaces hinweg ist damit ausgeschlossen. Innerhalb einer Verbindung bleibt der Wert ein PSEUDONYM im Sinne von ErwG 26 DSGVO und wird als solches behandelt: Er wird nie angezeigt, nie protokolliert und nie an den Kunden ausgeliefert; die Beobachtungsmeldung nennt ausschließlich Anzahlen.
- Richtung Werbeplattform übermittelt werden ausschließlich: Werbekonto-Kennung, Zeitfenster und der Gegenstands-Filter der Abfrage — keine personenbezogenen Daten und keine Endnutzerdaten. Der Personenbezug entsteht allein in der ANTWORT der jeweiligen Plattform.
PROJ-1890/PROJ-1891 SEO / GEO Research — Ad-hoc-Recherche ohne Projektbezug
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Marktbeobachtung und an der Vorbereitung von Vertriebsgesprächen). Ausschließlich interner Agentur-Workflow — der Kunde erhält keine dieser Auswertungen. Der fachliche Gegenstand sind Domains, Suchbegriffe und Suchmaschinen-Positionen; das sind Unternehmens- und Sachdaten, keine personenbezogenen Daten.
- `research_analysis_sets`: Name der Recherche, Zieldomain, optionaler Kontaktbezug, Lebenszyklus-Status, Ablaufdatum, letzter Zugriff, Datenherkunft und Datenstand, das Wettbewerbsfeld je Domain mit Herkunfts-Kennzeichnung (`ssot_wettbewerber` / `serp_wettbewerber`), Versionskennung der Volumen-Baseline, Favoriten-Kennzeichnung (`is_favorite`) sowie `created_by` als Verweis auf das anlegende Agentur-Mitglied.
- `research_keywords`: Suchbegriff, eingefrorenes Suchvolumen, Klickpreis, Wettbewerbsgrad, Suchabsicht (`search_intent`), Herkunft des Eintrags und optionaler Verweis auf ein Marketingziel. Öffentliche Suchbegriffe ohne Personenbezug.
- `research_rankings`: Domain, Rolle (Ziel oder Wettbewerber), Herkunft der Wettbewerber-Domain, Position, gefundene URL und Messzeitpunkt. Öffentlich abrufbare Suchergebnisse ohne Personenbezug.
- `research_fetch_jobs`: Umfang, Fortschritt, Fehlschläge und Kosten eines Frischabrufs, samt auslösendem Agentur-Mitglied und Bestätigungszeitpunkt.
- GELESEN, nicht gespeichert: Ereignisse aus `customer_timeline_events` für die Marker im Verlaufsdiagramm — ausgeliefert werden ausschließlich Zeitpunkt, Ereignistyp, Wichtigkeit, Titel und Quelle. Das Feld `metadata`, das die Urheber-Einstufung (`agentur` / `kunde` / `unbekannt`) enthält, wird bewusst NICHT selektiert und verlässt den Server über diesen Weg nicht. Es entsteht keine Kopie und kein neuer Speicherort für diese Einstufung.
- An DataForSEO übermittelt werden ausschließlich Suchbegriff, Domain, Zielregion und Sprache. An Anthropic (Keyword-Universum) ausschließlich der Suchbegriff und die Zieldomain — keine Freitexte aus der Datenbank, keine Kundendaten.
PROJ-1880 Erkennung toter Werbekonto-Verbindungen
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an funktionsfähiger Leistungserbringung: Eine Werbekonto-Verbindung, die keine Daten mehr liefert, führt sonst unbemerkt zu falschen Auswertungen gegenüber dem Kunden). Ausschließlich interner Agentur-Workflow — der Kunde erhält keine dieser Meldungen.
- `contact_ad_connections.last_successful_import_at`: technischer Zeitstempel des letzten Imports, der tatsächlich Daten geliefert hat (Bezugspunkt für „seit N Tagen keine Daten“). Kein Personenbezug.
- Meldungstyp `ads_connections_stale_digest` in `notifications` (wöchentliche Sammelmeldung): Titel, Nachrichtentext und `metadata.connections[]` nennen die betroffenen Verbindungen mit Kontaktname (`contact_name`), Kontakt-Kennung (`contact_id`), Plattform, Werbekonto-Kennung, Ausfalldauer in Tagen und übersetzter Klartext-Ursache. Empfänger sind ausschließlich admin/manager des Agentur-Workspace. Der ROHE Fehlertext des Anbieters wird bewusst NICHT ausgeliefert — er dient nur als Eingabe der Übersetzung in `src/lib/integrations/ads-connection-state.ts` und ist seit dem DSGVO-Lauf 02.08.2026 aus allen API-Antworten entfernt.
- Zwei neue Ereignistypen in der bestehenden `activity_log`-Tabelle: `ads_connection_decommissioned` und `ads_connection_reactivated` (`entity_type='contact'`, `entity_id`=Kontakt, `actor_id`=handelndes Agentur-Mitglied, `metadata` mit Verbindungs-Kennung, Plattform, Werbekonto-Kennung/-Name sowie Ausfalldauer und Ursache zum Zeitpunkt der Entscheidung). Zweck ist die Nachvollziehbarkeit, wer eine Verbindung wann stillgelegt oder wieder aktiviert hat.
PROJ-581 Contao Hub — Sites & Tickets (Phase 1)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an strukturiertem Bug-Reporting und zentraler Verwaltung der Contao-Kundensites — ohne diese Datenhaltung wären weder die effiziente Wartung noch das Tracking von Vorfällen über die Site-Lebensdauer möglich). Die Verarbeitung dient ausschließlich dem internen Agentur-Workflow.
- contao_sites (PROJ-581): Stammdaten einer betreuten Contao-Installation. Spalten: id, workspace_id (CASCADE), customer_id (nullable, FK später), name, url, server_alias, subscription_name (Plesk), php_version, contao_version, status (active/migration/sunset), vault_item_id (FK SET NULL → vault_items für Server-Zugang), notes (max 8000 Zeichen, optional), last_audit_at, Zeitstempel + created_by. RLS: nur Agentur-Workspace mit Rolle admin oder manager. Member dürfen NICHT lesen (Vault-Verknüpfung schützt Server-Credentials).
- contao_tickets (PROJ-581): Strukturierter Bug-Report bzw. Featurewunsch zu einer Site. Spalten: id, workspace_id (CASCADE), site_id (FK NOT NULL, ON DELETE RESTRICT), status (Pipeline new→triage→in_progress→testing→deployed→closed, bidirektional), severity (p1–p4), severity_suggested + bundle_suggested (KI-Triage-Vorschläge analog PROJ-260), title, description, steps_to_reproduce, expected, actual, browser (Auto-Detection aus User-Agent), console_output (max 64KB application-side), screenshot_url, git_link, created_by (NOT NULL, FK profiles), assigned_to (FK profiles), Zeitstempel inkl. closed_at, ai_analyzed_at. **Potenzielle PII** kann durch Reporter-Eingaben entstehen (Description, Steps-to-reproduce, Console-Output) — Reporter werden im Submit-Modal explizit darauf hingewiesen, keine Klartext-Passwörter, Kunden-Personendaten oder Tokens einzufügen. RLS: SELECT für admin/manager im Agentur-Workspace ODER Reporter sieht eigenes Ticket (created_by = auth.uid()); INSERT für alle aktiven Member; UPDATE wie SELECT; DELETE nur admin.
- contao_ticket_status_log (PROJ-581): Audit-Trail jedes Pipeline-Status-Wechsels. Spalten: id, ticket_id (CASCADE), from_status, to_status, comment (optionaler Kommentar zur Begründung), changed_by (FK profiles), changed_at. RLS: Lesen wie Tickets. Schreiben ausschließlich via Backend-Service-Role (kein Client-Insert) — verhindert Manipulation des Audit-Trails.
- vault_items.type_slug='server-access' (PROJ-581 Erweiterung): Neuer Vault-Item-Type für Server-Zugangsdaten (SSH-Host, SSH-User, SSH-Key-Pfad, Plesk-Panel-URL/User/Passwort, optional DB-Credentials). Verschlüsselung erfolgt mit der bestehenden Zero-Knowledge-Architektur aus PROJ-254 (AES-256-GCM, Master-Kennwort-abgeleiteter Schlüssel). Server speichert ausschließlich verschlüsselte Daten — keine Klartext-Sichtbarkeit ohne Master-Pass-Entsperrung. Audit-Log über Vault-Read-Operationen ist Teil der Vault-Mechanik (PROJ-254/566).
- Notifications (PROJ-581): drei neue Typen — contao_ticket_new (Empfänger Default-Assignee), contao_ticket_deployed (Empfänger Reporter), contao_ticket_p1_alert (Empfänger alle Agentur-Admins). Inhalt: Ticket-ID + Title + Severity + Site-Name (kein PII über Reporter-Texte hinaus, das über die Notification ohnehin zugänglich wäre).
- PROJ-582 Bundle-Registry (contao_bundles, contao_site_bundles, contao_sync_log): Speichert pro Agentur-Workspace die Liste der eigenen Composer-Bundles (vendor='neulandagentur') als Stammdaten (Vendor, Name, Repo-URL, optional Beschreibung) sowie pro Site die Liste aller installierten Composer-Pakete inkl. Vendor/Name/Version (own + external) und Sync-Audit-Logs (Start-/End-Zeitstempel, Outcome, Bundles-Counter, Fehlertext bei Misserfolg). Quelle der Daten: composer.lock-Dateien, die per SSH vom betreuten Server gelesen werden (PROJ-582 Phase 2 Cron + manueller Re-Sync), sowie ein optionaler Initial-Seed aus dem agentur-eigenen Satis-Composer-Repository (https://packages.neuland-agentur.com). Es werden ausschließlich technische Bundle-Versions-Strings und Repo-URLs erfasst — KEINE PII der Endkunden. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an strukturiertem Bundle-Tracking für Wartung, Sicherheits-Patches und Kompatibilitäts-Übersicht). RLS: Admin/Manager/Member SELECT auf contao_bundles + contao_site_bundles + contao_sync_log; INSERT/UPDATE/DELETE nur Admin/Manager (für Bundle-Stammdaten); contao_site_bundles + contao_sync_log werden ausschließlich per Service-Role durch den Sync-Cron geschrieben. Workspace-scoped (contao_bundles direkt via workspace_id; contao_site_bundles + contao_sync_log indirekt via contao_sites.workspace_id). CASCADE-DELETE bei Site-/Workspace-Löschung.
- Notifications (PROJ-582): ein neuer Typ — contao_site_sync_failed (Empfänger: Agentur-Admins; ausgelöst nach 3 aufeinanderfolgenden fehlgeschlagenen composer.lock-Pulls auf der gleichen Site). Inhalt: Site-ID, Site-URL, letzte Fehlermeldung. Kein PII.
- PROJ-585 Site Console (contao_site_operations): Audit-Log aller Write-Operationen aus dem Site-Console-Tab (Composer-Update, Cache-Clear, Form-Settings), der Phase-2-Recovery-Operationen (Cache-Clear/Warmup, Permissions-Fix, Composer-Install, Composer-Require, Contao-Migrate, Assets-Install, Combined-Cleanup, Bundle-File-Upload) sowie des PROJ-597 DB-Migration-Pre-Checks (migrate_check via contao:migrate --dry-run). Felder: id, workspace_id (CASCADE), site_id (FK CASCADE), operation_type (composer_update/cache_clear/form_settings + recovery_cache_clear/recovery_cache_warmup/recovery_permissions_fix/recovery_composer_install/recovery_composer_require/recovery_contao_migrate/recovery_assets_install/recovery_combined_cleanup/recovery_bundle_file_upload + migrate_check), status (pending/success/failed/timeout), bundle_vendor, bundle_name, form_id, form_changes (JSONB mit den geänderten dlEnabled/dlConsentRequired/dlEvents bei Form-Settings — bei Recovery enthält form_changes die Recovery-Parameter pattern/bundle/file_paths/file_count, NIEMALS den Klartext der hochgeladenen Files), output (redaktiert: Bearer/password/API-TOKEN-Strings werden serverseitig durch [REDACTED] ersetzt, harte Begrenzung auf 10.000 Zeichen pro Eintrag), triggered_by (User-ID, NULL erlaubt im Tool-Modus), triggered_by_label (sprechendes Tool-Label im Format 'tool:<sha256-fingerprint>:<ip>' wenn die Operation per Bearer HUB_TOOL_TOKEN ausgelöst wurde — KEIN Klartext-Token, nur 12-Hex-Fingerprint der ersten 8 Token-Zeichen), duration_ms, started_at, finished_at. Output kann theoretisch redaktierte Log-Auszüge mit personenbezogenen Daten aus Contao-Form-Submissions oder System-Stack-Traces enthalten — daher 90-Tage-Retention statt unbegrenzter Aufbewahrung. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Auftragsverarbeitung der Wartung + Audit-Trail für Plausibilität). RLS: Admin/Manager SELECT only, KEIN Member-Read. INSERT/UPDATE ausschließlich per Service-Role durch die Console-Routen (kein Client-Insert). Workspace-scoped (direkter workspace_id-Filter in jeder Route). CASCADE-DELETE bei Workspace- bzw. Site-Löschung. Retention: 90 Tage Hard-Delete via Cron contao-site-operations-cleanup (PROJ-585 Phase 1). Phase 2 (Tool-Modus): Auth via 64-stelligem Bearer-Token HUB_TOOL_TOKEN; nur am Recovery-Endpoint angenommen, Token-Wert wird NIEMALS in Logs oder DB gespeichert.
- PROJ-586 Bundle-Bootstrap (contao_bundle_operations): Audit-Log aller GitHub-Bootstrap-Operationen aus dem Contao Hub. Felder: id, workspace_id (CASCADE), bundle_id (FK contao_bundles ON DELETE SET NULL — bleibt nach Bundle-Löschung als historischer Audit-Eintrag erhalten), operation_type (bootstrap; Phase 2.5 erweiterbar auf archive/transfer/rename; PROJ-1444 ergänzt satis_registration), triggered_by (FK auth.users — User-ID, kein Klartext-Name), repo_url (varchar 500, gesetzt sobald GitHub-Repo existiert), status (pending/success/failed), error_message (sprechende deutsche Fehlermeldung bei status='failed'), output (redaktiert: GitHub-API-Responses mit Bearer/token/Authorization/github_pat_/ghp_/ghs_/gho_-Strings werden serverseitig durch [REDACTED] ersetzt, harte Begrenzung auf ca. 10.000 Zeichen pro Eintrag), duration_ms, started_at, finished_at. Personenbezug: ausschließlich triggered_by (User-ID des auslösenden Admins) + Co-Author-E-Mail im Initial-Commit auf GitHub-Seite (siehe GitHub-PROCESSORS-Eintrag). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Audit-Trail für Bundle-Lebenszyklus + Diagnose-Daten bei GitHub-Failures). RLS: Admin/Manager SELECT only auf eigenen Workspace, KEIN Member-Read. INSERT/UPDATE ausschließlich per Service-Role durch den Bootstrap-Endpunkt (kein Client-Insert). Workspace-scoped (direkter workspace_id-Filter). Retention: 90 Tage Hard-Delete via Cron contao-bundle-operations-cleanup (PROJ-586 Phase 1, täglich 02:45 UTC) — operation_type-agnostisch, deckt auch satis_registration-Zeilen ab. PROJ-1444 (satis_registration): Nach jeder Bundle-Anlage (Bootstrap- und manueller Pfad) wird versucht, das Bundle bei der team-internen Satis-Paketverwaltung zu registrieren — im Unterschied zum bisher rein lesenden Zugriff auf packages.neuland-agentur.com (siehe PROJ-582 Bundle-Registry) erfolgt hier ein SCHREIBENDER SSH-Zugriff auf die satis.json des als is_satis_server markierten contao_servers-Eintrags sowie — PROJ-1454 — anschließend die Ausführung des dort hinterlegten Skripts satis-cron.sh zum sofortigen Rebuild (Zugangsdaten Vault-verschlüsselt, gleiches Muster wie bei Contao-Site-Servern; keine zusätzliche Datenübermittlung durch die Skript-Ausführung). Übermittelt werden ausschließlich technische Repo-Metadaten (Typ + Repo-URL) — keine PII.
- PROJ-943 Mehrsprachigkeit-Assistent (contao_i18n_checklists): Persistenter Abhak-Status des Checklisten-Workflows zur Anlage einer weiteren Sprachversion einer betreuten Contao-Site. Felder: id, workspace_id (CASCADE), site_id (FK contao_sites ON DELETE CASCADE), target_language (ISO-Sprachkürzel), steps (JSONB: pro Anleitungs-Schritt status open/done/na + done_by User-ID + done_at Zeitstempel), note (optionale Freitext-Notiz max 5.000 Zeichen), created_by (FK auth.users), created_at, updated_at. Personenbezug: ausschließlich done_by/created_by (User-IDs der bearbeitenden Agentur-Mitarbeitenden) sowie ggf. in note frei eingegebener Text. Stufe 1 ist read-only gegenüber der Contao-Site (nur dieser NEULAND-OS-seitige Checklisten-Status wird gespeichert). Der Live-Audit (Lesezugriff via SSH doctrine:query:sql) speichert KEINE Contao-Inhalte dauerhaft — pro Audit-Lauf nur ein redigierter Eintrag in contao_site_operations (operation_type='i18n_audit'). PROJ-949 Stufe 2 (Safe-Writes): admin/manager-Aktionen schreiben nach ausdrücklicher Bestätigung tl_page-Strukturfelder der betreuten Contao-Site (languageMain-Zuordnung, urlPrefix/language/dns/fallback, Root-Titel) — KEINE personenbezogenen Daten, ausschließlich CMS-Strukturkonfiguration. Jede Schreib-Aktion wird redigiert in contao_site_operations mit operation_type='i18n_apply' protokolliert (90-Tage-Retention, PROJ-585). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an strukturierter Wartungs-/Übersetzungs-Begleitung). RLS: Admin/Manager (Agency) SELECT only, KEIN Member-Read; INSERT/UPDATE/DELETE ausschließlich per Service-Role durch die Hub-Routen (kein Client-Write). Workspace-scoped (direkter workspace_id-Filter). CASCADE-DELETE bei Site- bzw. Workspace-Löschung. Ergänzend (contao_i18n_tree_prefs): pro Site je Root-Baum (Contao tl_page.id) ein manueller Status (target/hidden) zur Steuerung der Sprachbaum-Anzeige, mit created_by (User-ID). Gleiche Rechtsgrundlage, RLS und CASCADE-Logik.
- PROJ-1448 Mitarbeiter-SSH-Zugang (profiles.ssh_public_key + contao_ssh_grants + contao_ssh_sessions): Gibt Agentur-Mitarbeitern echten, aber nie root-fähigen SSH-Zugang auf die im Contao Hub verbundenen Kundenserver. profiles-Erweiterung: ssh_public_key (ein aktiver Public-Key pro Mitarbeiter, ed25519 oder RSA >= 3072 bit), ssh_public_key_fingerprint (SHA256), ssh_public_key_updated_at. contao_ssh_grants: id, site_id (FK CASCADE), workspace_id (CASCADE), user_id (FK auth.users — der Mitarbeiter), status (pending/active/pending_revoke/revoked/failed), grant_token (UNIQUE, Basis des authorized_keys-Markers, NIEMALS in API-Responses), granted_by/revoked_by (FK auth.users), granted_at/revoked_at, last_error, last_provisioned_at. Environment (preview/stage/live) ergibt sich aus der referenzierten Site, kein eigenes Feld. UNIQUE (user_id, site_id) WHERE status IN ('pending','active'). RLS: SELECT admin/manager (Agentur-Workspace) sowie der betroffene Mitarbeiter selbst (eigene Grants, read-only); INSERT/UPDATE ausschließlich Service-Role. contao_ssh_sessions: id, grant_id (FK CASCADE), site_id, workspace_id, user_id, started_at, ended_at, log_text (vollständiger, redaktierter Terminal-Mitschnitt einer SSH-Sitzung, gecappt bei 200.000 Zeichen), log_truncated, source_file (Idempotenz-Schlüssel des Sync-Crons, UNIQUE mit grant_id), source_ip, synced_at. **Besonders sensibel:** log_text kann personenbezogene Mitarbeiter-Verhaltensdaten (welcher Befehl wann) UND potenziell Ausschnitte aus Kunden-Datenbank-Abfragen enthalten, falls ein Mitarbeiter per SSH direkt auf die Contao-Datenbank zugreift — Zweckbindung ist ausschließlich IT-Sicherheit/Nachvollziehbarkeit von Änderungen an Produktivsystemen. Session-Logs werden vor dem Schreiben nach contao_ssh_sessions durch dieselbe Redaktionsfunktion wie PROJ-585 (redactSecrets — Bearer/Password/API-Token-Strings werden durch [REDACTED] ersetzt) gefiltert. RLS: SELECT nur admin/manager, KEIN Member-Read (auch nicht der eigene Mitarbeiter — Sessions können sensible Ausgaben Dritter enthalten). INSERT/UPDATE ausschließlich Service-Role via Sync-Cron. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Nachvollziehbarkeit von Produktivsystem-Änderungen) — aufgrund der systematischen Mitarbeiter-Verhaltensüberwachung ist eine DSFA empfohlen (Art. 35 Abs. 3 lit. c DSGVO, siehe docs/dsfa/PROJ-1448-ssh-session-recording.md). Provisionierung: Root-SSH-Verbindung des Servers (bestehende PROJ-581-Infrastruktur, kein neuer Secret-Speicherweg) trägt den Public-Key mit Forced-Command-Wrapper (command=... no-port-forwarding,no-X11-forwarding,no-agent-forwarding) in die authorized_keys des bestehenden Deploy-Users ein. Offboarding: Wird ein Mitarbeiter deaktiviert oder entfernt (workspace_members.is_active=false), werden automatisch alle seine Grants entzogen und die Keys von den Servern entfernt; Fehlschläge erzeugen eine Admin-Notification (contao_ssh_revoke_failed). Retention: 90 Tage Hard-Delete für contao_ssh_sessions via Cron contao-ssh-session-cleanup (täglich 03:40 UTC) — contao_ssh_grants bleiben als Vergabe-Historie ohne separate Retention bestehen (analog Grant-Historie anderer Berechtigungsfeatures), werden aber via CASCADE bei Site-Löschung entfernt.
- PROJ-1522 Server Health Monitoring (server_metrics): Zeitreihen-Messpunkte des Server-Infrastruktur-Monitorings — pro contao_servers-Eintrag alle 15 Minuten ein Messpunkt via Cron server-health-monitor (fest codierte Read-only-Whitelist-Befehle über den bestehenden execOnSite-Helper aus PROJ-585, kein Freitext im Befehls-String; authentifiziert mit den in contao_servers hinterlegten Zugangsdaten — in Produktion aktuell root für alle Server, identisches Modell wie der bereits deployte PROJ-585 Site-Console-Zugriff, Risikomitigation ausschließlich über die statische Befehls-Whitelist). Felder: id, server_id (FK contao_servers ON DELETE CASCADE), workspace_id (CASCADE), measured_at, reachable, error_text (SSH-Connect-/Auth-Fehlermeldung aus dem SSH-Client, nie Befehls-Output; gecappt bei 500 Zeichen), disk_used_pct, ram_used_pct, cpu_load_1m, cpu_cores, uptime_seconds, services (JSONB — feste Dienst-Namensliste mit systemctl-Status, kein Freitext), updates_available, overall_status (green/yellow/red/unreachable), alert_metrics (Cooldown-Basis der Schwellwert-Alarme), seit PROJ-1575 zusätzlich mysql_present + mysql_connections + mysql_running_processes + mysql_long_queries + mysql_longest_query_seconds (reine Aggregat-Zahlen aus der lokalen MySQL/MariaDB-Statusabfrage — NIEMALS SQL-Query-Volltexte, Prozess-Details oder Datenbank-Inhalte, PROJ-1575 AC-D6). Es werden AUSSCHLIESSLICH technische Infrastruktur-Metriken erfasst — KEINE personenbezogenen Daten, keine systematische Überwachung von Personen, keine automatisierten Entscheidungen über Personen (keine DSFA-Pflicht, Architektur-Einschätzung PROJ-1522 Tech Design Abschnitt 11). Notification-Typ server_health_threshold_alert (Empfänger: alle aktiven admin/manager der Agentur) enthält Server-Alias + Metrik-Werte, kein PII. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an proaktiver Verfügbarkeits-Überwachung der betreuten Kundenserver). RLS: SELECT nur admin/manager (Agentur-Workspace, is_active), KEIN Member-Read; INSERT/DELETE ausschließlich Service-Role via Crons (server-health-monitor + server-metrics-cleanup). Workspace-scoped. CASCADE-DELETE bei Server- bzw. Workspace-Löschung. Retention: 90 Tage Hard-Delete via Cron server-metrics-cleanup (täglich 03:50 UTC, R-153).
- PROJ-1575 Server-Advisor (server_capacities, server_dimension_checks, server_advisor_runs, server_advisor_findings + contao_servers-Fallback-Spalten): Erweiterung des Server-Bereichs um regelbasierte 4-Dimensionen-Checks (Updates/Sicherheit/Performance/Setup) und manuell angestoßene KI-Empfehlungen. server_capacities: eine Zeile je Server mit zuletzt erfolgreich ausgelesener Kapazität (mysql_max_connections, ram_total_mb, cpu_cores, disk_total_mb, je Wert eigener read_at-Zeitstempel) — reine Infrastruktur-Daten, kein PII. server_dimension_checks: eine Zeile je Server je Tages-Cron-Lauf (server-advisor-daily-check) bzw. je frischer Advisor-Probe — updates_total/security_updates/reboot_required, security_checks (JSONB: feste Check-Liste SSH-Passwort-Login/Root-Login/unattended-upgrades, je Check nur ok/warn/unknown + kurzer Allowlist-Wert, kein Freitext), setup_inventory (JSONB: geparste Versions-Strings OS/PHP/MySQL/Webserver; seit 30.07.2026 auf Plesk-Servern zusätzlich php_versions — je installierter PHP-Version die ANZAHL der Domains, die sie ausliefern, ausschließlich als Zählwert, ohne Domain- oder Kundennamen), berechnete Ampeln — kein PII. contao_servers-Erweiterung: vier optionale, von Admins gepflegte Fallback-Kapazitätswerte (fallback_mysql_max_connections, fallback_ram_total_mb, seit PROJ-1664 zusätzlich fallback_disk_total_mb + fallback_cpu_cores — analoges Muster, GB-Eingabe im Formular wird intern als MB gespeichert) — kein PII, reine Hardware-Spezifikationswerte. Ein neuer Effective-Value-Resolver (resolveEffectiveCapacityValue, seit PROJ-1664) berechnet aus server_capacities + den vier Fallback-Feldern effektive Absolutwerte für RAM/Disk/CPU, die in der Server-Health-Übersichtsliste neben dem bestehenden Live-Prozentwert angezeigt werden — keine neue Datenerhebung, nur eine Anzeige-Ableitung aus bereits erfassten Infrastruktur-Werten. server_advisor_runs: Job-Zeile je manuell angestoßenem KI-Analyse-Lauf mit started_by (User-ID des auslösenden admin/manager — Audit-Personenbezug), status, fresh_probe_ok, data_basis_at, findings_count, error_text, Zeitstempeln. server_advisor_findings: KI-Empfehlungen (dimension, priority, title, reasoning, impact — ausschließlich von der KI generierter Text über Infrastruktur-Messwerte) mit Freigabe-/Verwerfen-Audit decided_by (User-ID) + decided_at. KI-Verarbeitung (Anthropic Claude, bestehender PROCESSORS-Eintrag): An das LLM werden AUSSCHLIESSLICH Messwerte, Kapazitätswerte, Ampel-Status und Server-Alias/Hostname übermittelt — NIEMALS SSH-Zugangsdaten, Passwörter, Keys oder SQL-Query-Texte (PROJ-1575 AC-A7/AC-D6); der Advisor erzeugt ausschließlich Text-Empfehlungen, niemals ausführbare Befehle, und führt keine automatischen Aktionen aus (Freigeben = reine Status-Änderung mit Audit). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an proaktiver Wartung der betreuten Kundenserver); Personenbezug beschränkt sich auf die Audit-User-IDs der auslösenden/entscheidenden Agentur-Mitarbeiter. RLS: SELECT nur admin/manager (Agentur-Workspace, is_active), Schreibzugriff ausschließlich Service-Role (Crons + Advisor-Routen). Workspace-scoped, CASCADE-DELETE bei Server- bzw. Workspace-Löschung. Retention: server_dimension_checks + abgeschlossene server_advisor_runs 90 Tage (Cron server-metrics-cleanup); server_capacities eine Zeile je Server ohne Historie; server_advisor_findings ohne automatische Retention (Audit-Charakter, run_id ON DELETE SET NULL).
- PROJ-1743 Server-Advisor Phase 3 — Admin-SSH-Zugriff (profiles.admin_ssh_public_key* + server_admin_grants + server_admin_sessions) + Findings-Lifecycle-Erweiterung: Neues, von PROJ-1448 unabhängiges Berechtigungsmodell für vollen Root-Zugriff auf Server-Ebene (statt nicht-root Site-Subuser). profiles-Erweiterung: admin_ssh_public_key/admin_ssh_public_key_fingerprint/admin_ssh_public_key_updated_at — dediziertes, client-seitig erzeugtes Keypaar pro Mitarbeiter, getrennt vom bestehenden ssh_public_key (PROJ-1450, Site-Zugriff). server_admin_grants: id, server_id (FK contao_servers CASCADE), workspace_id (CASCADE), user_id (FK auth.users), status (pending/active/pending_revoke/revoked/failed), grant_token (UNIQUE, NIEMALS in API-Responses), pending_finding_id (FK server_advisor_findings SET NULL — technisches Zuordnungsfeld zwischen einem gestarteten Session-Start und der später aufgezeichneten SSH-Verbindung, kein PII), granted_by/revoked_by (FK auth.users), granted_at/revoked_at, last_error, last_provisioned_at. UNIQUE (user_id, server_id) WHERE status IN (pending/active/pending_revoke). RLS: SELECT admin/manager (Agentur-Workspace) sowie der betroffene Mitarbeiter selbst; INSERT/UPDATE ausschließlich Service-Role. server_admin_sessions: id, grant_id (FK CASCADE), server_id (FK CASCADE), workspace_id (CASCADE), user_id, finding_id (FK server_advisor_findings SET NULL), started_at, ended_at, log_text (vollständiger, redaktierter Terminal-Mitschnitt — höheres Risiko als PROJ-1448, da voller Root-Shell-Zugriff statt eines nicht-root Subusers, gecappt bei 200.000 Zeichen), log_truncated, source_file (Idempotenz-Schlüssel, UNIQUE mit grant_id), source_ip, synced_at. Erhoben über denselben Forced-Command-Wrapper wie PROJ-1448 (neuland-ssh-record) — bereits bestehende Infrastruktur, kein neues Recording-System. **Besonders sensibel (höheres Risiko als PROJ-1448):** log_text kann personenbezogene Mitarbeiter-Verhaltensdaten UND potenziell vollständige Kunden-Datenbank-Inhalte enthalten, da der Zugriff nicht auf einen nicht-root Subuser beschränkt ist. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Nachvollziehbarkeit von Produktivsystem-Änderungen) — DSFA-Pflicht analog PROJ-1448 (Art. 35 Abs. 3 lit. c DSGVO, systematische unausweichliche Mitarbeiter-Verhaltensüberwachung), siehe docs/dsfa/PROJ-1448-ssh-session-recording.md (Erweiterung um die erhöhte Root-Risikostufe durch /dsgvo zu bewerten). RLS: SELECT nur admin/manager, KEIN Member-Read (auch nicht der eigene Mitarbeiter). INSERT/UPDATE ausschließlich Service-Role via Sync-Cron server-admin-session-sync (alle 15 Min). Server-advisor_findings-Erweiterung: neuer Status completed + completed_by/completed_at (Audit, automatisch durch den Sync-Cron oder manuell durch admin/manager). Notifications (2 neue Typen): server_admin_access_granted (Empfänger: der Mitarbeiter, dem Zugriff gewährt wird) und server_admin_access_revoked (Empfänger: der betroffene Mitarbeiter) — Inhalt: Server-Alias, kein weiteres PII. Provisionierung: identischer Mechanismus wie PROJ-1448 (appendAuthorizedKey/removeAuthorizedKey, Marker-basiert), aber Ziel-User ist server.ssh_user (in Produktion root, PROJ-1522 F-1) statt eines Site-Subusers — kein neuer Secret-Speicherweg. Offboarding: Verliert ein Mitarbeiter Admin-Rolle UND Entwickler-Flag, werden automatisch alle seine server_admin_grants entzogen (analog PROJ-1448-Offboarding). Retention: 90 Tage Hard-Delete für server_admin_sessions via Cron server-admin-session-cleanup (täglich 03:45 UTC) — server_admin_grants bleiben als Vergabe-Historie bestehen (analog contao_ssh_grants), CASCADE bei Server-/Workspace-Löschung.
PROJ-652 KI-CD-Generator (Corporate Design)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: Marken-Konzeptentwicklung im Agentur-Kunden-Kontext). Die Verarbeitung dient ausschließlich der internen Agentur-Workflow-Beschleunigung bei CD-Relaunches und Neuentwicklungen für Bestandskunden. Externe Auftragsverarbeiter (Anthropic, Higgsfield AI, Google Cloud Vision) sind in der PROCESSORS-Liste dokumentiert und unter Standardvertragsklauseln/DPA gebunden.
- cd_generator_briefings (PROJ-652 Phase A, erweitert PROJ-715): Briefing-Stammdaten — id, workspace_id (CASCADE), contact_id (FK SET NULL → contacts, eingeführt 2026-05-19 als Datenleck-Fix: SSOT-Snapshot wird ausschließlich für diesen Kunden eingefroren; Art. 5 Abs. 1 lit. c DSGVO Datenminimierung), title (max 200), mode ('relaunch' | 'new_development'), status-Pipeline (draft→generating→ready→applied/archived/failed), pre_archive_status (PROJ-715: TEXT NULLABLE — persistiert den Status vor Archivierung, damit Reaktivierung sauber zurueck wechseln kann; NULL wenn nicht archiviert), ssot_snapshot (JSONB — Personas/Markenwerte/Zielgruppen/Marketingziele/USPs zum Erstellzeitpunkt eingefroren, R-Snapshot), current_ci_snapshot (JSONB, nur bei mode='relaunch' — aktueller CI-Stand: ci_color/ci_font/ci_logo/ci_image/ci_favicon/ci_moodboard/ci_guideline/ci_typography_responsive), briefing_answers (JSONB Lückenfragen-Antworten), transcript_text (max 100k Zeichen, optional — Klartext aus Workshop-Transkript), transcript_extracted_answers (JSONB von Claude extrahiert), prompt_feedback_history (JSONB Array — pro Iteration ein Eintrag), applied_route_id (FK SET NULL → cd_generator_routes), applied_at, created_by (FK auth.users CASCADE), Zeitstempel. **Potenzielle PII** durch Workshop-Transkripte (Klartext-Namen, Originalformulierungen) — Upload-Banner weist Reporter explizit auf DSGVO-Implikationen hin. RLS: SELECT alle aktiven Workspace-Member; INSERT/UPDATE Admin+Manager (nur in status='draft' änderbar — Ausnahmen seit PROJ-715: title-Umbenennen in allen Status, Archive/Unarchive in allen Status); **DELETE Admin+Manager (PROJ-715-Eskalation für Konsistenz mit PATCH/Archive/Duplicate; vorher Admin-only)**. Discard von Job-Phasen (PROJ-709) bleibt Admin-only. (SELECT auth.uid())-Pattern (R-50).
- cd_generator_uploads (PROJ-652 Phase A): Hochgeladene Referenzbilder (max 10 pro Briefing, ≤8MB JPEG/PNG/WebP/HEIC) + Transkripte (max 1 pro Briefing, ≤5MB TXT/MD/PDF/DOCX). Spalten: id, briefing_id (CASCADE), workspace_id (CASCADE), file_type ('reference_image' | 'transcript'), category ('color_inspiration'|'logo_reference'|'mockup_inspiration'|'mood_style'|'reference_logo' — nur für Bilder; 'reference_logo' markiert das Gateway-0-Pflichtbild aus PROJ-738), storage_path (workspaces/<wid>/cd-generator/<bid>/<fid>.<ext>), mime_type, file_size_bytes, original_filename, created_by, created_at. Magic-Byte-Check (R-228) verhindert MIME-Spoofing. Storage-RLS via Pfad-Prefix (R-413) — nur Admin/Manager schreibt, alle aktiven Member lesen. Retention: 90 Tage nach Briefing-Abschluss (Cleanup-Cron in Phase D).
- cd_generator_routes (PROJ-652 Phase A): Pro Briefing genau 3 Routen (route_index 1-3, UNIQUE). Spalten: id, briefing_id (CASCADE), workspace_id (CASCADE), route_index, active_version_id (FK SET NULL → cd_generator_route_versions), created_at. Keine PII. RLS analog briefings.
- cd_generator_route_versions (PROJ-652 Phase A+B): Versionierte Iterationen pro Route. Spalten: id, route_id (CASCADE), briefing_id (CASCADE), workspace_id (CASCADE), version_number (UNIQUE pro route), moodboard_image_urls (JSONB Array Storage-URLs aus Higgsfield Phase C — Auto-Gen liefert 1 Composite-Bild pro Route mit 2×3-Grid-Layout; weitere Einträge nur durch manuelle Iteration möglich), moodboard_concept_text (max 5000, Claude-Output), color_palette (JSONB — 10 Pflicht-Variablen Primary/Secondary/Third/Fourth/Fifth/Sixth/Light/Dark/Background/CTA mit hex/rgb/hsl/reasoning), typography (JSONB — Google-Fonts-Paar + 7 Textfarben p/H1-H6), logos (JSONB Array — Auto-Gen liefert nur 1 Eintrag pro Version (`wordmark_monochrome`, schwarz auf weiß); historische Kinds (color/negative/signet) bleiben für Manual-Upload und Legacy-Daten gültig, mit storage_path/plagiarism_check_id/is_user_uploaded), mockups (JSONB Array, Phase D), change_origin ('initial_generation'|'manual_edit'|'prompt_regeneration'), prompt_used (max 5000, User-Prompt bei prompt_regeneration), created_by, created_at. RLS analog routes.
- cd_generator_logo_plagiarism_checks (PROJ-652 Phase C): Audit pro generiertem Auto-Gen-Logo (`wordmark_monochrome`) und optional pro Manual-Upload-Logo (User-Verantwortung — keine automatische Plagiats-Pflicht). Spalten: id, logo_storage_path, workspace_id (CASCADE), briefing_id (CASCADE), route_version_id (CASCADE), logo_kind ('wordmark_monochrome'|historische Kinds für Legacy-Daten), provider ('google_vision_web_detection'), similarity_score (0-100%), status ('pending'|'clean'|'review'|'blocked'|'failed'), web_matches (JSONB Array — URL/similarity/source), manual_override_user_id (FK SET NULL → auth.users), manual_override_reason (max 2000, Pflicht bei Override), manual_override_at, retry_count (max 10), Zeitstempel. Override-Konsistenz via CHECK-Constraint. Pflicht-Audit-Trail für Designer-Entscheidungen (R-558).
- cd_generator_jobs (PROJ-652 Phase B, erweitert PROJ-709): Background-Job-Lifecycle (analog cms_higgsfield_jobs). Spalten: id, briefing_id (CASCADE), workspace_id (CASCADE), phase ('moodboard_synthesis'|'color_palette'|'typography'|'logo_generation'|'plagiarism_check'|'mockup_generation'|'route_iteration'|'completed'), status ('pending'|'running'|'completed'|'failed'|'discarded' — letzteres PROJ-709 für User-getriggertes Verwerfen einzelner Phasen), provider ('anthropic_claude'|'higgsfield_ai'|'google_vision'), external_job_id, progress_percent, error_message, error_provider (R-662 Granularität), retry_count (max 5), started_at, completed_at, created_at, claim_locked_until (R-460/R-586 Worker-Claim + Stale-Recovery). **PROJ-709 Verbrauchs-Spalten:** tokens_input (INT NULLABLE — Anthropic-Input-Tokens dieser Phase), tokens_output (INT NULLABLE — Anthropic-Output-Tokens), higgsfield_generations_count (INT NULLABLE — Snapshot der Anzahl Higgsfield-Generations beim Phase-Completion). Diese Werte werden via Status-Endpoint (/briefings/:id/status?include=consumption) als Verbrauchs-Block (Admin+Manager) aggregiert dargestellt — Kostentransparenz vor Resume-Trigger. **PROJ-709 cd_generator_briefings.last_resume_at (TIMESTAMPTZ NULLABLE):** Zeitstempel des letzten User-getriggerten Resume; dient als 30s-Server-side-Debounce gegen versehentliche Doppel-Klicks und als Audit-Trail wann ein fehlgeschlagener Lauf wieder aufgenommen wurde. RLS: SELECT Workspace-Member, UPDATE Admin+Manager (Cancel/Resume) und Admin-only (Discard), DELETE Admin, INSERT ausschließlich via Service-Role (Worker) und via /resume/discard-Routen.
- cms_higgsfield_jobs.linked_cd_briefing_id + cd_logo_kind (PROJ-652 Phase C-Erweiterung): Bestehende Higgsfield-Job-Tabelle erhält zwei optionale Spalten — linked_cd_briefing_id (FK → cd_generator_briefings, CASCADE) zur Briefing-Zuordnung; cd_logo_kind (TEXT mit CHECK-Constraint: wordmark/signet je color/negative/monochrome, moodboard, mockup_mug/polo/flag/business_card/phone) zur Kategorisierung. Bestehende Higgsfield-Jobs ohne diese Felder sind aus PROJ-596/607-Kontext. Keine zusätzliche PII.
- Externe Auftragsverarbeiter: (1) Anthropic Claude Sonnet 4.6 — Briefing-Texte + SSOT-Snapshot + Transkripte + Signed-URLs zu Referenzbildern (15min TTL) werden transient zur Synthese gesendet. Prompt-Caching auf System-Prompts (cache_control: ephemeral). Keine Persistenz bei Anthropic. PROJ-738: zusätzliche Phase-1-Konzept-Synthese (text-only, ohne Bildausgabe) — Firmenname + Tagline + Briefing werden für die Generierung von 3 strategischen Konzept-Routen übermittelt; Single-Route-Phase-2 (Farben + Schriften) nutzt zusätzlich das gesperrte Konzept als Input. (2) Higgsfield AI — Prompt + CI-Hex-Farben pro Logo-/Moodboard-/Mockup-Generation; Quota gemeinsam mit PROJ-596/607. PROJ-738 erweitert um Image-to-Image-Mockup-Generation: das in Gateway 3 gesperrte Primär-Logo wird als physisches Input-Image (reference_image_url, signed URL 15min TTL) an Higgsfield übergeben — kein Text-Prompt-Neu-Render des Logos. (3) Google Cloud Vision API — Signed-URL einer generierten Logo-Bilddatei zur Web-Detection (Plagiat) UND PROJ-738: TEXT_DETECTION zur Drift-Erkennung am Mockup (byte-exakter Firmennamen-Abgleich mit dem gesperrten firma_name aus Gateway 0). Kein persistentes Speichern bei Google. PROJ-738-Update bestehender Google-Vision-PROCESSOR-Eintrag: purpose umfasst jetzt zusätzlich Text-Erkennung.
- cd_generator_briefings (PROJ-738 Erweiterung): firma_name (Pflicht nach Gateway 0, 1-100 Zeichen — wird byte-identisch in allen Phasen 1-4 verwendet, Anti-Drift-Garantie), tagline (optional, 0-120 Zeichen), reference_image_upload_id (FK SET NULL → cd_generator_uploads; Pflicht-Upload genau 1 Bild aus Gateway 0), reference_image_classification ('style_reference' = nur Stil-Inspiration | 'adaptation_template' = strukturelle Adaption), selected_mockup_carriers (TEXT-Array, 1-8 Träger aus zentraler Bibliothek; Beachflag bewusst NICHT enthalten — Cap durch CHECK-Constraint nach Gateway-0-Lock), selected_route_id (FK SET NULL → cd_generator_routes; gesperrte Konzept-Route aus Gateway 1), primary_locked_logo_asset_id (FK SET NULL → cd_generator_locked_assets; gesperrtes Primär-Logo aus Gateway 3). 10 Lock-Spalten (5×_locked_at + 5×_locked_by) als FK SET NULL → auth.users dokumentieren wer wann welches Gateway gesperrt hat. Status-Pipeline auf 17 Werte erweitert (briefing_locked → concept_generating → concept_ready → … → mockups_locked → applied). Diese Felder sind keine PII — sie speichern Marken-Konfiguration. Lock-Spalten enthalten User-IDs, die bei Workspace-Löschung via FK CASCADE bzw. SET NULL behandelt werden. Audit-Trail-Sichtbarkeit: Admin sieht alle Lock-Aktionen; Manager nur eigene + Phase-Wechsel-Zeitpunkte.
- cd_generator_route_versions (PROJ-738 Erweiterung): concept_payload (JSONB, Phase-1-Text-Output mit name_lock_confirmation + key_message + style_direction + visual_keys[] — kein PII, Marken-Konzept-Text), font_fidelity_note (TEXT NULLABLE — dokumentiert wenn Higgsfield den Originalfont nicht rendern konnte und visuell kompatible Alternative gewählt hat, AC-3.2), is_discarded (BOOLEAN, markiert verworfene Konzept-/Logo-Varianten ohne Löschung — bleibt im Audit-Trail sichtbar, R-558 Lifecycle-Status-Transition). change_origin erweitert um 4 neue Werte (concept_synthesis | colors_typo_synthesis | logo_synthesis | mockup_synthesis), damit pro Phase nachvollziehbar ist welche Synthese die Version erzeugt hat.
- cd_generator_jobs (PROJ-738 Erweiterung): gateway_pause_at (TIMESTAMPTZ NULLABLE — Zeitpunkt an dem der Worker an einem Gateway pausiert hat; kein Auto-Advance zur nächsten Phase ohne User-Lock-Aktion). phase erweitert um 3 neue Werte (concept_synthesis = text-only Phase 1, colors_typo_synthesis = Single-Route-Phase 2, drift_detection = Post-Mockup-Google-Vision-Text-Check). Worker pausiert nach jeder Phase und überlässt die Freigabe explizit dem User (Phase-Gate-Enforcement).
- cd_generator_locked_assets (PROJ-738, NEUE Tabelle): In Gateway 3 gesperrte Logo-Assets mit unveränderlichen Snapshots aus Phase 0+2. Spalten: id, briefing_id (CASCADE), route_version_id (FK SET NULL → cd_generator_route_versions), workspace_id (CASCADE), storage_path (Pfad im cd-generator-Bucket, workspaces/<wid>/cd-generator/<bid>/locked-logos/), firma_name_snapshot (Pflicht 1-100, eingefrorener Firmenname aus Gateway 0), tagline_snapshot (NULLABLE), hex_palette_snapshot (JSONB — 6 HEX-Werte aus Phase 2), typography_snapshot (JSONB — Schrift-Paar), font_fidelity_note, is_primary (BOOLEAN, Partial-Unique-Index erzwingt genau 1 Primär-Asset pro Briefing — wird für Phase 4 als Image-Input genutzt), is_user_uploaded (BOOLEAN — manueller Upload überspringt Plagiats-Prüfung), plagiarism_check_id (FK SET NULL → cd_generator_logo_plagiarism_checks; NULL bei User-Upload), created_by (FK CASCADE → auth.users), created_at. Keine PII — Marken-Asset-Snapshots. RLS: SELECT Workspace-Member, INSERT/UPDATE/DELETE Admin+Manager. Workspace-scoped CASCADE-DELETE.
- cd_generator_audit_log (PROJ-738, NEUE Tabelle, IMMUTABLE): Gateway-Audit-Tagebuch pro Briefing — jeder Lock/Reset/Regenerate/Cancel/Auto-Advance erzeugt einen Eintrag. Spalten: id, briefing_id (CASCADE), workspace_id (CASCADE), gateway_phase (briefing | concept | colors_typo | logo | mockups), action_type (lock | reset | regenerate | cancel | auto_advance), user_id (FK SET NULL → auth.users — NULL bei System-Aktionen), comment (Pflicht-Begründung bei reset/regenerate, max 2000 Zeichen, sonst NULL), payload_snapshot (JSONB — Werte zum Zeitpunkt der Aktion: gewählte Routen-ID, gewählte Farben, Logo-Asset-IDs, Carrier-Auswahl etc.), affected_entity_ids (JSONB-Array — z.B. gelöschte Route-Versions bei Reset), created_at. RLS: SELECT für Workspace-Member; INSERT für Admin/Manager; **KEIN UPDATE/DELETE-Recht per Design** (immutable). Comment kann personenbezogene Begründungen enthalten (z.B. „Reset durch Geschäftsführer Müller wegen Markenkonflikt“) — bei berechtigter Lösch-Anfrage gem. Art. 17 DSGVO erfolgt manuelle Anonymisierung durch Workspace-Admin (Service-Role-Update auf comment=[redacted]). Workspace-scoped CASCADE-DELETE.
Virtual Text Generator (PROJ-655, PROJ-682 Move zu Agency-Workspace, PROJ-837 Texteditor-Phase-1, PROJ-838 Texteditor-Phase-2 CI-Briefing, PROJ-839 Texteditor-Phase-3 Social Media + SEA Copy, PROJ-841 Texteditor-Phase-5 Polish + KI-Fragen-Engine)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: Effiziente Marketing-Text-Erstellung für Kunden-Workspaces mit SSOT-Kontext). Seit PROJ-682 (Move) wird der Bereich ausschließlich von Agency-Membern bedient (Workspace-Typ-Guard: workspaces.type='agency'); die generierten Daten verbleiben jedoch datenrechtlich am Kunden-Workspace (virtual_text_chats.workspace_id zeigt auf den Client-Workspace). Die Verarbeitung erfolgt über die bestehende Auftragsverarbeitung (AVV gemäß Art. 28 DSGVO zwischen Agentur und Kunde). Der externe Auftragsverarbeiter Anthropic ist in der PROCESSORS-Liste dokumentiert (DPA + SCCs). Keine automatisierten Entscheidungen im Sinne von Art. 22 DSGVO — alle generierten Texte sind Vorschläge zur manuellen Prüfung und Freigabe.
- virtual_text_chats (PROJ-655, PROJ-682 Move): Themen-Chat-Metadaten — id, workspace_id (FK CASCADE → workspaces, zeigt weiterhin auf den Kunden-Workspace), created_by (FK CASCADE → auth.users, Agency-Member der verbundenen Agentur), name (max. 200 Zeichen), last_used_at (Sortier-Kriterium), soft_deleted_at (30-Tage-Wiederherstellungsfenster, NULL = aktiv), created_at, updated_at. RLS: SELECT/UPDATE/DELETE ausschließlich für den Eigentümer (created_by = auth.uid()). INSERT seit PROJ-682 mit workspace_id aus Server-Context und Workspace-Typ-Guard agency + workspace_connections-EXISTS-Subquery: der INSERT ist nur erlaubt, wenn der ausgewählte Kunden-Workspace eine aktive workspace_connection zur Agency des eingeloggten Users hat. Per-User-Sichtbarkeit (created_by = auth.uid()) — keine Cross-User-Sichtbarkeit im MVP.
- virtual_text_messages (PROJ-655): Einzelne Anfragen und KI-Antworten pro Chat — id, chat_id (FK CASCADE → virtual_text_chats), role ('user' | 'assistant'), content (Klartext: User-Prompt bzw. LLM-Antwort, max. 8.000 Zeichen User-Prompt), ai_role (Whitelist: seo_optimiert | conversion_optimiert | storyboard | storytelling | social_media_post), ssot_snapshot_jsonb (Snapshot des SSOT-Kontexts zum Generierungs-Zeitpunkt für Reproduzierbarkeit: Marketingziel, Bedarfsgruppen, Tonalität, Zielregion, Markenfarben), llm_provider ('anthropic'), llm_model ('claude-sonnet-4-6'), input_tokens, output_tokens, created_at. **Potenzielle PII** durch frei formulierte User-Prompts (Klarnamen, E-Mails Dritter, Kontaktdaten) — PII-Hinweis-Banner im UI bei Bereich-Öffnung (PROJ-655 AC-DSGVO: 'Prompts werden zur Generierung an Anthropic übermittelt. Bitte keine personenbezogenen Daten Dritter eingeben.'). RLS: SELECT/INSERT/DELETE indirekt über chat_id → virtual_text_chats.created_by = auth.uid(). Token-Verbrauch zusätzlich in api_cost_entries (PROJ-30) mit Feature-Tag virtual_text_generator.
- SSOT-Snapshot pro Generierung (Reproduzierbarkeit): Aktuelles Marketingziel, Top-Bedarfsgruppen, Tonalität (sofern in SSOT gepflegt), Zielregion, Markenfarben werden zum Generierungs-Zeitpunkt eingefroren und in virtual_text_messages.ssot_snapshot_jsonb gespeichert. Zweck: Nachvollziehbarkeit auch wenn die SSOT später geändert wird. SSOT-Originaldaten bleiben in den jeweiligen SSOT-Tabellen (ssot_items, workspaces) — werden hier nur als Snapshot referenziert.
- virtual_text_quality_scores (PROJ-656): Qualitäts-Score-Cache pro Assistant-Message — id, message_id (FK CASCADE → virtual_text_messages), text_hash (SHA-256 hex 64 Zeichen des content, KEIN Klartext), ssot_version (SHA-256 hex 64 Zeichen des SSOT-Snapshots), total_score (INTEGER 0–100), score_breakdown_jsonb (4 Komponenten: SEO 30% / Textlängen 20% / SSOT-Abgleich 40% / Lesbarkeit 10% inkl. Haiku-Tooltip-Beispiele zur Verbesserung), computed_at. Pro Message exakt 1 Score (UNIQUE message_id) — bei manueller Text-Bearbeitung wird der Score per UPSERT überschrieben. RLS: SELECT über message_id → virtual_text_messages → virtual_text_chats.created_by-Kette. INSERT/UPDATE/DELETE: Service-Role-only (Backend-Berechnung, R-356: keine Client-Manipulation). KEIN Klartext der bewerteten Texte — nur Hash + strukturierter Score-Breakdown. Bei SSOT-Änderung invalidiert sich der Cache automatisch über den ssot_version-Hash (R-647).
- Externer Auftragsverarbeiter Anthropic (Claude Sonnet 4.6): Pro Generierungs-Anfrage werden User-Prompt + SSOT-Kontext-Snapshot + KI-Rolle als strukturierter System-Prompt-Block übermittelt. Anthropic-Prompt-Caching auf System-Prompts (cache_control: ephemeral, R-658). Übermittlung transient — keine Datenpersistenz bei Anthropic. AVV/SCCs sind im PROCESSORS-Eintrag dokumentiert. EU AI Act Art. 50: KI-generierte Texte werden im UI mit ✦ KI-generiert-Kennzeichnung versehen.
- virtual_text_batch_jobs (PROJ-657, PROJ-682 Move): Batch-Job-Metadaten pro Bereichs-Generierungs-Auftrag — id, workspace_id (CASCADE, zeigt auf Kunden-Workspace), created_by (CASCADE, Agency-Member), ai_role (Whitelist), page_ids (JSONB), total_pages/completed_pages/failed_pages (Counter), status (pending/running/done/partial_failed/failed), Timestamps. RLS: SELECT/UPDATE/DELETE nur created_by; INSERT seit PROJ-682 nur durch Agency-Member mit aktiver workspace_connection zum Ziel-Kunden-Workspace. Service-Role fuer Worker-UPDATEs.
- virtual_text_batch_results (PROJ-657): Generierungs-Ergebnis pro CMS-Seite — id, batch_job_id (CASCADE), workspace_id (CASCADE), page_id (Soft-FK), status, generated_content_jsonb (LLM-Output), ssot_snapshot_jsonb (SSOT-Snapshot), retry_count. Service-Role-only-Write. Kein PII in generated_content_jsonb (Marketing-Texte).
- virtual_text_cms_writes (PROJ-657): Audit-Trail jeder Direkt-CMS-Uebernahme — id, workspace_id (CASCADE), batch_result_id (CASCADE), page_id (Soft-FK), written_blocks_jsonb (block_id -> version_id), written_by (CASCADE), written_at. Immutable (kein UPDATE/DELETE fuer authenticated). RLS: SELECT nur written_by.
- virtual_text_review_refinements (PROJ-658): Audit-Trail jeder LLM-Block-Verfeinerung im Review-Workflow (Modus A) — id, batch_result_id (CASCADE), workspace_id (CASCADE), created_by (CASCADE), block_id (Soft-FK auf cms_blocks.id), refinement_hint (User-Prompt 'Diesen Block umschreiben mit Hinweis: ...'), previous_content_jsonb (Block-Inhalt vor Verfeinerung), new_content_jsonb (LLM-Vorschlag), accepted (Boolean ob User uebernommen hat), input_tokens, output_tokens, created_at. RLS: SELECT/UPDATE nur created_by, INSERT nur eigene Review-Items (Ownership ueber batch_result_id), DELETE nur Service-Role. CASCADE-DELETE bei Workspace-/User-Loeschung. Cleanup ueber virtual-text-cleanup-Cron bei rejected Reviews >90 Tage.
- virtual_text_impact_findings (PROJ-660): Audit-Trail der KI-Impact-Analyse bei gravierenden SSOT-Aenderungen — id, ssot_history_id (FK CASCADE → ssot_history), workspace_id (FK CASCADE → workspaces), page_id (Soft-FK auf cms_pages.id), block_id (Soft-FK auf cms_blocks.id), current_text_excerpt (Snapshot des veralteten Block-Texts max. 500 Zeichen — Marketing-Text, kein PII), suggested_new_text (LLM-Vorschlag max. 2000 Zeichen — Marketing-Text, kein PII), confidence (NUMERIC 0.0-1.0), status-Enum (pending/applied/rejected/obsolete), applied_at + applied_by (FK auth.users SET NULL — Audit Uebernahme), rejected_at + rejected_by (FK auth.users SET NULL) + rejection_reason (max. 1000 Zeichen), cms_write_id (FK virtual_text_cms_writes SET NULL — bei applied), created_at + updated_at. Findings werden vom pg_cron 'virtual-text-impact-worker' (15-Min-Intervall) erzeugt sobald ssot_history neue Eintraege in den relevanten Sections (marketing_goal/target_group/persona/usp) erhaelt. Pro Event max. 20 CMS-Seiten analysiert (Cost-Control). RLS: SELECT alle aktiven Workspace-Member; INSERT/UPDATE/DELETE Service-Role-only (Worker + apply/reject-API mit Admin/Manager-Role-Check). Workspace-scoped, CASCADE-DELETE bei Workspace-/SSOT-History-Loeschung. Cleanup ueber virtual-text-cleanup-Cron bei status='rejected'/'obsolete' >90 Tage. ssot_history wird in derselben Phase erweitert um severity (low/medium/high) + severity_classified_at + impact_analysis_completed_at — diese Lifecycle-Spalten sind ausschliesslich Metadata-Marker, sie aendern nichts am bestehenden ssot_history-Datenschutzkonzept (Klartext-Marketing-Daten bleiben in previous_data/new_data wie zuvor).
- text_editor_sessions (PROJ-837 Texteditor-Phase-1): Editor-Sessions im neuen Kategorie-basierten Texteditor unter /kunden-workspaces/texte (Agency-only). Spalten: id, workspace_id (FK CASCADE → workspaces — zeigt auf den Kunden-Workspace), crm_contact_id (FK CASCADE → contacts — Kundenscope), category (CHECK content_optimization|social_media|sea_copy|storytelling|storyboard), agent_persona_key, platform, format, wireframe_id (Soft-FK), briefing_json (JSONB — Editor-Briefing-Daten, redaktioneller Kontext), ssot_snapshot (JSONB — eingefrorener SSOT-Kontext aus loadVirtualTextSsotContext zum Session-Start: Marketingziel, Bedarfsgruppen, Tonalität, Zielregion, Markenfarben — Reproduzierbarkeit auch bei späteren SSOT-Änderungen), chat_history (JSONB-Array, max 500 Einträge — Steuerungs-Chat des Editors mit User-Prompts und KI-Antworten; bewusst denormalisiert für Auto-Save ohne N+1), editor_state (JSONB — kategoriespezifische Mitte-Komponente, Phase 1 leer, ab PROJ-838 mit Inhalt), change_mode (CHECK targeted|suggest DEFAULT 'targeted'), quality_score (NUMERIC 0-100 — siehe POST /quality-score), ssot_check_result (JSONB — letztes Ergebnis von POST /ssot-check mit 6 Dimensionen status+hint), created_by (FK CASCADE → auth.users), created_at, updated_at. **Potenzielle PII** durch frei formulierte User-Prompts in chat_history (Klarnamen, E-Mails Dritter, Kontaktdaten) — analog virtual_text_messages. Auto-Save alle 30s schreibt PATCH-Updates auf editor_state + chat_history + quality_score + ssot_check_result. RLS: workspace_members (alle Rollen) lesen/schreiben eigene Sessions ihres Workspaces; INSERT mit Agency-Workspace-Type-Guard + Contact-Ownership-Check (R-346, R-456). Workspace-scoped, CASCADE-DELETE bei Workspace-/Contact-/User-Löschung.
- text_editor_categories + text_editor_agent_personas (PROJ-837 Konfigurations-Tabellen, workspace-spezifisch): Pro Workspace 5 Standard-Kategorien (content_optimization/social_media/sea_copy/storytelling/storyboard) mit display_name, icon, is_active, sort_order, has_wireframe/has_mockup/has_variants. Pro Kategorie eine konfigurierbare KI-Persona (display_name, system_prompt, model_identifier — Phase 1: Default-Gemini-Modelle, Phase 2 wechselbar — temperature, version, is_active). Auto-Seed via Backend-Helper ensureWorkspaceSeeds() beim ersten /sessions oder /categories Aufruf. PROJ-837 Phase 1: Personas-Daten werden gespeichert, aber noch nicht für Gemini-Calls genutzt (Persona-getriebene Generierung folgt ab PROJ-838). Kein PII in Konfigurations-Daten (display_names sind redaktionelle Bezeichnungen, system_prompts sind System-Prompt-Templates). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (Konfiguration der Agentur-Workflows). RLS: SELECT alle aktiven Workspace-Member, INSERT/UPDATE/DELETE Admin+Manager. Workspace-scoped, CASCADE-DELETE bei Workspace-Löschung.
- text_editor_platforms + text_editor_formats + text_editor_sea_templates (PROJ-837 Globale Stammdaten, nicht workspace-spezifisch): Statische Plattform-Constraints (linkedin/instagram/facebook/tiktok/x mit max_characters, max_hashtags, truncation_line, image_ratio, best_practices_json), Format-Definitionen (feed_post/story/reel/carousel pro Plattform mit constraints_json) und SEA-Template-Limits (bing_responsive_search_ad mit headline_count/headline_max_chars etc.). Read-only via API, gepflegt per Migration. Kein Bezug zu konkreten Workspaces oder Kontakten → kein PII. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (Stammdaten-Lookup). RLS: SELECT für alle authentifizierten Nutzer, INSERT/UPDATE/DELETE nur Service-Role (Plattform-Admin via Migration).
- PROJ-840 Storytelling, Storyboard & Export (Migration 20260528xxxxxx_proj840_storytelling_export_sync.sql): Pro Session speichert editor_state fuer Storytelling die Section-Struktur (Setup/Konflikt/Aufloesung mit nested Chapter-Cards: id/title/text), fuer Storyboard die Frame-Liste (id/description/dialog/camera/order) + view_mode (strip/slide_deck). Neue Spalten auf text_editor_sessions: last_exported_at (timestamptz, nullable) + last_export_format (text, nullable). Neue Spalten auf content_intelligence_jobs fuer CI-Editor-Status-Sync: text_editor_status (CHECK in_progress/done, nullable), text_editor_status_at (timestamptz, nullable), text_editor_session_id (uuid FK auf text_editor_sessions ON DELETE SET NULL). Inhalte sind Marketing-Werkstuecke der Agentur - kein PII von Endkunden. Workspace-scoped, CASCADE-DELETE bei Session/Workspace-Loeschung. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO. Datenexport Art. 15/20 DSGVO via /api/workspaces/data-export - editor_state + neue Spalten ueber erweiterten SELECT (R-241/R-707). Zwei neue Endpoints: GET /sessions/:id/export?format=... (5 Formate: cms_json, social_text, bing_csv, markdown, storyboard_json - Server-Side-Generierung, last_exported_at-Tracking), POST /sessions/:id/sync-ci-status (setzt text_editor_status auf bestehendem CI-Job - nur wenn ci_job_id verknuepft). Keine externen KI-Provider-Calls in PROJ-840.
- PROJ-839 Social Media + SEA Copy (kein neues DB-Schema — alle Daten in bestehender text_editor_sessions.editor_state JSONB-Spalte): Pro Social-Media-Session speichert editor_state den aktuellen Post-Text (`text`), bis zu 3 KI-generierte Varianten (`variants[].id/angle/text`) und ein view_mode (`mobile`/`desktop`). Pro SEA-Copy-Session speichert editor_state bis zu 15 Headlines (`headlines[].id/text`, je max. 30 Zeichen), bis zu 4 Descriptions (`descriptions[].id/text`, je max. 90 Zeichen), 2 Path-Felder (`paths[0..1]`, je max. 15 Zeichen) und die Final-URL (`final_url`). Inhalte sind Marketing-Texte der Agentur (Werkstücke) — keine PII von Endkunden. Workspace-scoped (geerbt von text_editor_sessions), CASCADE-DELETE bei Session-/Workspace-/Kontakt-Löschung. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung Agentur-Plattform-Nutzung). Datenexport Art. 15/20 DSGVO via /api/workspaces/data-export — `editor_state` ist im SELECT-Statement der text_editor_sessions-Export-Query bereits enthalten (R-241, R-707). Drei neue Endpoints: POST /generate-variants (3 Varianten in einem Call), POST /generate-rsa (15 Headlines ODER 4 Descriptions), POST /targeted-change-element (Single-Field-Regeneration). Alle Endpoints nutzen Claude Haiku 4.5 mit Anthropic-Prompt-Caching (cache_control: ephemeral, R-658). Rate-Limit: 12 Calls/Min (Variants+RSA) bzw. 20 Calls/Min (Targeted-Change-Element) pro (workspace, user). Token-Logging via ai_token_logs.feature='text_editor_generate_variants' | 'text_editor_generate_rsa_headlines' | 'text_editor_generate_rsa_descriptions' | 'text_editor_targeted_change_element'.
- PROJ-838 CI-Briefing-Integration (Erweiterung text_editor_sessions um 4 Spalten, Migration 20260528132753_proj838_text_editor_ci_briefing.sql): Pro Session speichert (a) ci_job_id (UUID FK auf content_intelligence_jobs ON DELETE SET NULL, nullable — NULL = manuelle Session ohne Briefing), (b) briefing_page_index (INTEGER 0..50, NOT NULL DEFAULT 0 — Index in pages_to_generate bei Multi-Page-Briefings), (c) briefing_snapshot_json (JSONB nullable — eingefrorener Snapshot des CI-Phase-04-Exports zum Lade-Zeitpunkt: target_keyword, target_url, pages_to_generate, scoring_summary, competitors, conversion_hints, must_cover_topics, paa_questions; schützt Session vor nachträglichen CI-Re-Runs), (d) targeted_change_history (JSONB NOT NULL DEFAULT '[]'::jsonb — Liste der letzten max. 50 KI-Targeted-Element-Änderungen mit Schema [{id, ts, element_id, before, after, reason, applied}], FIFO-Pruning, ermöglicht Rückgängig). Briefing-Snapshot ist Marketing-Content (kein PII von Endkunden — Keywords, Wettbewerber-URLs, Conversion-Hinweise). Targeted-Change-History enthält ggf. workspace-interne Marketingtexte aus dem Editor-Block (Vorher/Nachher) und KI-Begründung — analog chat_history potenzielle PII durch frei formulierte User-Instructions. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung Agentur-Plattform-Nutzung) i.V.m. Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: Effiziente Content-Optimierung mit CI-Kontext). RLS: workspace-scoped (geerbt von text_editor_sessions, R-707). Workspace-scoped, CASCADE-DELETE bei Session-Löschung; ci_job_id ON DELETE SET NULL erhält die Session wenn der CI-Job gelöscht wird (Snapshot bleibt erhalten). Datenexport Art. 15/20 DSGVO via /api/workspaces/data-export — alle 4 Felder sind im explizit aufgelisteten SELECT enthalten (R-241).
- PROJ-841 KI-Fragen-Engine + Persona/Platform-Konfigurierbarkeit (kein neues DB-Schema): Neuer Endpoint POST /text-editor/sessions/:id/proactive-hints liefert max. 3 proaktive Hinweise via Claude Haiku 4.5 (max_tokens 800, strukturierter Tool-Use-Output 'report_proactive_hints' mit hints[] {id, type, message, severity}, Rate-Limit 6 Calls/Min pro (workspace, user), 8s Timeout R-665). Input: editor_state-Slice (truncated auf 4000 Zeichen aus extractCurrentContent) + SSOT-Snapshot + briefing_snapshot_json (sofern vorhanden) + Plattform-Best-Practices aus text_editor_platforms. Output: hints[] mit type ∈ {competitor|engagement|keyword|tonality|structure} und severity ∈ {info|warning|opportunity}. Prompt-Caching auf System-Prompt + SSOT + Plattform + Briefing (cache_control: ephemeral, R-658). Token-Logging via ai_token_logs.feature='virtual_text_generator_qa' (bestehender Enum-Wert wiederverwendet, R-624). Neuer PATCH-Endpoint PATCH /text-editor/platforms/:platform_key (Admin-only — Plattformen sind globale Stammdaten ohne workspace_id) erlaubt das Updaten der Plattform-Constraints (display_name, max_characters, max_hashtags, truncation_line, image_ratio, best_practices_json). Keine neuen DB-Schema-Änderungen — die KI-Fragen sind transient (kein Persist im DB). Keine PII-Persistenz; transient an Anthropic übermittelter Editor-Inhalt kann theoretisch frei formulierte User-Eingaben enthalten (analog SSOT-Check und Targeted-Change). Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung Agentur-Plattform-Nutzung) i.V.m. Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: effiziente Marketing-Text-Erstellung mit KI-Begleitung). RLS unverändert. Externer Verarbeiter Anthropic im bestehenden PROCESSORS-Eintrag dokumentiert (purpose um PROJ-841 KI-Fragen-Engine erweitert, R-624), PROJ-860 Conversational Briefing Assistant — Claude mit Vision + 7 Tool-Use-Function-Calls (get_component_by_screenshot, get_field_by_context, get_api_endpoint, get_current_navigation, get_existing_briefings, query_db — read-only; PROJ-1408: + read_repo_file — liest einzelne Quellcode-Dateien read-only aus festgelegten Repository-Bereichen via GitHub Contents-API mit separatem Nur-Lese-Token und übergibt den Datei-Inhalt transient als Tool-Result an Anthropic; reiner Programmcode ohne personenbezogene Daten. PROJ-1408 ersetzt zudem die statische DB-Schema-Momentaufnahme des Chat-Kontexts durch eine Live-Abfrage der Tabellen-STRUKTUR aus information_schema — weiterhin keine Kundendaten-Inhalte); transient, kein Training, Prompt-Caching via cache_control:ephemeral).
- PROJ-1388 Texteditor — Mehrfach-Vorschläge, Score-Delta, Header-Konsolidierung, Chat-Gruppierung (kein neues DB-Schema, keine Migration): editor_state.suggest_diff (Einzel-Objekt, PROJ-838) wird durch editor_state.suggestions[] ersetzt — ein Array, das mehrere gleichzeitig offene Vorschläge trägt: id, element_id (referenzierter Block), before/after (bisheriger/vorgeschlagener Text — redaktionelles Marketing-Werkstück, kein PII von Endkunden), reason (KI-Begründung), confidence ('high'|'low' — reine KI-Zuversicht-Einstufung, konsistent mit dem bestehenden CONFIDENCE_LEVELS-Pattern, kein Personenbezug), status ('open'|'applied'|'rejected'), score_delta (geschätzte Punktzahl-Differenz aus zwei Aufrufen der bestehenden reinen Funktion computeKpiGroupScores, reine Qualitäts-Metadaten ohne Personenbezug), created_at. Datencharakter identisch zum bereits dokumentierten targeted_change_history (PROJ-838): 'workspace-interne Marketingtexte aus dem Editor-Block (Vorher/Nachher) und KI-Begründung — analog chat_history potenzielle PII durch frei formulierte User-Instructions' — suggestions[] führt keine neue Kategorie personenbezogener Daten ein. Kein neuer externer Auftragsverarbeiter: score_delta wird ausschließlich lokal/serverseitig über die bestehende reine Funktion computeKpiGroupScores berechnet (kein zusätzlicher LLM-Call für die Delta-Berechnung); die KI-Generierung des Vorschlagsinhalts (before/after/reason/confidence) läuft weiterhin über den bestehenden PROJ-838 targeted-change-Endpunkt (Anthropic, s.u., bereits dokumentiert und AVV-gedeckt). Header-Konsolidierung (Kunden-/Sitzungs-Auswahl im Header zusammengeführt) und Chat-Gruppierung nach Block (nutzt das bereits bestehende ChatMessageOption.block_id aus PROJ-1383) sind reine UI-Änderungen ohne neues Datenmodell und ohne neue Sichtbarkeits-/Consent-Implikation. Workspace-scoped (geerbt von text_editor_sessions.editor_state), CASCADE-DELETE folgt demselben Pfad wie der Rest von editor_state (workspace_id-/crm_contact_id-/created_by-CASCADE, s.u. deletionConcept) — es gibt keinen separaten DELETE-Endpunkt für einzelne Vorschläge, das Array wird ausschließlich als Teil der gesamten Session mitgelöscht. Datenexport Art. 15/20 DSGVO: suggestions[] ist Teil der bereits im SELECT enthaltenen editor_state-Spalte (/api/workspaces/data-export, Zeile mit 'editor_state' im SELECT-Statement) — kein Code-Änderungsbedarf, da der gesamte JSONB-Wert exportiert wird, nicht einzelne Unterfelder (R-241/R-707 bereits erfüllt). Keine neue Consent-Anforderung (kein neues Tracking, keine neue Datenquelle, kein externer Empfänger, kein neuer Cookie).
- Externer Auftragsverarbeiter Anthropic (Claude Haiku 4.5) für PROJ-837 SSOT-Check und PROJ-838 KI-Targeted-Element-Change: Pro POST /text-editor/sessions/:id/ssot-check werden der aktuelle Editor-Inhalt (extrahiert aus editor_state oder letzter chat_history-Assistant-Message, max. 6000 Zeichen) + SSOT-Kontext-Snapshot (Marketingziel, Bedarfsgruppen, Tonalität, Zielregion, Markenfarben, USPs) als strukturierter System-Prompt-Block übermittelt. Pro POST /text-editor/sessions/:id/targeted-change (PROJ-838) werden zusätzlich der aktuelle editor_state.blocks (alle Block-IDs, Tags und Inhalte des Editors), die natürlichsprachige User-Anweisung (max. 2000 Zeichen — potenzielle PII durch frei formulierte Prompts) und der briefing_snapshot_json-Kontext (target_keyword, target_url, must_cover_topics, conversion_hints) übermittelt. Strukturierter Output via Tool-Use 'targeted_change' (kind: 'change' mit element_id+new_content+reason ODER kind: 'clarification' mit question). Anthropic Prompt-Caching auf System-Prompt + Briefing-Snapshot (cache_control: ephemeral, R-658). Übermittlung transient — keine Datenpersistenz bei Anthropic. AVV/SCCs sind im bestehenden PROCESSORS-Eintrag (Anthropic PBC) dokumentiert. Rate-Limit: 10 Calls/Min pro (workspace, user). Token-Logging via ai_token_logs.feature='virtual_text_generator_qa' (existierender Enum-Wert wiederverwendet, R-624). POST /text-editor/sessions/:id/quality-score ist rein rechnerisch und ruft KEINEN externen Auftragsverarbeiter auf. POST /text-editor/sessions/:id/undo-change ist eine reine DB-Operation (Block-Restore aus targeted_change_history) und ruft KEINEN externen Auftragsverarbeiter auf.
PROJ-654 Brand Vision Studio — Fotografisches Bildkonzept + KI-Bildgenerierung
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertrag — Erfüllung des Agentur-Auftrags zur Markenpflege und Bilderstellung für den Kunden) UND Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Effiziente Marken-Bildsprache-Konzeption im Agentur-Kunden-Kontext). Die Verarbeitung dient ausschließlich der internen Agentur-Workflow-Beschleunigung bei der fotografischen Bildkonzept-Definition und KI-gestützter Bildgenerierung pro Kundenbetreuung. Externe Auftragsverarbeiter (Anthropic Claude Vision, Higgsfield AI) sind in der PROCESSORS-Liste dokumentiert und unter Standardvertragsklauseln/DPA gebunden. Keine automatisierten Einzelentscheidungen im Sinne von Art. 22 DSGVO — Master-Prompts und Generierungen sind redaktionelle Werkzeuge mit Admin/Manager-Freigabe.
- brand_vision_categories (PROJ-654 + PROJ-754 + PROJ-1048): Bildkategorie-Master-Prompts pro Kunde. Spalten: id, workspace_id (CASCADE), customer_id (FK contacts CASCADE), category_slug (CHECK 5 Standards portrait/action/product/lifestyle/abstract ODER Custom-Slug-Regex aus PROJ-754), status (draft/in_review/approved), master_prompt (JSONB — 4-Block-Komposition: brand_prefix/technical/aesthetic/negative, max ~5000 Zeichen Gesamtsumme), parameters (JSONB — Kamera-/Optik-/Licht-/Ästhetik-Parameter), claude_analysis (JSONB — Claude-Vision-Output: Stil-Stichworte, Komposition, Licht-Erkennung), preview_brand_asset_id (FK brand_assets SET NULL — letztes KI-Vorschau-Bild), preview_image_url (TEXT ≤2000 Zeichen — PROJ-1048: direkter Storage-URL des ersten hochgeladenen Analyse-Eingangsbilds; kann Personenbezug enthalten — identisches DSGVO-Regime wie hochgeladene Kundenrohbilder; Retention bis Kategorie-Löschung, nicht Session-basiert), preview_source (TEXT CHECK ki_generated/manual_upload — PROJ-1048: Herkunftstracking, kein PII), approved_by_user_id (FK auth.users SET NULL), approved_at, created_by (FK auth.users CASCADE), last_edited_by_user_id (FK auth.users SET NULL), created_at, updated_at. PROJ-754 Custom-Bildkategorien-Stammdaten (custom_title 1–80 Zeichen, custom_subtitle 0–200 Zeichen, custom_higgsfield_model — Higgsfield-Modell-Wahl aus Whitelist): Admin/Manager können workspace-globale Custom-Kategorien (customer_id=NULL) mit freiem Titel und optionaler Unterzeile anlegen, zusätzlich zu den 5 hartkodierten Standards. Custom-Felder sind durch Paired-CHECK custom_fields_consistency mit category_slug-Klasse verknüpft (Standards haben NULL, Custom haben NOT NULL + Längen-Bounds). Slug wird automatisch via slugify(title) + Hex-Suffix bei Kollision generiert (workspace-scoped Eindeutigkeit). Titel/Unterzeile sind redaktionelle Bezeichnungen für interne Konfiguration (kein PII von Endkunden). Master-Prompts sind redaktionelle Bildbeschreibungen ohne PII. Claude-Vision-Analyse beschreibt visuelle Stil-Merkmale, kein Personenbezug. Keine Übermittlung der Custom-Stammdaten an externe Auftragsverarbeiter (LLM-Detector bleibt hartcodiert auf 5 Standards). Rechtsgrundlage: Art. 6 Abs. 1 lit. b + f DSGVO. RLS: SELECT alle aktiven Workspace-Member, INSERT/UPDATE/DELETE Admin+Manager. Workspace-scoped, CASCADE-DELETE bei Workspace- oder Kontakt-Löschung.
- brand_vision_sessions (PROJ-654): Container für Phase-2/3-Generierungs-Sessions. Spalten: id, workspace_id (CASCADE), customer_id (FK contacts CASCADE), phase (CHECK transform/generate), user_id (FK auth.users CASCADE), created_at, last_active_at. Keine PII direkt — Session-Metadaten zur Gruppierung mehrerer Generierungen. RLS: SELECT alle aktiven Workspace-Member, INSERT/UPDATE eigener User+Admin+Manager. Workspace-scoped, CASCADE-DELETE bei Workspace- oder User-Löschung. Cleanup-Cron 'brand-vision-cleanup' (täglich 03:15 UTC) löscht Sessions deren last_active_at > 30 Tage zurückliegt — kaskadiert via FK auf brand_vision_generations.
- brand_vision_generations (PROJ-654 + PROJ-1048): Einzel-Generierungen pro Session. Spalten: id, workspace_id (CASCADE), session_id (FK brand_vision_sessions CASCADE), category_id (FK brand_vision_categories SET NULL), phase (CHECK transform/generate), status (pending/running/completed/failed), prompt_snapshot (JSONB — komplette zusammengesetzte Prompt-Komposition zur Reproduzierbarkeit), reference_inputs (JSONB — Storage-URLs zu hochgeladenen Kunden-Rohbildern UND Marken-Asset-Referenzen via @-Mention, max 3 pro Generierung), model_used (CHECK soul/flux/seedream/nano_banana/gpt_image), strength (NUMERIC 0.3–0.9 — Image-to-Image-Anteil), external_job_id (Higgsfield-Job-ID, max 500 Zeichen), higgsfield_job_id (FK cms_higgsfield_jobs SET NULL), result_image_url (max 2000 Zeichen — generiertes Bild-URL oder bei PROJ-1048-Ersetzung: URL des manuell hochgeladenen Ersatz-Bilds; Ersatz-Bilder können Personen zeigen — DSGVO-Aufklärung im ImageReplaceDialog Pflicht), brand_asset_id (FK brand_assets SET NULL), error_message (max 5000 Zeichen), error_provider (CHECK higgsfield_ai/anthropic_claude), claim_locked_until (Worker-Claim R-586), created_by (FK auth.users CASCADE), created_at, completed_at. PROJ-1048-Erweiterungen: source (TEXT CHECK ki_generated/manual_upload NOT NULL DEFAULT ki_generated — Herkunftstracking, kein PII), original_result_url (TEXT — Backup des originalen KI-Bilds vor Ersetzung, kein PII da KI-generiert), replaced_at (TIMESTAMPTZ — Audit-Zeitstempel), replaced_by_user_id (UUID FK auth.users ON DELETE SET NULL — Audit-Feld, bei User-Löschung auf NULL gesetzt). Reference_inputs kann Signed-URLs zu Kunden-Rohbildern enthalten, die theoretisch Personen abbilden — Bilder werden während der Higgsfield-Generierung transient an Higgsfield übermittelt, kein persistentes Speichern bei Higgsfield. Rechtsgrundlage: Art. 6 Abs. 1 lit. b + f DSGVO. RLS: SELECT alle aktiven Workspace-Member, INSERT via Worker (Service-Role) ODER eigener User, UPDATE/DELETE Admin+Manager. Workspace-scoped, CASCADE-DELETE bei Session-Löschung.
- Hochgeladene Bilder (Storage): Drei Storage-Subpfade im workspace-isolierten brand-assets-Bucket (foldername[1] = workspace_id): (1) Kundenrohbilder Phase 2 '{workspace_id}/brand-vision-studio/{categoryId}/{session_id}/' — Session-gebunden, 30-Tage-Retention. (2) PROJ-1048 Analyse-Eingangsbilder 'analysis-inputs/' '{workspace_id}/brand-vision-studio/{categoryId}/analysis-inputs/' — Kategorie-gebunden, Retention bis Kategorie-Löschung (NICHT Session-basiert; Nutzung: einmalig zur Prompt-Generierung via Claude Vision). (3) PROJ-1048 Ersatz-Bilder 'replacements/' '{workspace_id}/brand-vision-studio/{categoryId}/replacements/{generationId}/' — Session-gebunden (via brand_vision_generations CASCADE auf brand_vision_sessions), 30-Tage-Retention. DSGVO-Besonderheit: Alle drei Subpfade können Personenbezug enthalten (Mitarbeiterportraits, Lifestyle-Aufnahmen, explizit bei Ersatz-Bildern: echte Personen als Ersatz für KI-Output). Besondere Sorgfalt: User-Aufklärung im Upload-Flow durch DSGVO-Banner (Phase 2) bzw. Dialog-Beschreibung (PROJ-1048 Ersetzen-Flow). Storage-RLS: foldername(1) = workspace_id, nur Admin+Manager schreibt, alle aktiven Member lesen.
- Generierte Bilder (in brand_assets): Outputs von Phase 2/3 werden bei expliziter User-Aktion 'In Markenassets übernehmen' in der bestehenden brand_assets-Tabelle persistiert. Neue source_kind-Enum-Erweiterung 'brand_vision_studio' (vs. bestehende cms_uploads/higgsfield/manual). is_ai_generated=true (EU AI Act Art. 50 — Kennzeichnung als synthetischer Inhalt, ✦ KI-generiert-Badge in der UI). Neue optionale Spalte source_brand_vision_generation_id (FK brand_vision_generations SET NULL) verlinkt das Asset zurück zur erzeugenden Generierung für Audit-Trail und Re-Generation.
- Externe Auftragsverarbeiter: (1) Anthropic Claude (claude-sonnet-4-6 für Bildanalyse via Claude Vision, claude-haiku-4-5 für Kategorie-Erkennung) — hochgeladene Bilder via Signed-URL (15min TTL) und Kategorie-Beschreibungstexte werden transient zur Master-Prompt-Synthese bzw. Kategorie-Klassifikation gesendet. Prompt-Caching auf System-Prompts (cache_control: ephemeral, R-658). Keine Persistenz bei Anthropic. (2) Higgsfield AI — Prompt + CI-Hex-Farben + Signed-URLs zu Reference-Images (Kunden-Rohbilder Phase 2, Marken-Asset-Referenzen via @-Mention Phase 3) pro Generation; Quota gemeinsam mit PROJ-596/607/652. Hardcoded Wordlist-Filter (Personen-Namen, NSFW, Markenrechte) blockt vor Übermittlung. Bei Mock-Modus (adapter_mode='mock') keine Datenübermittlung — alle Generierungen lokal über MockHiggsfieldAdapter.
AI Talk Studio (PROJ-666)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — eigene Unternehmenskommunikation und Content-Marketing-Produktion der Agentur). Auftragsverarbeitung gegenüber OpenAI (Whisper-Transkription, siehe Voice-PROCESSOR-Eintrag), Anthropic PBC (Claude Sonnet 4.6 für NORA-Dialog, siehe PROCESSORS) und ElevenLabs Inc. (Text-zu-Sprache-Synthese, neuer PROCESSORS-Eintrag) gem. Art. 28 DSGVO.
- Gesprochene Inhalte (via OpenAI Whisper transkribiert): Marketing-Themen, Agentur-Insights, Kundenperspektiven — ausschließlich vom Nutzer Marcel Hoenerbach selbst aufgenommen (kein Dritter im MVP).
- Generierte KI-Antworten (Claude Anthropic Sonnet 4.6): NORA-Dialog-Antworten auf Basis des Agentur-Wissens; System-Prompt enthält statisches NEULAND-Unternehmenswissen + NeulandOS-Featureliste (keine Endkunden-PII). Conversation-History wird pro API-Aufruf an Anthropic übermittelt — keine dauerhafte Speicherung bei Anthropic, kein Training.
- Sprachsynthese-Texte (an ElevenLabs übermittelt): NORA-Antworttext (max. 2000 Zeichen pro Call) wird zur Sprachsynthese mit der konfigurierten NORA-Voice-ID an ElevenLabs gesendet. Antwort: audio/mpeg-Stream, transient. Keine Persistenz bei ElevenLabs.
- Optional CTA-Text (Call-to-Action, max. 300 Zeichen): Wird pro Session konfiguriert und im System-Prompt von Claude an NORA übergeben — kein Endkunden-PII, sondern Marketing-Botschaft der Agentur.
- Lokale Session-Artefakte auf dem Mac des Nutzers: MP4-Aufnahme + Markdown-Transkript unter ~/Movies/Neuland AI Talk/. KEINE DB-Einträge im NeulandOS — Sessions werden nicht serverseitig persistiert.
KI-Requirements-Assistent im Feature-Wunsch-Flow (PROJ-662 + PROJ-664)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse: strukturierte Anforderungs-Briefings reduzieren Rückfragen-Schleifen und beschleunigen die Entwicklungs-Pipeline; KI-gestützte 5-Phasen-Konversation erzeugt vollständige, testbare Feature-Spezifikationen ohne dass der Einreicher Requirements-Engineering-Kenntnisse mitbringen muss). Auftragsverarbeitung gegenüber Anthropic Inc. und GitHub Inc. gem. Art. 28 DSGVO (siehe PROCESSORS-Einträge).
- PROJ-662 requirements_drafts (Konversations-Metadaten + generierte Feature-Spezifikation): pro Draft id (UUID), workspace_id (FK CASCADE), conversation_id (FK ai_conversations CASCADE), created_by (FK auth.users SET NULL — Audit-Trail bleibt nach Mitarbeiter-Löschung), current_phase (1-5: Kern-Idee/User Stories/ACs/Edge Cases/Scope), feature_name (kebab-case-Slug, Regex [a-z0-9-]), generated_spec_md (Markdown-Volltext der finalen Feature-Spezifikation — kann User-formulierte Beschreibungen mit impliziten Personenbezügen enthalten, max 50.000 Zeichen), proj_id (PROJ-X nach Commit), commit_sha + commit_url (GitHub-Referenz), status-Enum (in_progress/spec_generated/committed/archived), Zeitstempel created_at/updated_at/archived_at. Verknüpfter Chat-Verlauf in ai_conversation_messages (Frage-Antwort-Paare User ↔ Claude Sonnet 4.6 mit input_tokens/output_tokens-Tracking via ai_token_logs). System-Prompt wird workspace-spezifisch in ai_assistants.system_prompt (slug='requirements-assistant', is_system=true) gepflegt und ist Admin-editierbar (Custom-Gem-Pattern, PROJ-65). Workspace-Einstellungen workspaces.github_repo_owner + github_repo_name + requirements_target_branch (Klartext-Metadaten) + github_token_encrypted (AES-256-GCM via GITHUB_REQUIREMENTS_TOKEN_ENCRYPTION_KEY, R-313 Key-Isolation gegenüber HIGGSFIELD_TOKEN_ENCRYPTION_KEY etc.). Externe Übermittlung: (1) Anthropic Inc. (Sonnet 4.6) für Chat + Spec-Generierung (transient, kein Training), (2) GitHub Inc. für atomaren 2-File-Commit der spec.md + INDEX.md-Update über Tree+Commit+Ref-API. Token-Tracking via logTokenUsage(feature='ai_requirements_assistant_chat' bzw. 'ai_requirements_assistant_spec_generation'). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Entwicklungs-Effizienz durch strukturierte Feature-Briefings). RLS: workspace_member darf eigene Drafts SELECT/INSERT/UPDATE, admin+manager sehen alle Workspace-Drafts (R-369). Workspace-scoped, CASCADE-DELETE bei Workspace-Löschung. PII-Awareness: User trägt Verantwortung für Inhalts-Prüfung der Spec vor Commit, da generated_spec_md im GitHub-Repo dauerhaft öffentlich-intern verbleibt (Doku-Charakter).
- PROJ-664 requirements_draft_attachments (Chat-Anhänge im Feature-Brief-Workflow): pro Anhang id (UUID), draft_id (FK CASCADE), message_id (FK ai_conversation_messages CASCADE — NULL während Upload-Phase, gesetzt nach User-Send), workspace_id (FK CASCADE), uploaded_by_user_id (FK auth.users CASCADE), file_name (Original-Dateiname max. 255 Zeichen), mime_type (image/png, image/jpeg, image/webp, image/gif, application/pdf — Whitelist), size_bytes (max. 10.485.760 = 10 MB pro Datei), storage_path (Pfad in privatem Supabase-Storage-Bucket 'requirements-attachments' im Format <workspace_id>/<draft_id>/<id>.<ext>), extracted_text (Plain-Text aus PDF-Anhängen via pdf-parse, max. 100.000 Zeichen — bei Bildern immer NULL — kann implizit PII aus dem PDF-Inhalt enthalten), status-Enum (uploading/ready/failed), Zeitstempel created_at/updated_at. Storage-Bucket privat, Zugriff nur über Signed-URLs mit TTL 1h (UI-Anzeige) bzw. 7 Tage (Spec.md-Einbettung im GitHub-Repo). Cap pro Draft: 50 MB kumulativ über alle Anhänge. Bilder werden vor Anthropic-Übertragung serverseitig auf max. 2048 px Längstkante via sharp komprimiert. Magic-Byte-Check (R-228) gegen MIME-Type-Spoofing serverseitig. Externe Übermittlung: (1) Anthropic Inc. (Claude Sonnet Vision) für Multimodal-Chat — Bilder gehen als Base64-Vision-Block in den messages.create()-Call mit, PDF-Plain-Text wird als Text-Block vor die User-Nachricht gemerged (transient, kein Training, keine Datenpersistenz bei Anthropic). Bilder + PDF-Text werden NICHT an GitHub übermittelt, sondern verbleiben in Supabase-Storage; in der spec.md werden lediglich Signed-URLs eingebettet (TTL 7 Tage, danach manueller Refresh durch Admin über dokumentierten Storage-Pfad). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — präzisere Anforderungs-Briefings durch visuelle Mockups + PDF-Briefings). RLS: workspace_member darf eigene Anhänge SELECT/INSERT/UPDATE, admin+manager sehen alle Workspace-Anhänge. Storage-RLS: (storage.foldername(name))[1] = workspace_id::text (R-156 Hard-Blocker). Workspace-scoped, CASCADE-DELETE bei Draft-/Workspace-/Message-Löschung. PII-Awareness: Mitarbeiter trägt Verantwortung für PII-Prüfung der hochgeladenen Mockups + PDF-Inhalte — insbesondere Screenshots können personenbezogene Inhalte (E-Mail-Adressen, Telefonnummern, Klarnamen) enthalten.
Feature Brief Module (PROJ-811): Wizard-basierte PM-Briefings mit KI-Systemabgleich
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — strukturierte Wizard-Briefings ermöglichen Produkt-Managern ohne tieferes Tech-Wissen präzise Feature-/Bug-Beschreibungen zu erstellen; KI-Systemabgleich (Claude Haiku) reduziert manuelle DB-Schema-Recherche und Spec-zu-Code-Drift; PROJ-813 KI-Mockup-Generierung (Claude Sonnet 4.6) erweitert die Briefing-Qualität um eine visuelle Komponente; PROJ-842 Unified Entry Point + Gesprächsmodus erlaubt freien Briefing-Einstieg statt starrer Branch-Wahl). Auftragsverarbeitung gegenüber Anthropic Inc. gem. Art. 28 DSGVO (siehe PROCESSORS-Eintrag).
- PROJ-811 feature_briefs (strukturierte Feature-/Bug-Briefings via Wizard, separat zu PROJ-662 chat-basierten Drafts): pro Briefing id (UUID), workspace_id (FK CASCADE), created_by (FK auth.users — Ersteller, Audit-Trail bleibt bei User-Löschung), validated_by (FK auth.users, nullable — wer hat das Briefing freigegeben), branch (feature_request|bugfix_release|bugfix_assisted|design), status (draft|draft_conversation|validated|handed_off|review_ready|completed|rejected — PROJ-833 AC-1.1, PROJ-1439), status_before_rejection/rejected_reason/rejected_by/rejected_at (PROJ-1439 — nur bei Status rejected gesetzt, rejected_by FK auth.users ON DELETE SET NULL, rejected_reason optionale Freitext-Notiz max. 2000 Zeichen, bleibt bei Reaktivierung erhalten), completed_at (Zeitstempel der manuellen Abnahme, nullable, kein PBD — PROJ-833 AC-3.1), feature_group (optionales Freitext-Label max. 50 Zeichen z.B. PROJ-814 zur Gruppen-Zuordnung verwandter Briefings, kein PBD — PROJ-833 AC-5.1), title (max 200 Zeichen, vom Ersteller frei vergeben), description (max 50.000 Zeichen — kann implizite Personenbezüge enthalten wenn der Ersteller in der Beschreibung interne Namen / Kunden / Mitarbeiter erwähnt; internes Tool, keine End-Nutzer-PII), version_context JSONB (bei Bug-Branch B: gewählte Release-Version + Erste-betroffene-Version, Referenz auf app_releases), field_mappings JSONB-Array (PM-Begriff → tabellen.spalte mit data_source, field_type, confidence-Score), affected_components JSONB (für PROJ-812 Branch C reserviert — UI-Elemente die der PM via Debug-Overlay markiert hat: display_name, technical_field, component_name, screenshot_ref), design_mockups JSONB (für PROJ-813 Branch D reserviert — generierte React/Tailwind-Snippets als Mockup-Iterationen), deployment_steps JSONB-Array (Titel, Beschreibung, betroffene Felder/Endpunkte, Akzeptanzkriterien), acceptance_criteria_overall JSONB-Array (übergeordnete Gesamt-ACs), notes (Freitext-Notizen, max 10.000 Zeichen), wizard_state JSONB (Auto-Save-Zwischenstand des Wizards: aktueller Schritt + partielle Antworten), Zeitstempel created_at/updated_at/validated_at. PROJ-833: dev_sessions.feature_brief_id (UUID-FK, kein PBD) verknüpft Dev-Sessions mit einem Feature-Brief für Auto-Sync — ON DELETE SET NULL (Sessions bleiben erhalten wenn Brief gelöscht wird). RLS: alle Workspace-Mitglieder dürfen lesen (SELECT-Policy auf workspace_members), nur Ersteller darf editieren (UPDATE-Policy mit USING + WITH CHECK + status='draft'-Gate), nur Ersteller darf validieren und löschen (Draft-Status), Admin/Manager dürfen feature_group + Status-Übergänge setzen. Notification-Trigger: (1) draft → validated: alle Members (feature_brief_validated, PROJ-811); (2) handed_off → review_ready (auto via nw complete oder manuell): nur Admin+Manager (feature_brief_review_ready, PROJ-833 AC-4.1); (3) review_ready → completed: nur Admin+Manager (feature_brief_completed, PROJ-833 AC-4.4); (4) beliebiger Status außer completed → rejected (PATCH /:id/reject bzw. /bulk): an created_by, außer Ablehnender ist selbst Ersteller (feature_brief_rejected, PROJ-1439). Alle vier Typen in notifications_type_check-Constraint (R-686-Rollup). Externe Übermittlung an Anthropic Inc. erfolgt in drei Endpunkten: (1) /analyze (PROJ-811, Claude Haiku 4.5): PM-Beschreibung + gecachter DB-Schema-Snapshot (50 public-Tabellen, nur Namen+Typen, sensible Spalten *_encrypted/*_token/*_secret ausgefiltert, KEINE Werte/Inhalte), 60s Timeout, Token-Tracking via logTokenUsage(feature='feature_briefs_analyze'). (2) /generate-mockup (PROJ-813, Claude Sonnet 4.6): PM-Beschreibung + statischer shadcn-Komponenten-Snapshot + bisherige Iterations-History (Code + Feedback-Texte; ab Iteration ≥ 4 wird die Historie komprimiert — ältere JSX-Iterationen werden weggelassen, Feedback-Notizen bleiben), 60s Timeout, max. 10 Iterationen pro Briefing, Token-Tracking via logTokenUsage(feature='feature_briefs_generate_mockup'). (3) /suggest-acceptance-criteria (PROJ-811 Bugfix 2026-05-27, Claude Haiku 4.5): PM-Beschreibung + Titel/Beschreibung der Deployment-Schritte + bereits vorhandene Akzeptanzkriterien als Anti-Duplikat-Hinweis, 30s Timeout, Output 5–8 outcome-orientierte Kriterien (≤ 200 Zeichen pro Eintrag), Token-Tracking via logTokenUsage(feature='feature_briefs_suggest_acs'). Alle drei Endpunkte: transient, kein Training, Prompt-Caching via cache_control:ephemeral. Anhang-Support gibt es in PROJ-811 NICHT (Chat-basierte requirements_drafts mit Bildern bleiben in PROJ-662). Markdown-Export (Art. 20 Datenübertragbarkeit) via GET /:id/export — Briefing kann als .md-Datei oder Clipboard-String entnommen werden, Status wechselt nach Export auf 'handed_off'. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — strukturierte Feature-Briefings beschleunigen die Entwicklungs-Pipeline, KI-Systemabgleich reduziert Spec-zu-Code-Drift). Workspace-scoped, CASCADE-DELETE bei Workspace-Löschung. PII-Awareness: PM trägt Verantwortung für PII-Prüfung der Beschreibung, da das Briefing potenziell extern an Claude Code übergeben oder via Markdown-Export geteilt wird.
- PROJ-812 Debug-Overlay-Annotationen (feature_briefs.affected_components, JSONB-Array — Sub-Feld in der bestehenden feature_briefs-Tabelle): Pro Bug-Briefing in Branch C (Assisted Bug Fix) speichert das System die im Debug-Overlay angeklickten UI-Elemente mit Komponenten-Metadaten und Fehlertyp-Auswahl. Pro Item: debug_id (kebab-case-slug, FK-soft-Reference auf feature_brief_component_registry), display_name + technical_field (Snapshot aus Registry zum Zeitpunkt der Annotation — bleibt lesbar auch wenn Registry-Eintrag später gelöscht wird), route (tatsächlicher Pfad zum Klick-Zeitpunkt — kann impliziten Workspace-Slug oder Entity-IDs enthalten wie /agentur/crm/kontakte/abc-123, also potenziell internen Audit-Trail-Charakter), bug_types (1–5 aus wrong_field_mapping|wrong_display_value|wrong_label|should_be_removed|other), expected_value/expected_label/free_text (optionale PM-Eingaben je nach Bug-Typ), screenshot_ref (Base64-Data-URL eines html2canvas-Screenshots des betroffenen DOM-Elements, ~200–500 KB — KANN PII enthalten wenn die Dashboard-Ansicht zum Klick-Zeitpunkt Kontaktnamen, E-Mail-Adressen oder andere personenbezogene Daten zeigt; html2canvas-Fehler → screenshot_ref:null), captured_at (Timestamp). Limit: max 50 Items pro Briefing. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse interner Bug-Reports, beschleunigte UI-Fehlerdokumentation). Workspace-scoped via feature_briefs.workspace_id, CASCADE-DELETE bei Workspace-Löschung (über bestehende PROJ-811-FK). Zusätzlich CASCADE bei Briefing-Löschung (Drafts vom Ersteller). Datenexport (Art. 15/20): Bereits via PROJ-811 in /api/workspaces/data-export enthalten (feature_briefs.affected_components ist Teil des SELECT). PII-Awareness: Der PM ist verantwortlich vor Klick auf 'Briefing abschließen' zu prüfen, ob im Screenshot personenbezogene Daten von Endkunden sichtbar sind — wenn ja, ist das Briefing intern zu halten und nicht extern (z.B. via Markdown-Export) zu teilen.
- PROJ-812 feature_brief_component_registry (Registry-Tabelle für Debug-Overlay-Annotationen, KEINE PII): id (UUID), workspace_id (FK CASCADE), debug_id (kebab-case-Slug, UNIQUE per workspace_id), display_name + technical_field + route_pattern (rein technische Metadaten für die UI-Element-Identifikation), component_name (optional, React-Komponenten-Name), data_source (internal_db|external_api|computed|static_text), field_type (string|number|boolean|date|enum|json), example_value (Beispielwert, kein Live-PII), created_by (FK auth.users), created_at/updated_at. RLS: alle Workspace-Mitglieder dürfen lesen (Debug-Overlay-Provider benötigt Lookup); nur Admin und Manager dürfen INSERT/UPDATE/DELETE. Workspace-scoped, CASCADE-DELETE bei Workspace-Löschung. Wird NICHT in den Datenexport aufgenommen, da reine technische Konfigurations-Metadaten ohne Personenbezug. PROCESSORS-Anlage: keine — die Registry wird nur lokal in der Supabase-DB gehalten und nicht an externe Auftragsverarbeiter übermittelt.
- PROJ-813 Design-Mockup-Generierung (feature_briefs.design_mockups, JSONB-Array): Pro Briefing in Branch D oder Branch A Schritt 5 speichert das System bis zu 10 KI-generierte Code-Iterationen (JSX-Fragment + PM-Feedback + Pins). Generierter Code enthält keine PII (statische UI-Mockups). PM-Feedback-Texte können implizite interne Inhalte enthalten. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse Briefing-Qualität). CASCADE-DELETE via feature_briefs.workspace_id → workspaces.
- PROJ-830 PM-UX-Erweiterung (feature_briefs.field_mappings — Sub-Felder, JSONB-Array): Ergänzt bestehende Feldzuordnungen (PROJ-811) um zwei neue Sub-Felder pro Eintrag: (1) status (Enum: auto|pm_confirmed|new_field_required|pm_overridden|unresolved — reine Prozess-Metadaten, kein Personenbezug), (2) pm_description (nullable JSONB-Objekt mit 3 Pflichtfeldern purpose/possible_values/frontend_location + optionalem dependencies — qualitative Beschreibungen technischer System-Felder vom PM verfasst; i.d.R. kein Personenbezug, da die Beschreibung Feld-Semantik beschreibt, nicht Personen). Modul-Browser-API (GET /api/feature-briefs/module-fields): liefert Feldnamen + Beispielwerte aus workspace-eigenem DB-Schema transient an den Browser (admin/manager-only). PII-Spalten (email, phone, first_name, last_name, address, iban etc.) werden durch generische Platzhalter ersetzt (PII_COLUMN_PATTERNS-Denylist, 15+ Muster). Keine eigene Datenpersistenz — Beispielwerte werden NIE gespeichert. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — PM-Assistenz ohne technische DB-Kenntnisse). Speicherdauer: pm_description und status mit feature_briefs-Lifecycle (CASCADE-DELETE). Datenexport (Art. 15/20): bereits via PROJ-811 in /api/workspaces/data-export enthalten (field_mappings ist Teil des SELECT).
- PROJ-842 Unified Entry Point + Reifegrad-Analyse (feature_briefs — neue Spalten + JSONB-Sub-Felder): Ergänzt das Briefing-Modul um einen freien Texteingabe-Einstieg und einen KI-gestützten Gesprächsmodus. Sieben neue Spalten pro Briefing: (1) entry_input TEXT max 15.000 Zeichen — die ursprüngliche, ungekürzte PM-Eingabe; kann implizite interne Personenbezüge enthalten (Mitarbeiter-/Kunden-Namen wenn der PM diese im Briefing-Text erwähnt), analog description; (2) entry_mode TEXT CHECK (architect|gap_fill|direct) — interner Routing-Wert aus der Reifegrad-Analyse, kein Personenbezug; (3) branch_detected TEXT — automatisch erkannte Branch durch Claude Haiku 4.5, kein Personenbezug; (4) branch_confirmed_by_pm BOOLEAN DEFAULT FALSE — Flag ob PM die Branch korrigiert hat, kein Personenbezug; (5) maturity_assessment JSONB — {concept_maturity (vague|partial|concrete|complete), system_alignment (unknown|partial|known|conflict)} — interne Analyse-Werte aus dem LLM-Call, kein Personenbezug; (6) conversation_log JSONB DEFAULT '[]' — vollständiger Gesprächsverlauf zwischen PM und Claude Haiku 4.5 als Array von Objekten mit role (assistant|pm), message (Text), timestamp (ISO8601) und type (question|answer|proposal|system_reference|transition|import_summary). Append-only, kein nachträgliches Editieren einzelner Einträge. Kann implizite interne Personenbezüge enthalten wenn der PM während des Gesprächs Namen/Kontakte erwähnt — analog zu description. Max-Längen pro Turn: 15.000 Zeichen Assistant, 2.000 Zeichen PM. Anzahl Turns durch 20-Turn-Limit nach oben begrenzt; (7) import_source TEXT CHECK (external_model|direct_input) — Herkunfts-Marker ob die Eingabe ein importiertes Gespräch aus einem externen Modell (ChatGPT/Claude.ai) oder direkter PM-Input war, kein Personenbezug. Zusätzlich: assistant_decisions JSONB DEFAULT '[]' — internes LLM-Decision-Logging für Audit/Debug-Zwecke (Branch-Confidence, Mode-Routing, Turn-Counts), kein direkter Personenbezug, wird NICHT in den Workspace-Datenexport aufgenommen (interner Operator-Audit-Trail ohne Auskunfts-Anspruch des Betroffenen). Externe Übermittlung an Anthropic Inc. erfolgt in drei NEUEN Endpunkten zusätzlich zu den PROJ-811/PROJ-813-Endpunkten: (a) /api/feature-briefs/analyze-and-create (Claude Haiku 4.5): PM-Eingabe + gecachter NEULAND-OS Modul-Katalog-String (statisch, Workspace-übergreifend) → strukturiertes JSON mit branch_detected + concept_maturity + system_alignment + entry_mode + first_assistant_message; (b) /api/feature-briefs/:id/chat (Claude Haiku 4.5): kompletter conversation_log + gecachter Modul-Katalog → nächste Assistent-Antwort als strukturiertes JSON; (c) /api/feature-briefs/:id/transition-to-wizard (Claude Haiku 4.5): conversation_log + entry_input → strukturiertes Briefing-Objekt (title, description, deployment_steps, acceptance_criteria_overall) für Wizard-Vorbefüllung. Alle drei Endpunkte: 45s Timeout, transient, kein Training, Prompt-Caching via cache_control:ephemeral, Token-Tracking via logTokenUsage (feature='feature_briefs_analyze_and_create' bzw. 'feature_briefs_chat' bzw. 'feature_briefs_transition_to_wizard'). Status-Lifecycle-Erweiterung: neuer Status 'draft_conversation' für Modus A/B Briefings die noch im Gesprächs-Modus sind (nicht im Wizard); Übergang zu 'draft' erfolgt via /transition-to-wizard oder Modus C direkt. RLS-Update: UPDATE-Policy erweitert auf status IN ('draft', 'draft_conversation'). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Briefing-Qualität durch freien Einstieg + KI-Gesprächsführung statt starrer Branch-Wahl). CASCADE-DELETE bei Workspace-Löschung über die bestehende feature_briefs.workspace_id-FK; CASCADE bei Briefing-Löschung über das Parent-Briefing. Datenexport (Art. 15/20): entry_input, entry_mode, branch_detected, branch_confirmed_by_pm, maturity_assessment, conversation_log und import_source sind in /api/workspaces/data-export enthalten (R-241/R-707-Sync). assistant_decisions ist NICHT enthalten — internes Operator-Logging. PROJ-1019 Abnahme/Änderungsrunde (feature_briefs.change_requests JSONB DEFAULT '[]'): Wenn ein Briefing im Status 'review_ready' steht, kann der PM statt der Abnahme eine Nachbesserung anfordern; die Beschreibung der nötigen Änderungen wird append-only pro Eintrag {description, requested_by (auth.users.id), requested_at} gespeichert. change_requests.description kann implizite interne Personenbezüge enthalten wenn der PM Namen/Kontakte erwähnt — analog description/notes; in /api/workspaces/data-export enthalten (R-707-Sync). Zwei Entstehungswege: (a) der ursprüngliche /request-changes-Endpunkt (Status → 'handed_off', ruft KEIN LLM auf, Freitext direkt vom PM); (b) seit PROJ-1161/Bugfix 2026-07-06 der reguläre Weg über PATCH /:id/status (Status → 'draft_conversation', „Zurück in den Chat“) — hier legt der Endpunkt zunächst einen Eintrag mit leerer description an, die bestehende Chat-Route (/:id/chat, PROJ-860/885-Datenfluss) befüllt sie beim erfolgreichen Abschluss der Änderungsrunde mit der vom LLM erzeugten transition_summary (keine zusätzliche externe Übermittlung — nutzt denselben Chat-Aufruf, der ohnehin für dieses Briefing läuft). change_requests folgt — wie die übrigen Briefing-Felder (description/notes/deployment_steps/synthesis_data) — der bestehenden Verarbeitung des Briefings: Beim Start einer lokalen Entwicklungs-Session wird der Eintrag in das an Claude Code übergebene Briefing-Markdown aufgenommen (Operator-eigenes KI-Coding-Tooling, Art. 28 ggü. Anthropic Inc. wie für die übrigen Briefing-Inhalte). CASCADE-Löschung über feature_briefs (Spalte, keine eigene Tabelle).
Shop-Suche (PROJ-767): Search-Suggest, fehlertolerante Volltextsuche, Admin-Synonyme und Search-Analytics
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse — Verbesserung der Such-Qualität im Shop, Identifikation von Sortimentslücken über Null-Treffer-Analyse, Erhöhung der Conversion-Rate). Such-Daten sind PII-arm (gehashter IP statt Klartext, User-Agent auf Browser+OS redacted). Die schwächere Schutzwirkung der Verarbeitung gegenüber dem berechtigten Interesse ist durch die kurze Speicherdauer (180 Tage), die PII-Reduktion und das Workspace-Scoping ausgeglichen.
- PROJ-767 search_queries (Such-Anfragen-Analytics, Shop-DB mjvfwvkkaqyipuwspaoy): pro Anfrage id (UUID), workspace_id (Workspace-Scope), query (rohe Such-Eingabe des Nutzers max 200 Zeichen — kann unbeabsichtigt PII enthalten wenn ein Endkunde z.B. seinen Namen tippt), normalized_query (lowercase + unaccent, für Aggregation), result_count, clicked_product_id (FK products SET NULL), clicked_at, latency_ms, source-Enum (header_suggest/search_page/category_search), ip_hash (SHA-256 von x-forwarded-for mit Server-Salt — Re-Identifikation des Endgeräts technisch nicht möglich ohne Kenntnis des Salts), ua_redacted (User-Agent reduziert auf Browser+OS, z.B. 'Chrome on macOS' — keine Versionsnummern, kein Device-Fingerprint), created_at. Geschrieben vom anonymen Shop-Frontend bei jeder Such-Anfrage (anon-Insert via RLS-Policy mit Source-Whitelist + non-empty workspace+query CHECK). Gelesen ausschließlich Service-Role durch das neuland-os Admin-UI im Tab 'Suche → Auswertung' (Top-Queries, Null-Treffer-Quote, Click-Rate, 30-Tage-Zeitleiste). Retention: 180 Tage, automatischer DELETE durch Vercel-Native-Cron `/api/cron/search-cleanup` (täglich 03:15 UTC im shop-system-Repo). Workspace-Datenexport (Art. 15/20 DSGVO): enthält alle search_queries des Workspaces inklusive ip_hash und ua_redacted (keine Re-Identifikation des Betroffenen ohne Salt, daher kein 1:1-Auskunfts-Mapping pro Person möglich — Auskunft erfolgt aggregiert über Workspace-Scope).
- PROJ-767 search_synonyms (Admin-pflegbare Synonyme, Shop-DB): pro Eintrag id, workspace_id, term (Quell-Begriff max 100 Zeichen), synonyms (TEXT[] bis 20 Einträge à 100 Zeichen), source (manual/inbox/import), created_at/updated_at. Reine Konfigurations-Daten ohne Personenbezug. Anlage durch Workspace-Admins im Admin-Tab 'Suche → Synonyme' oder via Stufe 2.5 Quick-Add aus der Inbox. Wird vom Shop-Frontend bei jeder Such-Anfrage gelesen (Synonym-Expand vor FTS), öffentliche SELECT-Policy auf der Shop-DB. Retention: solange Workspace existiert. Im Datenexport enthalten.
- PROJ-767 search_query_dismissed (Inbox-Markierungen, Shop-DB, Stufe 2.5): pro Eintrag id, workspace_id, normalized_query, dismissed_by (UUID des Admin-Users aus neuland-os auth.users — kein FK in der Shop-DB, da Cross-DB), dismissed_at. Wird gesetzt wenn Admin im 'Suche → Vorschläge'-Tab eine Null-Treffer-Anfrage als 'kein Synonym sinnvoll' markiert. Reine Workflow-Markierung ohne PII der Endkunden, nur Admin-User-Audit. Retention: solange Workspace existiert. Im Datenexport enthalten.
- PROJ-767 Stufe 3 — products.embedding + embedding_text_hash (Shop-DB, pgvector): pro Produkt ein 1536-dim Float-Vektor (text-embedding-3-small) als semantische Repräsentation des Produkttexts (name + brand + category_path + description + ausgewählte field_values). Speicherort: products-Tabelle in der Shop-DB. Keine PII (Produkttexte sind Public-Shop-Inhalte). Externe Übermittlung: OpenAI Inc. (US) zum Berechnen des Embeddings über die offizielle Embeddings-API (transient — Produkttext wird im Call übertragen, der Vektor zurückgeliefert und in der Shop-DB gespeichert; OpenAI persistiert die Inputs nicht für Training). Re-Embedding nur bei tatsächlicher Text-Änderung (Change-Detection via SHA-256-Hash der kanonischen Text-Repräsentation in embedding_text_hash). Batch-Embed-Cron `/api/cron/embed-products` (Vercel-Native, alle 5 Min, 200 Produkte/Lauf). Retention: solange das Produkt existiert; bei Produkt-Löschung CASCADE.
- PROJ-767 Stufe 3 — search_llm_calls (Cost-Tracking, Shop-DB): pro LLM-Aufruf id (UUID), workspace_id, call_type (embed_query bei Query-Vektorisierung vor Hybrid-Search / rerank bei Top-12-Re-Ranking via Claude Haiku 4.5), model (z.B. 'text-embedding-3-small' oder 'claude-haiku-4-5-20251001'), input_tokens, output_tokens, cache_read_tokens, cache_write_tokens, cost_cents (NUMERIC(10,4)), query_id (FK search_queries SET NULL — verknüpft den LLM-Call mit der ursprünglichen User-Such-Anfrage), latency_ms, success, error_code, created_at. Workspace-scoped via RLS, Service-Role-only (Admin-Read über neuland-os Admin-Tab 'Suche → Auswertung > LLM-Kosten'). Keine direkte PII (die User-Query selbst wird hier nicht gespeichert — nur in search_queries verlinkt). Retention: solange Workspace existiert (Cost-Audit-Funktion, gleicher Aufbewahrungs-Charakter wie Buchhaltungsdaten). Bei Workspace-Löschung manuell zu bereinigen (analog zu den anderen Shop-DB-Tabellen, kein FK auf workspaces.id).
- PROJ-767 Stufe 3 — Endkunden-Such-Query bei aktiviertem Hybrid-Modus (`?mode=hybrid` oder Workspace-Default): Die rohe Such-Eingabe wird transient an OpenAI (Query-Embedding) und ggf. an Anthropic (LLM-Re-Ranking) übermittelt. Beide Provider persistieren die Inputs laut AGB nicht für Training. Die Query wird zusätzlich wie unter `search_queries` beschrieben in der eigenen Shop-DB gespeichert (mit Hash-IP, 180-Tage-Retention). Workspace-Setting `shop_config.search_llm_rerank` steuert ob Re-Ranking aktiv ist (Default: an — siehe AC-3.5); ein einmaliges Admin-Banner beim ersten Stufe-3-Aufruf informiert den Workspace-Admin und verlinkt zur Settings-Seite zum Opt-out. Tagesbudget pro Workspace in `shop_config.search_llm_daily_cap_cents` (Default 1000 Cent = 10 €) verhindert Kosten-Explosion — bei Überschreitung fällt das System bis Mitternacht (Europe/Berlin-Zeit) auf reine RRF-Fusion ohne LLM-Re-Rank zurück. **Endkunden-Opt-out (Stand 2026-05-23):** Cookie-Consent-Banner im shop-system ist noch nicht implementiert (Folge-Ticket); die Spec sieht einen Opt-out-Toggle für „KI-gestützte Suche“ vor, bis zur Umsetzung können Endkunden nur (a) auf eine Workspace-weite Deaktivierung durch den Workspace-Admin zurückgreifen (`search_llm_rerank=false`) oder (b) Browser-Cookies generell blockieren.
Bedarfsgruppen-KI-Assistent (PROJ-1027)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter KI-gestützter Erstellung von Marketing-Seitenstrukturen ohne manuellen CSV-Export; Verarbeitung dient ausschließlich der internen Arbeitseffizienz der Agentur)
- ki_bedarfsgruppen_jobs: workspace_id (Workspace-Zuordnung), contact_id (CRM-Kontakt-Referenz für SSOT-Kontext), ai_assistant_id (FK ai_assistants — konfigurierter Bedarfsgruppen-Assistent), domain_url (eigene Domain-URL für Crawler-Input — öffentlich zugängliche Unternehmens-Domain), competitor_domains (JSONB-Array von Wettbewerber-Domain-URLs — öffentlich zugängliche Unternehmens-Domains aus SSOT Corporate Identity), status (Job-Status: pending/running/done/error), processing_step (aktueller Verarbeitungsschritt für Progress-UI), result_payload (generierte Bedarfsgruppen-Seitenstruktur als JSONB — enthält ausschließlich Marketing-Inhaltsdaten: Segmenttyp, Navigationsebene, Sichtbarkeit, Mehrsprachigkeit; keine PII), error_message (technische Fehlermeldung bei Job-Fehler — keine PII), error_type (PROJ-1087: differenzierte Fehlerklasse MISSING_SSOT/TIMEOUT für die Frontend-Fehlerkommunikation — technische Metadaten, keine PII), progress_percent (PROJ-1087: Fortschrittswert 0–100 für die Ladeanzeige — technische Metadaten, keine PII), progress_detail (PROJ-1087: JSONB-Detail zum aktuellen Verarbeitungsschritt — current_domain/competitor_name sind öffentlich zugängliche Unternehmens-Domain-URLs, keine PII), created_by (FK auth.users ohne CASCADE — User-ID des auslösenden Workspace-Mitglieds; einziger Personenbezug in der Tabelle). Kein direkter Endnutzer-Personenbezug — verarbeitete Domain-URLs sind öffentlich zugängliche Unternehmens-Websites
- Externe Übermittlungen: (1) Web-Crawler (intern, Vercel Serverless): Die ausgewählte eigene Domain-URL wird serverseitig gecrawlt (HTTP-GET auf öffentliche Seiten, max. 2 Ebenen tief, 30s Timeout). Gecrawlt werden ausschließlich öffentlich zugängliche Navigationspfade (Seitentitel, URL, Hierarchieebene). Keine Authentifizierung gegen die Ziel-Domain. SSRF-Schutz: private IP-Ranges und Redirect-Chains auf interne Adressen werden blockiert (BUG-2-Fix). (2) DataForSEO Labs API: eigene Domain-URL und bis zu 20 Wettbewerber-Domain-URLs werden an DataForSEO übermittelt (Domain-Rank-Overview). Auftragsverarbeiter-Eintrag in PROCESSORS. (3) Anthropic Claude API: SSOT-Marketingdaten (Zielmärkte, Marketingziele, Keywords), gecrawlte Navigationsstruktur und DataForSEO-Ergebnisse werden transient übermittelt. Transient, kein Training, keine Persistenz bei Anthropic. Auftragsverarbeiter-Eintrag in PROCESSORS
Bedarfsgruppen-KI-Assistent — Chat-Flow & Onboarding (PROJ-1141)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an einem dialogbasierten KI-Assistenten zur Erstellung von Marketing-Seitenstrukturen; Verarbeitung dient der internen Arbeitseffizienz der Agentur). Erweitert den Bedarfsgruppen-KI-Assistenten (PROJ-1027) um einen persistenten Chat-Verlauf und eine geführte Onboarding-Runde
- ki_bedarfsgruppen_chat_sessions: workspace_id (Workspace-Zuordnung), contact_id (CRM-Kontakt-Referenz — die Session ist einem Kunden-Kontakt zugeordnet), segmenttyp (Bedarfsgruppen-Segment, z.B. Corporate/Recruiting — Marketing-Metadatum), onboarding_abgeschlossen (Boolean-Status), created_by (FK auth.users ON DELETE SET NULL — User-ID des Agentur-Mitglieds das die Session geöffnet hat), created_at/updated_at (Zeitstempel). Eine Session pro Bedarfsgruppe + Segmenttyp; neueste Session gilt als aktiv, ältere bleiben lesbar
- ki_bedarfsgruppen_chat_messages: session_id (FK CASCADE), rolle (user/assistant/system), inhalt (TEXT — der vollständige Nachrichten-Wortlaut. WICHTIG: Im Gegensatz zu anderen KI-Chats werden diese Nachrichten PERSISTENT in der Datenbank gespeichert, NICHT ephemer. Frei getippter User-Text kann personenbezogene Daten enthalten, z.B. Angaben zu Zielgruppen, Ansprechpartnern oder Projektdetails; system-Nachrichten enthalten SSOT-/Blueprint-Kontext ohne direkten Personenbezug), typ (frage/antwort/strukturaenderung/beratung), created_at (Zeitstempel). Bei Seiten-Reload wird der gesamte Verlauf aus der DB neu geladen
- ki_bedarfsgruppen_onboarding_antworten: session_id (FK CASCADE), frage_key/frage_text (Pflichtfrage-Kennung + Fragetext aus der Konstante ONBOARDING_PFLICHTFRAGEN), antwort_text (TEXT — frei getippte Antwort des Agentur-Mitglieds auf die Onboarding-Pflichtfragen, kann projekt-/kundenbezogene Angaben enthalten), ist_pflichtfrage (Boolean), created_at. UNIQUE pro Session + Fragen-Key (keine Duplikate). Persistent gespeichert, damit eine teilbeantwortete Onboarding-Runde nach Reload fortgesetzt werden kann
- Externe Übermittlung (Anthropic Claude API): Onboarding-Antworten, die letzten Chat-Nachrichten (Sliding-Window, max. 15) sowie der SSOT-Kontext und die Blueprint-Vorlage werden zur Verarbeitung jeder Chat-Nachricht transient an Anthropic Claude übermittelt (kein Training, keine Persistenz bei Anthropic — Auftragsverarbeiter-Eintrag in PROCESSORS). Die KI entscheidet autonom zwischen Berater-Modus (Rückfrage) und Umsetzer-Modus (Struktur-Mutation); es findet keine automatisierte Entscheidung im Sinne von Art. 22 DSGVO statt
Developer Onboarding — Setup-Pakete (PROJ-1238)
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Verarbeitung zur Erfüllung des Beschäftigungsverhältnisses bzw. der vertraglichen Zusammenarbeit mit dem neuen Entwickler — Setup-Koordination ist integraler Bestandteil des Onboarding-Prozesses). Alternativ Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an einem strukturierten, nachvollziehbaren Entwickler-Onboarding; keine schutzwürdigen Interessen der Betroffenen überwiegen da ausschließlich Beschäftigte / Auftragnehmer betroffen sind)
- developer_setup_packages: workspace_id (Workspace-Zuordnung), developer_name (Klarname des neuen Entwicklers — personenbezogenes Datum), developer_email (E-Mail-Adresse des neuen Entwicklers — personenbezogenes Datum), token (kryptografischer Einmal-Token, URL-safe Base64, 256 Bit Entropie — kein Personenbezug per se, dient ausschließlich zur Authentifizierung des Setup-Vorgangs), token_expires_at (Ablaufzeitpunkt, Standard +7 Tage), status (Paket-Status: ausstehend/in_bearbeitung/abgeschlossen/deaktiviert), config (JSONB — enthält ausschließlich technische Konfiguration: Repo-URLs, Variablennamen ohne Werte, MCP-Server-Bezeichnungen, manuelle Checkliste; keine Credentials oder personenbezogenen Daten), completed_at (Zeitstempel des Setup-Abschlusses, nullable), created_by (FK auth.users ON DELETE SET NULL — UUID des erstellenden Admin-Mitglieds), created_at (Erstellungszeitpunkt). Keine Verarbeitung besonderer Kategorien (Art. 9 DSGVO). Keine automatisierte Einzelentscheidung (Art. 22 DSGVO)
- Öffentlicher Token-Endpunkt: Beim Abruf der Setup-Konfiguration (GET /api/public/developer-setup/[token]) wird der Status des Pakets von 'ausstehend' auf 'in_bearbeitung' gesetzt. Die Response enthält developer_name (für die personalisierte Begrüßung im Skill-Output) sowie die technische Konfiguration. Keine Übermittlung an Dritte. Der Endpunkt ist ohne Login erreichbar (Token-gated), liefert jedoch nur Variablennamen ohne Werte — keine Credentials. Beim Setup-Abschluss (POST /api/public/developer-setup/[token]/complete) wird completed_at gesetzt und status auf 'abgeschlossen' aktualisiert; idempotent bei Mehrfachaufruf
PROJ-1418 PR-Merge-Benachrichtigung + Dev-Inbox (GitHub-CI-Status)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an einem effizienten, nachvollziehbaren Release-Prozess: Benachrichtigung des Plattform-Betreibers sobald der Pflicht-CI-Check eines Pull Requests im internen Code-Repository neulandagentur/neuland-os abgeschlossen ist; seit PROJ-1478 zusaetzlich automatischer Merge ohne manuellen Klick, sobald der Pflicht-Check gruen ist — der manuelle Merge-Button bleibt als Fallback). Betroffen sind ausschliesslich interne Entwicklungs-Metadaten des eigenen Repositories — keine Kunden- oder Endkundendaten.
- github_pr_ci_checks (Plattform-Tabelle, kein workspace_id — ein Eintrag pro offenem Pull Request: repo_full_name (fest neulandagentur/neuland-os), pr_number, pr_title, html_url, head_sha (Commit-Stand des letzten Checks), check_conclusion (success/failure), notified_at, Zeitstempel; seit PROJ-1426 zusaetzlich retry_status (none/pending/conflict/exhausted), retry_attempts, retry_started_at fuer die automatische Merge-Selbstheilung; seit PROJ-1460 zusaetzlich ci_failure_auto_bugfix_attempts (Integer-Zaehler 0-3, wie oft bei einem echten CI-Fehlschlag automatisch eine Bugfix-Session gestartet wurde); seit PROJ-1658 zusaetzlich trigger_status (none/stuck_detected/retriggered/branch_restarted/resolved/failed_permanently), trigger_first_detected_at, trigger_retrigger_at, trigger_branch_restart_at, trigger_notified_at und superseded_by_pr_number fuer die automatische Erkennung + Behebung ausgebliebener CI-Check-Trigger (check_conclusion kann seither auch 'none' sein — noch kein Check-Ergebnis; Schreibzugriff zusaetzlich durch den ci-trigger-check-Cron via Service-Role) — alles reine technische Statuswerte, KEIN Personenbezug): PR-Titel/Nummern/Commit-Hashes des eigenen Code-Repositories — KEIN Personenbezug. RLS: platform_admins-only (alle 4 Operationen), Writes ausschliesslich via Service-Role (Webhook + Merge-Endpunkt + merge-retry-Cron). Seit PROJ-1461 liest GET /api/admin/github-pr-checks weiterhin ausschliesslich per Service-Role (RLS unveraendert); auf Anwendungsebene erhalten zusaetzlich zu Marcel nun auch is_developer=true-Mitglieder Lesezugriff, serverseitig gefiltert auf PR-Zeilen zu PROJ-IDs mit einer eigenen dev_sessions-Zeile (workspace-gescoped, identische Regel wie das bestehende Merge-Recht aus PROJ-1431) — kein Einblick in PR-Zeilen anderer Entwickler, keine neuen personenbezogenen Felder. Eintrag wird geloescht sobald der PR gemergt oder geschlossen wird.
- github_pr_status_webhook_logs (Webhook-Receiver-Log gemaess R-666 — id, received_at, source_ip (IP des aufrufenden GitHub-Servers, indirekter Personenbezug moeglich), github_event/action, github_delivery_id, pr_number, repo_full_name, processing_status (11 Werte: accepted/invalid_signature/.../duplicate), error_message, payload_excerpt JSONB (redaktiert: nur head_sha, conclusion, gekuerzter PR-Titel — keine Secrets, keine Personendaten)): Plattform-Admin-only SELECT. Diagnose-Log fuer abgewiesene/fehlgeschlagene Webhook-Zustellungen, 30 Tage Retention.
- Benachrichtigungen (bestehende notifications-Tabelle, Typen github_pr_ready_to_merge/github_pr_check_failed sowie seit PROJ-1478 github_pr_auto_merged bei automatischem Merge nach gruenem Pflicht-Check): fest an den Plattform-Betreiber adressiert (Nutzer-ID-Zuordnung per E-Mail-Aufloesung, KEINE Rollen-Verteilung), workspace_id = interner NEULAND.-Workspace. Inhalt: PR-Titel, PR-Nummer, Check-Ergebnis — keine Endkundendaten. Zustellung Inbox + APNs-Push (bestehende PROJ-169-Pipeline).
- GitHub-Uebermittlung (Merge-Endpunkt + PR-Titel-Lookup): Serverseitige REST-Calls an api.github.com mit dediziertem Fine-grained-Token (GITHUB_PR_MERGE_TOKEN, nur Pull requests + Contents Read/Write auf neulandagentur/neuland-os). Uebermittelt werden nur PR-Nummer, Commit-SHA und Merge-Parameter — keine Personendaten aus NEULAND. OS. GitHub Inc. ist fuer das Code-Hosting bereits als Verarbeiter im Einsatz (PROJ-510/PROJ-586/PROJ-662).
- PROJ-1431 Merge-Berechtigung fuer Entwickler: is_developer=true-Mitglieder duerfen PRs zu Features mergen, fuer die sie selbst eine Dev-Session gestartet haben (dev_sessions.started_by + proj_id_context, workspace-gescoped). Neuer Benachrichtigungstyp github_pr_merged_by_developer informiert ausschliesslich Marcel (Plattform-Betreiber) ueber Fremd-Merges — notifications.metadata enthaelt merged_by_user_id (FK auth.users) und merged_by_name (profiles.display_name des mergenden Mitarbeiters, bereits an anderer Stelle in NEULAND. OS verarbeitet, hier neu im Kontext der Merge-Historie). Rechtsgrundlage identisch zum bestehenden Eintrag (berechtigtes Interesse an nachvollziehbarem internem Release-Prozess). Empfaenger ausschliesslich Marcel — keine Rollen-Verteilung, kein Zugriff durch andere Workspace-Mitglieder. Aufbewahrung/Loeschung: Standard-Notification-Retention. notifications.user_id (Empfaenger Marcel) ist ON DELETE CASCADE, notifications.created_by (Ersteller/Merger) ist ON DELETE SET NULL — der Name im JSONB-metadata.merged_by_name bleibt bei User-Loeschung des Mergers als Text-Snapshot erhalten (identisches Verhalten zu allen anderen bestehenden Notification-Typen mit Namens-Snapshot in metadata, kein neuer Loeschpfad noetig). Keine neuen Auftragsverarbeiter.
- PROJ-1564 Preview-Freigabe-Gate: github_pr_ci_checks bekommt zwei neue Spalten preview_approved_at (Zeitstempel) und preview_approved_by (FK auth.users, ON DELETE SET NULL) — anders als die uebrigen Spalten dieser Tabelle IST preview_approved_by ein Personenbezug (interner Mitarbeiter-Account, kein Endkunde), identisches Muster wie das bereits dokumentierte merged_by_user_id/merged_by_name aus PROJ-1431. GET /api/admin/github-pr-checks loest den Namen zusaetzlich per Batch-Lookup auf profiles.display_name auf (preview_approved_by_name in der Response, R-671). Zweck: technischer Nachweis, welcher Entwickler die Vercel-Preview eines PRs vor dem Merge geprueft hat (Zwei-Stufen-Freigabe, PROJ-1418-Kontext) — berechtigtes Interesse an nachvollziehbarem Release-Prozess, keine neue Rechtsgrundlage noetig. Setzende Akteure: der Ersteller der zugehoerigen Dev-Session (dev_sessions.started_by) oder Marcel, ueber denselben canActOnPr()-Berechtigungs-Helper wie der Merge-Endpunkt. Beide Felder werden automatisch auf NULL zurueckgesetzt sobald ein neuer Commit auf den PR gepusht wird (Webhook-Upsert bei head_sha-Wechsel) — keine veraltete Freigabe bleibt an einem neuen, ungeprueften Commit-Stand haengen. Aufbewahrung: identisch zur restlichen Zeile (geloescht bei Merge/Close des PRs, siehe deletionConcept), kein eigenstaendiger Loeschpfad noetig. ON DELETE SET NULL verhindert, dass eine spaetere Account-Loeschung des freigebenden Mitarbeiters die PR-Zeile blockiert oder verwaist. Keine neuen Auftragsverarbeiter (gleiche Supabase/GitHub-Verarbeiter wie PROJ-1418).
- PROJ-1645 Fallback-Owner via GitHub-PR-Autor: profiles bekommt eine neue Spalte github_login (text, GitHub-Login des internen Mitarbeiters, z.B. "marcelhoenerbach" — Personenbezug, nur fuer die beiden aktuell aktiven Entwickler befuellt) und github_pr_ci_checks bekommt pr_author_login (text, GitHub-Login des PR-Autors aus pull_request.user.login, identisches Muster wie das bereits dokumentierte preview_approved_by/merged_by_name aus PROJ-1431/PROJ-1564). Zweck: In der 'Offene Pull Requests'-Liste der macOS-App einen Owner anzeigen, auch wenn die primaere dev_session-basierte Auflösung (PROJ-1479) mangels proj_id_context nichts liefert (strukturelle Luecke, PROJ-1613) — GitHub selbst kennt den Autor bereits aus der ohnehin geladenen Pulls-API-Response beim check_suite-Webhook. Rechtsgrundlage identisch zum bestehenden PROJ-1418-Eintrag (berechtigtes Interesse an nachvollziehbarem internem Release-Prozess), keine neue Rechtsgrundlage noetig. GET /api/admin/github-pr-checks nutzt github_login nur als Fallback-Batch-Lookup (kein N+1), NICHT als primaeren Pfad. Ist der GitHub-Login keinem Profil zugeordnet (z.B. ein externer/Bot-Autor), wird der rohe Login-String angezeigt statt einer leeren Spalte. Aufbewahrung: profiles.github_login folgt dem bestehenden profiles-Loeschkonzept (kein eigener Loeschpfad); github_pr_ci_checks.pr_author_login folgt der bestehenden Zeilen-Retention dieser Tabelle (geloescht bei Merge/Close des PRs). Keine neuen Auftragsverarbeiter (gleiche Supabase/GitHub-Verarbeiter wie PROJ-1418).
KI-Interview-Tool: Experten-/Kunden-Interviews inkl. Archivieren + Papierkorb (PROJ-635, PROJ-1428)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an strukturierter Wissenserfassung für die Kunden-SSOT) bzw. Art. 6 Abs. 1 lit. b DSGVO soweit die interviewte Person selbst Vertragspartner/Kontakt ist. Für die interviewte externe Person erfolgt die Teilnahme freiwillig über den zugesandten Link.
- interview_sessions: Name/E-Mail der interviewten Person (expert_name, expert_email, optional), Topic, Interview-Typ, optionale Verknüpfung zu einer SSOT-Entität (Bedarfsgruppe/Persona/Zielgruppe/Marketingziel/CI), Status, KI-Recherche-Kontext (research_context, u.a. SerpAPI-Snippets), KI-Briefing-Dokument (briefing_document), Zeitstempel. Neu durch PROJ-1428: is_archived, archived_at, deleted_at (Lifecycle-Felder ohne eigenen Personenbezug).
- interview_questions / interview_answers: KI-generierte bzw. manuell ergänzte Fragen und die von der interviewten Person eingegebenen Freitext-Antworten (answer_text) — können je nach Thema personenbezogene oder unternehmensbezogene Inhalte enthalten.
- Token-Zugriff: interview_token + token_expires_at (Standard 30 Tage) für den öffentlichen, loginlosen Zugriff der interviewten Person. PROJ-1428: Der Token bleibt beim Archivieren/Löschen unverändert bestehen — der Zugriff wird stattdessen serverseitig anhand von is_archived/deleted_at gesperrt (HTTP 423), sodass ein Dearchivieren den bestehenden Link ohne Neuerstellung reaktiviert.
KI-Briefing-Abgleich gegen SSOT (PROJ-1535)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an redaktioneller Qualitätssicherung und Vermeidung doppelter Inhalte/SEO-Kannibalisierung).
- task_briefing_checks: Verweis auf die geprüfte Aufgabe (task_id, UNIQUE — genau eine Momentaufnahme pro Aufgabe), erkanntes Thema (detected_topic, aus dem Aufgaben-Beschreibungstext abgeleitet), Zielgruppen-Treffer (audience_matches: SSOT-Bedarfsgruppen-IDs + Bezeichnungen), Lücken-Flag (audience_gap), SEO-Überschneidungen (seo_overlaps: Keyword + bestehende Seite), auslösende Person (checked_by, Workspace-Mitglied) und Zeitpunkt (checked_at).
- Transiente LLM-Übermittlung an Anthropic: Aufgaben-Titel + Beschreibungsfeld (max. 6.000 Zeichen) + Bedarfsgruppen-Bezeichnungen des Kunden — Geschäfts-/Redaktionsdaten; personenbezogene Daten nur, soweit Mitarbeitende sie in den Freitext der Aufgabenbeschreibung geschrieben haben. Kein Training, keine Persistenz bei Anthropic.
WaWi Mandanten-Verwaltung — Kunde → Marke (PROJ-1740)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an strukturierter interner Warenwirtschafts-Verwaltung).
- wawi_kunden: workspace_id, name (Firmen-/Kundenname, in aller Regel keine natürliche Person), status (active/inactive), Zeitstempel. Keine Adress-, Kontakt- oder Rechnungsdaten — diese bleiben bewusst in den bestehenden NEULAND-Modulen (CRM), WaWi dupliziert sie nicht.
- wawi_marken: workspace_id (denormalisiert), kunde_id, name, status, Zeitstempel.
- Browser-localStorage (Kontext-Switcher, kein Server-Speicher): Schlüssel wawi_context_<workspace-slug> speichert die zuletzt gewählte Kunde-/Marken-ID rein clientseitig, um den Arbeitskontext über Seitenwechsel hinweg zu behalten. Kein Personenbezug (nur interne UUIDs), nach §25 Abs. 2 Nr. 2 TDDDG technisch unbedingt erforderlich (keine Einwilligung nötig, analog Theme-/Ansichts-Präferenzen anderer Module).
WaWi Artikelstamm & -verwaltung (PROJ-1741)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an strukturierter interner Warenwirtschafts-Verwaltung).
- wawi_artikel: Marke, Artikelnummer (systemvergeben, je Marke fortlaufend), URL-Slug, Name, Kurzbeschreibung, Kategorie, Artikeltyp (physisch/digital), Hersteller-/Verkäufer-Referenz, Soft-Delete- und Zeitstempel. Reine Produkt-/Geschäftsdaten.
- wawi_varianten (+ typspezifische Erweiterungen wawi_varianten_physisch/_digital): Bezeichnung, Varianten-Kennung, Variantennummer (seit PROJ-2273: systemvergebene, unveränderliche laufende Nummer je Marke — reines internes Ordnungsmerkmal ohne Personenbezug), Marken-Zuordnung (marke_id — seit PROJ-2100 zusätzlich an der Variante selbst gespeichert, damit die Kennung je Marke eindeutig sein kann; wird aus dem Artikel abgeleitet und enthält keine neue Datenkategorie), Einkaufs-/Verkaufspreis (Cents), Veröffentlicht-Schalter, Vertriebsstatus; physisch: Bestand, Meldebestand, Lagerort, EAN, Lieferzeit, Gewicht, Versandklasse; digital: Lizenzanzahl, vergebene Lizenzen, Ablaufdatum, Version, Auslieferungsart. Keine personenbezogenen Daten.
- wawi_partner: Hersteller-/Verkäufer-Referenzliste je Workspace — nur der Name. In aller Regel Firmennamen; bei Einzelunternehmern potenziell Personenbezug.
- wawi_medien + wawi_medien_zuordnungen: Datei-Metadaten (Dateiname, MIME-Typ, Größe, Storage-Pfad im privaten Bucket wawi-medien) und Artikel-Zuordnung mit Position/Alt-Text. Produktbilder/Datenblätter — kein intendierter Personenbezug.
- wawi_artikel_uebersetzungen: Sprachfassungen (DE/EN) von Name/Kurzbeschreibung inkl. Herkunft je Textfeld (auto/manuell) und Aktiv-Flag.
- wawi_artikel_changelog: Änderungsprotokoll für Artikelnummer und URL-Slug — Feld, alter/neuer Wert, ändernde Person (User-ID) und Zeitpunkt. Befüllt ausschließlich per Datenbank-Trigger.
- wawi_nummernkreise: reiner Zähler je Marke für die nächste Artikelnummer — kein Personenbezug.
WaWi Eigene Texte und URL-Kürzel je Variante (PROJ-1809)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an strukturierter interner Warenwirtschafts-Verwaltung und an der Auffindbarkeit der eigenen Produktseiten).
- Neue Spalten auf bestehenden Tabellen: wawi_artikel.langtext und wawi_varianten.langtext (formatierter Beschreibungstext, höchstens 20.000 Zeichen je Sprachfassung), wawi_varianten.url_slug (eigene Web-Adresse), wawi_varianten.url_slug_manuell (Merker, ob die Adresse von Hand gesetzt wurde — verhindert späteres automatisches Überschreiben), wawi_varianten.eigene_seite (Schalter). wawi_artikel_uebersetzungen zusätzlich um langtext, url_slug und die Herkunftsangabe zum Langtext erweitert.
- wawi_varianten_uebersetzungen: Sprachfassungen je Variante (Deutsch, Englisch) — Bezeichnung, Kurzbeschreibung, Langtext, Web-Adresse, Herkunft je Textfeld (automatisch oder manuell), Aktiv-Schalter, Zeitstempel. Strukturgleich zur bestehenden Artikel-Übersetzungstabelle.
- wawi_slug_registry: technische Verwaltungstabelle, in der jede vergebene Web-Adresse genau einmal steht (Marke, Sprache, Adresse, Eigentümer). Sie enthält keine eigenen Inhalte, sondern verhindert, dass zwei Produktseiten dieselbe Adresse belegen und eine davon unerreichbar wird. Wird ausschließlich von Datenbank-Triggern gepflegt, nie von Hand.
- Personenbezug: nicht intendiert. Die Texte beschreiben Produkte. Der Langtext ist technisch formatierter Freitext ohne inhaltliche Einschränkung — er wird beim Speichern serverseitig bereinigt, sodass sich kein ausführbarer Inhalt einschleusen lässt. Kein KI-Einsatz, keine Übermittlung an Dritte, keine automatische Texterzeugung.
WaWi Änderungsverlauf je Variante (PROJ-2284)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an einem fachlichen Bearbeitungsnachweis ihrer Warenwirtschaftsdaten). Keine Datenschutz-Folgenabschätzung erforderlich: kein Merkmal aus Art. 35 DSGVO trifft zu (keine systematische Überwachung, keine besonderen Datenkategorien, keine automatisierte Entscheidung über Personen).
- wawi_varianten_changelog: workspace_id, variante_id, ereignis (angelegt/geaendert/geloescht/wiederhergestellt), feld, alter_wert, neuer_wert (als Text; Preise als Cent-Rohwert), herkunft (person/import/system — seit Bugfix 21.08.2026: 'system' für Direktzugriffe ohne Import-Lauf UND ohne angemeldete Person, z. B. Admin-Skript/SQL), geaendert_von (User-ID der ändernden Person; NULL bei Import UND bei System), import_lauf_id (Kennung des Katalog-Import-Laufs; NULL bei manuellen und System-Änderungen), betroffene_felder (Feldnamen-Liste — nur bei verdichteten Import-Einträgen), Zeitpunkt. Befüllt AUSSCHLIESSLICH per Datenbank-Trigger — Clients haben keine Schreibrechte.
- Beim Langtext und bei den Sprachfassungen wird nur die TATSACHE der Änderung festgehalten (Feldname), nie der Textinhalt — alter und neuer Wert bleiben dort leer.
- Lauf-Marker letzter_import_lauf_id (neue Spalte auf wawi_varianten, wawi_varianten_physisch und wawi_varianten_digital): Kennung des letzten schreibenden Import-Laufs — technisches Herkunftssignal für den Trigger, kein Personenbezug.
WaWi Merkmale & Zusatzfelder (PROJ-1789)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an strukturierter interner Warenwirtschafts-Verwaltung).
- wawi_felddefinitionen: workspace_id, kunde_id, marke_id, schluessel (technischer Bezeichner), label (Anzeigename), feldtyp, ebene (artikel/variante), filterbar, sichtbar, gruppierungs_prioritaet (Rang als varianten-bildende Achse), sort_order, optionen (Auswahlliste als JSON-Array), einheit (nur bei Zahlenfeldern), Zeitstempel. Reine Konfigurationsdaten — Feldnamen und Auswahlwerte sind von Agentur-Mitarbeitenden frei vergebener Text.
- wawi_artikel_feldwerte: workspace_id, artikel_id, felddefinition_id sowie die typabhängigen Wertespalten wert_text, wert_zahl, wert_datum, wert_liste (JSON-Array), wert_boolean und Zeitstempel. Je Feldtyp ist genau eine Wertespalte belegt (serverseitig erzwungen).
- wawi_variante_feldwerte: identisch aufgebaut, aber an der Variante statt am Artikel (workspace_id, variante_id, felddefinition_id, dieselben fünf Wertespalten, Zeitstempel).
- Personenbezug: nicht intendiert. Die Werte beschreiben Produkteigenschaften (Material, Farbe, Maße, Lizenzumfang). wert_text und wert_liste sind technisch jedoch unbeschränkter Freitext je Artikel bzw. Variante — ein Personenbezug entstünde nur, wenn Mitarbeitende dort bewusst Namen oder Kontaktdaten eintragen. Vorgesehen ist das nicht, und es gibt keinen Zufluss aus anderen Modulen: Werte entstehen ausschließlich durch manuelle Eingabe in der WaWi-Oberfläche. Keine KI-Verarbeitung, keine Übermittlung an Dritte.
WaWi Katalog-Import aus Google Sheets (PROJ-1742)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an der verlustfreien Übernahme von Kundenkatalogen in die eigene Warenwirtschaft). Für den KI-Zuordnungsvorschlag Auftragsverarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC (siehe PROCESSORS-Eintrag).
- wawi_katalog_quellen: workspace_id, marke_id, Bezeichnung der Quelle (frei vergebener Name, je Marke eindeutig, PROJ-1992), Art der Quelle (Google Sheet oder hochgeladene Datei, PROJ-1935), Verweis auf die Google-Verbindung (user_google_tokens), Adresse des Spreadsheets, aus der Adresse gezogene Google-Dokument-Kennung (PROJ-1992, verhindert die doppelte Verknüpfung desselben Arbeitsblatts), Name des Arbeitsblatts, Name der zuletzt hochgeladenen Datei, aktiv-Kennzeichen, Sperrzustand gegen Doppelstart, Zeitpunkt des letzten Imports, anlegende Person, Zeitstempel.
- Zweiter Einleseweg seit PROJ-1935 (06.08.2026, Direkt-Upload seit 10.08.2026): Ein Katalog kann statt aus einem Google Sheet auch als Datei (CSV oder Excel, bis 25 MB) hochgeladen werden. Es entsteht dadurch KEINE neue Datenkategorie und KEIN weiterer Empfänger — es sind dieselben Katalogdaten, die sonst aus dem Sheet kommen, nur auf anderem Weg hereingegeben. Speicherort während der Verarbeitung: Die Datei geht vom Browser direkt in den privaten Supabase-Storage-Bucket wawi-katalog-dateien (Ablageort serverseitig vergeben, Format workspace_id/quelle_id/…; Zugriff nur über befristete, serverseitig ausgestellte Upload-Zugänge und Service-Role — kein öffentlicher Zugriff). Löschregel: Die Datei wird gelöscht, sobald die Rohkopie vollständig eingelesen ist bzw. der Lauf in einem Endzustand endet — im Regelfall nach Minuten; liegengebliebene Dateien (harter Abbruch, Absturz) räumt ein täglicher Cron (wawi-katalog-dateien-cleanup) nach spätestens 24 Stunden ab. Dauerhaft bleiben nur die Rohkopie der Zeilen (wawi_import_zeilen), der Dateiname und der Ablageort-Text (wawi_import_laeufe.datei_pfad) zur Nachvollziehbarkeit im Verlauf. Beim Datei-Weg entfällt die Übermittlung an Google — die Daten verlassen das System nicht.
- wawi_katalog_mapping_profile: workspace_id, quelle_id (seit PROJ-2279 das Ordnungsmerkmal — ein Profil je Katalog-Quelle), marke_id, die bestätigte Zuordnung Quellspalte → Zielfeld sowie die ausdrücklich ausgeschlossenen Spalten (beide als JSON), anlegende Person, Zeitstempel. Reine Konfiguration. Bei der Umstellung auf ein Profil je Quelle (PROJ-2279) wurden bestehende Profile maschinell auf die Quellen ihrer Marke vervielfältigt — die anlegende Person wurde dabei aus dem Ursprungsprofil übernommen, da die Zuordnung inhaltlich von ihr stammt.
- wawi_import_laeufe: workspace_id, Verweis auf die Quelle, Marke, Auslöser (manuell/geplant), auslösende Person, Status, Fehlermeldung, Fortschritt, Zeilenzahl, die vier Zähler (neu/aktualisiert/abgelehnt/ohne Freigabe), Momentaufnahme der verwendeten Zuordnung, Start- und Endzeitpunkt, bei Datei-Läufen der Ablageort der hochgeladenen Datei (datei_pfad, PROJ-1935 — die Datei selbst wird nach dem Einlesen gelöscht, der Pfad bleibt als Verlaufsangabe).
- wawi_import_zeilen: workspace_id, Verweis auf den Lauf, Zeilennummer im Sheet, **rohdaten** — die vollständige, unveränderte Kopie der Katalogzeile mit allen Original-Spaltenbeschriftungen —, Ergebnis, Ablehnungsgrund, Verweise auf erzeugten Artikel und Variante, Zeitstempel.
- Personenbezug: nicht intendiert, aber in der Rohkopie technisch möglich. rohdaten enthält jede Spalte des Kunden-Sheets unverändert. Produktkataloge tragen üblicherweise Bezeichnungen, Maße, Preise und Bildpfade — sie können jedoch auch Spalten für Ansprechpartner, Lieferanten oder Hersteller-Kontakte enthalten. Die Kopie wird nicht gefiltert, weil ihr Zweck gerade die Verlustfreiheit ist. Keine KI-Verarbeitung der Rohkopie als Ganzes; für den Zuordnungsvorschlag im Prüfschritt (Phase 2d, ai_feature wawi_katalog_mapping) werden ausschließlich die Spaltenüberschriften plus bis zu drei auf 60 Zeichen gekürzte Beispielwerte je Spalte sowie der Zielfeld-Katalog transient an Anthropic PBC übermittelt (Claude Haiku 4.5, Art.-28-Auftragsverarbeitung, Standardvertragsklauseln, kein Training, keine Persistenz bei Anthropic; enthält eine Ansprechpartner-Spalte Beispielwerte, können diese Namen darin vorkommen). Der Vorschlag wird serverseitig gegen den echten Zielfeld-Katalog validiert und nie automatisch übernommen — der Mensch bestätigt jede Zuordnung im Prüfschritt (EU AI Act Art. 50: Kennzeichnung als KI-Vorschlag im UI). Darüber hinaus keine Übermittlung an Dritte — gelesen wird aus dem Google-Konto des Kunden über dessen bestehende Verbindung, geschrieben wird nur in die eigene Datenbank.
Datenquellen-Umformatierung & Verknüpfung (PROJ-1777)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse der Agentur an effizienter, für beliebige Kunden wiederverwendbarer Reporting-Konfiguration). Für den KI-Vorschlags-Pfad Auftragsverarbeitung gemäß Art. 28 DSGVO mit Anthropic PBC (siehe PROCESSORS-Eintrag).
- data_field_transformations: source_kind/source_ref (Diskriminator auf Custom- oder Standard-Datenquelle), input_fields (referenzierte Rohfeld-Namen), formula (Formeltext, eigene sichere Ausdruckssprache — kein beliebiger Code), formula_origin (manual/ai_generated), ai_instruction (bei KI-Herkunft die ursprüngliche Freitext-Anweisung, max. 2000 Zeichen), display_name, status. Reine Konfigurationsdaten ohne Personenbezug — created_by/updated_by sind interne Workspace-Mitarbeiter-Referenzen.
- data_source_joins: chain_name, from/to_source_kind + from/to_source_ref (Quellen-Diskriminatoren), from/to_join_key (Feldnamen als Verknüpfungsschlüssel), join_type (exact/case_insensitive), primary_source_kind/ref, chain_position, status. Reine Konfigurationsdaten ohne Personenbezug.
- data_source_derivation_rules + data_source_derivation_ruleset_fallbacks: Regelwerk zur robusten Ableitung eines Join-Keys bei uneinheitlichen Quelldaten (condition_field/condition_value, condition_operator: equals/contains/regex — wie das Bedingungsfeld gegen den Wert geprüft wird, method: field/substring/allocate/constant, method_detail als JSONB, fallback strategy unassigned/fixed_value/exclude). Reine Konfigurationsdaten ohne Personenbezug.
- KI-Vorschlag Formel/Join/Verkabelung/Regelwerk (ai-suggestions.ts; PROJ-1777 Formel-/Join-Vorschlag AC-5/6/7 UND PROJ-2126 Pro-Quelle-Verkabelung `POST /axes/suggest-wiring` + Regelvorschlag `POST /rules/suggest`): An Anthropic PBC (Claude Haiku, claude-haiku-4-5) übermittelt werden Feldnamen (columnName/kind/dataType, durch die eigene Katalog-Pflege kuratiert), je Feld EIN einzelner Beispielwert (RawField.sampleValue, auf 200 Zeichen gekürzt und durch sanitizePii() redaktiert — kein vollständiger Datensatz, keine Bulk-Rohdaten), die Freitext-Zielbeschreibung sowie der Dimensionsname des Nutzers, jeweils durch sanitizePii() redaktiert und als separater User-Turn (nie im System-Prompt injiziert, R-1446-konform). Antwort wird serverseitig gegen das echte Quellenschema + Vokabular-Whitelist validiert (validateFormula() bzw. Feldnamen-/Enum-Prüfung, stop_reason-Check, parseLlmJsonResponse()) bevor sie angezeigt wird — ungültige Vorschläge werden verworfen, nie automatisch übernommen. Transient, keine Persistenz/kein Training bei Anthropic. EU AI Act Art. 50: Vorschlag wird im UI als KI-generiert gekennzeichnet, bevor der Nutzer ihn einzeln bestätigt.
- Konkrete hawego-Migrationsinstanz (AC-20): eine data_source_joins-Zeile verknüpft Google-Ads-Kampagnenkosten (campaign_cost_line_items.custom_label_0) mit der hawego-eigenen Shopware-Produktgruppen-Custom-Datenquelle (produktgruppe). Reine Kampagnen-/Kostendaten, kein Personenbezug.
- data_source_business_axes + data_source_axis_bindings (PROJ-2126 Unified Dimensions, Achsen-Modell aus PROJ-2123): pro Kunde definierte quellenübergreifende Auswertungs-Dimensionen. axes: axis_key, label (z. B. Produktgruppe), kind, status. bindings je Quelle: source_kind/source_ref/source_table (Diskriminatoren), strategy (direct/reformat/derive), source_field (Feldname als Herkunft), reformat_config (Format-Angleichungs-JSONB), ruleset_key (Verweis auf data_source_derivation_rules), ruleset_workspace_id (Verweis auf den Workspace, in dem das Regelwerk gepflegt wird — PROJ-2205), is_reference. Reine Konfigurationsdaten ohne unmittelbaren Personenbezug — created_by/updated_by sind interne Workspace-Mitarbeiter-Referenzen (ON DELETE SET NULL).
- Scope-Anzeige-Label (PROJ-2205, GET /overview): Zur Beschriftung agenturseitig gepflegter Regelwerke wird der Firmenname des Kunden angezeigt. Dazu liest die Übersicht über die aktive Agentur-Kunden-Verbindung (workspace_connections, gefiltert auf den aufrufenden Agentur-Workspace) den zugeordneten CRM-Kontakt (contacts.name) — ausschließlich der Firmenname zur Anzeige, keine Kontaktperson-Daten, keine neue Speicherung, keine Weitergabe. Der Firmenname stammt aus der bestehenden CRM-Verarbeitung.
Inbox-Ansichtseinstellungen pro Mitarbeiter (PROJ-1636, PROJ-1758, PROJ-1936)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an einem personalisierten, über Geräte hinweg konsistenten Arbeitsplatz).
- Standard-Filteransicht des Postfachs (default_filter: alle oder wichtig)
- Anzeige gelesener Einträge (show_read: Ja/Nein)
- Angeheftete Channels (pinned_channel_ids: Liste der Kennungen eigener, selbst angelegter Postfach-Channels — keine Inhalte)
- Sortiermodus des Priorisierungsbereichs (was_jetzt_sort_mode: nach Priorität oder chronologisch)
- Vorschau-Zeitfenster für Wiedervorlagen (follow_up_preview_window: Keine Vorschau, Alle oder ein festes Zeitfenster von 1 Tag bis 12 Monate — bestimmt nur, wie weit in die Zukunft fällige Wiedervorlagen angezeigt werden; PROJ-1936)
- Verknüpfung mit Nutzer und Workspace sowie Zeitpunkt der letzten Änderung
- Stummschaltung eines eigenen Postfach-Channels (inbox_channels.is_muted, PROJ-2032: Ja/Nein — steuert ausschließlich, ob die Einträge dieses Channels in den Ungelesen-/Dringend-Zählern der Gesamtansicht mitgezählt werden; die Einträge selbst bleiben unverändert sichtbar. Reiner Anzeigewert ohne Personenbezug zu Dritten, unabhängig von der bereits bestehenden Sichtbarkeits-Einstellung is_visible)
Umsatzentwicklung — Monatsabschluss & Dashboard (PROJ-1918)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an interner Unternehmenssteuerung und Nachvollziehbarkeit, wer einen Monatsabschluss vorgenommen hat).
- Monatswerte (revenue_months): Jahr, Monat, Netto-Umsatz in Cent, Status (Entwurf/Abgeschlossen), Zeitpunkt des Abschlusses, abschließende Person (closed_by → auth.users), Zeitpunkt der Benachrichtigung. Historische Werte (2021–Juli 2026) wurden einmalig aus der bisherigen Google-Tabelle übernommen (Backfill), dabei ist closed_by durchgängig leer (kein Rückgriff auf die alte Prozess-Historie möglich/nötig).
- Jährliche Zielwerte (revenue_annual_targets): Jahr, Zielbetrag in Cent.
- Inbox-Benachrichtigung (notifications, Typ revenue_month_closed): enthält ausschließlich Finanzkennzahlen im Text (Nettoumsatz, Vorjahresvergleich, YTD-Werte) — keine personenbezogenen Daten. Metadata-Felder (revenue_month_id, Jahr, Monat, Netto-Umsatz) dienen nur dem internen Deep-Link-Aufbau, sind in der Inbox-Oberfläche nicht als rohe Zeile sichtbar.
Umsatz pro Mitarbeiter — Beschäftigungszeitraum-Historie (PROJ-1934)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an interner Unternehmenssteuerung — betriebswirtschaftliche Produktivitätskennzahl auf Basis historisch korrekter Mitarbeiterzahlen).
- Beschäftigungszeiträume (employee_headcount_periods): Anzeigename des Mitarbeiters (Snapshot zum Anlagezeitpunkt), Startdatum, optionales Enddatum der Anstellung, lose Referenz auf die Workspace-Mitgliedschaft (member_id, ON DELETE SET NULL — die Zeile bleibt beim Löschen des Accounts erhalten, nur die Verknüpfung wird entfernt).
- Abgeleitete Kennzahlen (nicht gespeichert, zur Laufzeit berechnet): tage-gewichtete Ø-Mitarbeiterzahl je Monat und Umsatz pro Mitarbeiter (Nettoumsatz ÷ Ø-Mitarbeiterzahl) — sichtbar für alle aktiven Workspace-Mitglieder auf dem Umsatz-Dashboard. Es werden keine Gehälter oder individuellen Leistungsdaten verarbeitet; die Kennzahl ist ein Unternehmens-Durchschnitt, keine Einzelpersonen-Bewertung.
Organic Social — Content-Ideen & Inspirationsquellen (PROJ-2033)
Rechtsgrundlage: Mitarbeiterjubiläen als Content-Quelle: Art. 6 Abs. 1 lit. a DSGVO (ausdrückliche Einwilligung der/des Beschäftigten, getrennt vom HR-Zweck; Widerruf jederzeit nach Art. 7 Abs. 3 mit sofortiger Löschung offener Ideen). Kundenspezifische Sachstichtage, Watchlist-Signale und materialisierte Ideen: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Content-Planung für die Agentur-Kunden). Personenbezogene Kunden-Stichtage werden ohne Einwilligung nicht verarbeitet (fail-closed, s. Zweck).
- Personen-Opt-in (organic_content_person_optin): Referenz auf ein Workspace-Mitglied (subject_kind='workspace_member', subject_id → auth.users), Zweck ('content_vorschlaege'), Status (granted/revoked), Erteilungs-/Widerrufszeitpunkt, anlegende Person. subject_id wird beim Anlegen serverseitig gegen die aktive Workspace-Mitgliedschaft geprüft (PROJ-2033 S-1/F-4).
- Kundenspezifische Stichtage (organic_content_key_dates): Bezeichnung (Freitext, kann bei is_person_related einen Personennamen enthalten), Datum, Typ, Vorlauf/Serie, Kennzeichen is_person_related, Kontaktbezug. is_person_related-Einträge werden gespeichert, aber nicht zu Ideen verarbeitet (fail-closed).
- Watchlist beobachteter Accounts (organic_watchlist_accounts) und deren öffentlich sichtbare Beiträge (organic_watchlist_posts): Plattform, Handle/Profil-URL, Beobachtungsgrund, Format/Medientyp, Veröffentlichungszeitpunkt. Es werden ausschließlich öffentlich zugängliche Metadaten als Format-Signal ausgewertet; Like-/Kommentarzahlen fließen NICHT in Score oder Learning-Cube ein (AC-F7).
- Materialisierte Ideen (organic_content_ideas): KI-/regelbasiert erzeugter Titel und Beschreibung je Kunde, Quelle, Zieldatum, Relevanz-Score. Ideen aus Quelle H (Mitarbeiterjubiläum) können den Namen der einwilligenden Person im Titel enthalten.
- Ausblend-Signale (organic_idea_hide_signals): pro Kunde/Dimension gezählte Ausblendungen — steuern die künftige Priorisierung, kein direkter Personenbezug.
PROJ-2204 D&P laufende Synchronisation (Folge-Feature zu PROJ-912/PROJ-1441)
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an einheitlicher, aktueller Projekt-/Aufgaben-/Zeiterfassungsführung ohne Medienbruch während der Ablösung von D&P). Die migrierten/synchronisierten Projekt-, Aufgaben- und Zeiterfassungsdaten selbst fallen unter dieselbe Rechtsgrundlage wie die bestehenden Einträge Projektverwaltung/Aufgabenverwaltung (Art. 6 Abs. 1 lit. b, Vertragserfüllung) — es entsteht keine neue Zweckbindung, nur ein zusätzlicher, automatisierter Erfassungsweg für dieselben Datenkategorien.
- Projekt-/Aufgabendaten wie bereits in den bestehenden Einträgen Projektverwaltung/Aufgabenverwaltung dokumentiert — keine neue Datenkategorie, nur ein zusätzlicher automatisierter Erfassungsweg (projects.dnp_project_id, tasks.dnp_task_id als technische Herkunfts-Marker).
- Zeiterfassung (time_entries): D&P liefert nur Datum + Dauer, keine Uhrzeit — importierte Einträge erhalten eine synthetische Startzeit 09:00 Uhr (technische Notlösung, keine neue Personendatenkategorie). Zuordnung zum NEULAND-Nutzer über Namensabgleich (aktive Workspace-Mitglieder); ohne eindeutigen Treffer wird der Eintrag übersprungen (kein Sammel-Konto) — der D&P-Anzeigename der nicht zugeordneten Person landet dabei als Freitext im internen Fehler-Protokoll (dnp_migration_log.message, Platform-Admin-only, analog PROJ-1441-Bewertung).
- Firmenkontakte (contacts): D&P führt Firmen und Einzelpersonen in einer gemeinsamen Liste — der Sync übernimmt ausschließlich Datensätze vom Typ „Company“ (NEULAND contacts ist strukturell eine Firmen-Entität, keine Personen-Stammdaten). Neue Firmen werden angelegt, bereits vorhandene NEULAND-Kontakte werden ausschließlich in leeren Feldern ergänzt (E-Mail, Telefon, Website, Adresse) — bereits gepflegte NEULAND-Werte werden nie überschrieben.
- dnp_config.session_state_encrypted/_iv: AES-256-GCM-verschlüsselte Playwright-Sitzungsdaten (Cookies) des persönlichen D&P-Zugangs des einloggenden Agentur-Mitarbeiters — technisches Betriebsmittel-Credential, kein Endkunden-Personenbezug, RLS ohne Policies (Server-only, nie in API-Responses), analog dem bereits dokumentierten dnp_config.api_key_encrypted aus PROJ-912.
- dnp_migration_runs/dnp_migration_log: Protokoll jedes automatischen Laufs (Zeitpunkt, Zähler, Fehlermeldungen) — wächst seit PROJ-2204 kontinuierlich/stündlich statt einmalig (siehe Feststellung F-2 unten).
7. Einsatz von Künstlicher Intelligenz
NEULAND. OS setzt KI-Funktionen ein, die auf Diensten von Anthropic (Claude) und OpenAI basieren:
• KI-Assistent: Beantwortet Fragen zu Projekten und zur App-Nutzung. Projektkontext-Daten (Aufgaben, Mitarbeiternamen, Kommentare) werden anonymisiert an den KI-Dienst übermittelt.
• SSOT-Analyse: Generiert automatische Vorschläge für Marketing-Strategien. Anonymisierte Projektdaten werden an Claude übermittelt.
• OCR-Dokumentenerkennung: Erkennt automatisch Text, Beträge, Daten und Lieferanteninformationen in hochgeladenen Dokumenten (Rechnungen, Belege, Verträge). Die Dokumenteninhalte werden zur Analyse an Claude (Anthropic) übermittelt. Erkannte Metadaten werden in der Datenbank gespeichert und können manuell bearbeitet werden.
• Benutzerdefinierte KI-Assistenten: Workspace-Admins können spezialisierte KI-Assistenten mit eigenen System-Prompts und Wissensbasen erstellen. Konversationsinhalte werden an Claude (Anthropic) übermittelt. Konversationen und Nachrichten werden pro Nutzer gespeichert und können vom Nutzer jederzeit gelöscht werden.
• Prompt-Builder & Prompt-Optimierer (Admin-Konfigurationswerkzeuge): Workspace-Admins können KI-Assistenten-System-Prompts mithilfe eines KI-gestützten Chats erstellen (Prompt-Builder) oder verbessern (Prompt-Optimierer). Der Chat-Verlauf und der aktuelle System-Prompt werden an Claude Haiku (Anthropic) übermittelt. Es werden ausschließlich Konfigurationsdaten ohne Personenbezug verarbeitet (kein PII, kein Kundenbezug). Sämtliche Konversationsinhalte sind ephemer — sie werden nicht in der Datenbank gespeichert und existieren nur während der aktiven Browser-Session im Arbeitsspeicher. Diese Werkzeuge sind ausschließlich für Workspace-Admins zugänglich. Token-Verbrauch wird anonymisiert protokolliert (Feature: prompt_builder/prompt_optimizer, workspace-bezogen).
• KI-Mitarbeiter: Virtuelle Team-Mitglieder, die Aufgaben autonom bearbeiten können. Bei Zuweisung oder @Mention werden Aufgabeninhalte und anonymisierte Kommentare an Claude (Anthropic) übermittelt. Der KI-Redakteur greift auf SSOT-Kundendaten (anonymisiert) zu. Der KI-Projektassistent liest Projektstruktur, Aufgaben und Sprint-Kapazitäten. Der KI-Vertriebsassistent greift auf CRM-Kontaktdaten (Kontaktname, Unternehmen, Pipeline-Stage, Kommentare und Aktivitätsprotokoll) zu und übermittelt diese zur Analyse an Claude (Anthropic) — dies umfasst Kontaktdaten im Sinne der DSGVO. Der KI-Buchhalter analysiert Buchhaltungsdaten: Eingangsbelege (Lieferantenname, Betrag, Buchungstext, Kontonummer), überfällige Rechnungen (Kundenname, Rechnungsbetrag) und Monatsabschluss-Daten werden an Claude (Anthropic) übermittelt. Lohndaten (Gehälter, Abzüge) werden pseudonymisiert übermittelt — Mitarbeiternamen werden vor der Übermittlung durch Pseudonyme ersetzt. KI-Buchungsvorschläge erfordern manuelle Freigabe. Der KI-Buchhalter kann in den KI-Mitarbeiter-Einstellungen deaktiviert werden. KI-generierte Inhalte werden im System als solche gekennzeichnet (Badge „KI-generiert" bzw. „KI-Entwurf"). Ausführungsprotokolle (Trigger, Status, Dauer, Token-Verbrauch) werden 90 Tage aufbewahrt und danach automatisch gelöscht. KI-Buchungsvorschläge und Prüfberichte werden für die Dauer der Workspace-Mitgliedschaft aufbewahrt und bei Löschung des Workspace vollständig entfernt.
• CMS-Übersetzung: Generiert KI-gestützte Übersetzungsvorschläge für Website-Inhalte. Block-Inhalte (Text, Überschriften, Beschreibungen) werden an Claude (Anthropic) übermittelt. Vorschläge werden als KI-generiert gekennzeichnet und müssen manuell geprüft und gespeichert werden.
• KI-Asset-Generierung: Generiert Marketing-Texte (Headline, Subline, Body, Hashtags) und Hintergrundbilder für Redaktionsplan-Assets. Marketing-Briefing-Daten (Thema, Tonalität, Keywords, Key Message) werden anonymisiert an Claude (Anthropic) übermittelt. Aus dem generierten Text wird ein englischsprachiger Bild-Prompt abgeleitet und an OpenAI DALL-E 3 zur Bildgenerierung gesendet — es werden keine personenbezogenen Daten übermittelt. Generierte Inhalte werden als KI-erzeugt gekennzeichnet.
• Marketing-Strategie-Wizard: Geführter KI-Chat zur Erstellung einer vollständigen Marketing-Strategie in 8 Phasen. Kontaktdaten (Name, Firmenname, Branche) und bestehende Marketing-Daten (Zielgruppen, USPs, Suchworte, Touchpoints) werden anonymisiert an Claude (Anthropic) übermittelt. Chat-Nachrichten werden nicht persistent gespeichert — sie existieren nur während der aktiven Sitzung im Browser. Ergebnisse (Zielgruppen, Strategien, Redaktionsplan-Einträge) werden als reguläre Datensätze gespeichert und können jederzeit bearbeitet oder gelöscht werden.
• KI-Seitenersteller: Generiert automatisch CMS-Landingpages aus einem Keyword oder einer Bedarfsgruppe. SSOT-Daten (Zielgruppen, USPs, Positionierung), Bedarfsgruppen-Informationen und Keyword-Analysen werden anonymisiert (sanitizePii) an Claude (Anthropic) übermittelt. Generierte Seiten starten als Entwurf und müssen manuell geprüft und veröffentlicht werden. Token-Verbrauch wird in der Kostenübersicht erfasst. Maximal 5 Generierungen pro Workspace und Tag. KI-generierte Seiten werden im CMS-Editor als maschinell erzeugt gekennzeichnet (EU AI Act Transparenzpflicht).
• KI-Workflow-Pipelines: Mehrstufige KI-Workflows zur automatisierten Content-Erstellung (z.B. Landing-Page-Texte, SEO-Optimierung, Lektorat). Nutzereingaben (Briefing), SSOT-Kundendaten (Zielgruppen, USPs, Positionierung) und Bedarfsgruppen-Informationen werden anonymisiert (sanitizePii) an Claude (Anthropic) übermittelt. Zwischenergebnisse und finale Outputs werden pro Nutzer in der Datenbank gespeichert und können jederzeit vom Nutzer gelöscht werden. Ergebnisse können als CMS-Entwurf oder Aufgabe weiterverwendet werden — diese starten jeweils als Entwurf und erfordern manuelle Freigabe. KI-generierte Inhalte sind als maschinell erzeugt gekennzeichnet (EU AI Act). Token-Verbrauch wird in der Kostenübersicht erfasst. Maximal 20 Workflow-Ausführungen pro Nutzer und Tag.
• Spracheingabe (Voice-to-Text): Unterschiedliche Transkriptions-Pfade je nach Endgerät:
— Web-App & iOS: Audio wird über das Mikrofon aufgenommen, an den NEULAND.-Server gesendet und von dort an OpenAI Whisper-1 weitergeleitet. Die Audiodaten werden auf dem NEULAND.-Server ausschließlich im Arbeitsspeicher verarbeitet — es erfolgt keine dauerhafte Speicherung.
— macOS Companion App (seit PROJ-1878): Die Transkription erfolgt im Regelfall über die Cloud — gleicher Pfad wie Web-App & iOS (Audio an den NEULAND.-Server, von dort an OpenAI Whisper-1; nur Arbeitsspeicher-Verarbeitung, keine dauerhafte Speicherung). Zusätzlich werden die selbst gepflegten Einträge des persönlichen Wörterbuchs der App (Eigennamen/Fachbegriffe) als Erkennungs-Kontext mitübertragen, damit Eigennamen korrekt erkannt werden; sie werden serverseitig nicht gespeichert. Bei fehlender Internetverbindung oder Cloud-Fehler fällt die App automatisch auf die lokale Transkription via WhisperKit zurück (quelloffene Apple-ML-Runtime mit OpenAI-Whisper-Modell, ~800 MB, GPU-beschleunigt) — in diesem Fall verlassen die Audiodaten das Gerät NICHT.
Die Nutzung erfordert eine explizite Einwilligung (Opt-in) vor der ersten Verwendung. Im Kunden-Portal muss die Spracheingabe zusätzlich vom Agentur-Administrator aktiviert werden. Kosten (bei Cloud-Transkription) werden über das bestehende KI-Token-Tracking erfasst; bei lokaler Transkription entstehen keine externen Kosten, der Vorgang wird aber dennoch protokolliert.
• KI-gestützte E-Mail-Kategorisierung: Analysiert E-Mail-Betreff und Textvorschau automatisch bei der Gmail-Synchronisation. Daten werden anonymisiert (sanitizePii) an Claude Haiku (Anthropic) übermittelt. Ergebnis: Kategorie (z.B. Kunde, Team, Werbung — konfigurierbar pro Workspace), Priorität, Handlungsempfehlung und kurze Zusammenfassung (1–2 Sätze). Gespeichert im E-Mail-Cache, gekennzeichnet als KI-generiert (EU AI Act). Maximal 20 E-Mails pro Synchronisation. E-Mail-Body und Anhänge werden nicht an die KI übermittelt. Nutzer können die KI-Kategorisierung im Profil pro Google-Konto separat deaktivieren (datenschutzförderndes Opt-out). Optional kann ein eigener KI-Assistent (System-Prompt + Wissensbasis, Workspace-kontrollierter Inhalt ohne personenbezogene Daten) als zusätzlicher Kontext für die Kategorisierung zugeordnet werden — dies beeinflusst ausschließlich die Qualität der Klassifikation, nicht den Umfang der übermittelten personenbezogenen Daten.
• Kontextbezogener KI-Chat: Im Hilfe-Icon jeder Seite können Nutzer direkt Fragen stellen. Die Frage wird zusammen mit den zugehörigen Hilfe-Artikeln als Kontext an Claude (Anthropic) übermittelt. Chat-Nachrichten werden nicht in der Datenbank gespeichert (ephemer). Doku-Verbesserungsvorschläge werden persistent gespeichert (Nutzer-ID, Fragetext, Vorschlagstext).
• Persönlicher Voice-Assistent (Diktat-Optimierung) & Voice-Szenarien: Jeder Nutzer erhält automatisch einen persönlichen KI-Assistenten, der diktierte Texte im eigenen Schreibstil optimiert. Zusätzlich können Agentur-Mitarbeiter bis zu 5 persönliche Voice-Szenarien mit je eigener KI-Assistenten-Zuordnung, konfigurierbarem globalem macOS-Shortcut (Standard Fn+1 bis Fn+5, kann vom Nutzer auf beliebige Tastenkombination umgestellt werden) und Post-Aktion (Direkt einfügen mit/ohne Zwischenablage, Zwischenablage, Dialog, Workspace-Aufgabe, Workspace-Notiz) anlegen. Die Audio-Aufnahme wird — wie im Web-Pfad — im Regelfall per OpenAI Whisper-1 in der Cloud transkribiert (seit PROJ-1878; zuvor primär lokal); bei fehlender Internetverbindung oder Cloud-Fehler transkribiert die macOS-App lokal via WhisperKit (dann keine Audio-Übertragung an externe Dienste). Das entstehende Whisper-Transkript (Text) wird direkt (ohne Anonymisierung — eigene Diktate des Nutzers) an Claude (Anthropic) zur Stiloptimierung übermittelt. Der vom Nutzer frei vergebene Szenario-Name wird zusätzlich als Metadatum im internen Token-Tracking protokolliert und kann theoretisch personenbezogene Inhalte enthalten, falls der Nutzer etwa einen Kontaktnamen im Szenario-Namen verwendet — Nutzer wird daher empfohlen, keine Kundennamen als Szenario-Namen zu wählen. Der persönliche System-Prompt enthält den Vornamen des Nutzers zur Personalisierung. Nutzer können System-Prompt, Name und Beschreibung ihres persönlichen Assistenten sowie alle Szenarien jederzeit anpassen oder löschen (Profil-Sektion „Voice-Szenarien"). Bei Account-Löschung werden persönlicher Assistent und alle Voice-Szenarien automatisch gelöscht (DB-CASCADE). Persönliche Assistenten und Voice-Szenarien sind im DSGVO-Datenexport enthalten (Name, Beschreibung, System-Prompt, Shortcut-Index, Post-Aktion, zugeordnete Assistenten-ID). Maximal 200 Optimierungen pro Nutzer und Tag (geteilt über persönlichen Assistenten und alle Szenarien). Token-Verbrauch wird in der Kostenübersicht erfasst (Feature-Key "voice_scenario" für Szenario-basierte Optimierungen, "voice_dictation_optimization" für direkten persönlichen Assistenten).
• Voice-Agent (mobile Intent-Klassifizierung): In der NEULAND. OS Companion App können Nutzer per Spracheingabe Aufgabenwünsche, Kommentare oder Statusabfragen an die Plattform senden. Das Sprach-Transkript wird vor Übermittlung anonymisiert (sanitizePii) und an Claude Haiku (Anthropic) zur Intent-Erkennung gesendet (4 Kategorien: Aufgabenwunsch, Kommentar, Statusabfrage, unklar). Das Transkript wird ausschließlich im Arbeitsspeicher verarbeitet — es erfolgt keine dauerhafte Speicherung. Die Nutzung setzt die bestehende Voice-Opt-in-Einwilligung voraus. KI-klassifizierte Ergebnisse werden in der App als KI-verarbeitet gekennzeichnet (EU AI Act). Maximal 10 Klassifizierungen pro Workspace und Minute. Token-Verbrauch wird in der Kostenübersicht erfasst.
• Agency Brain Kampagnen-Analyse: Täglich werden vollständig anonymisierte, aggregierte Kampagnenmetriken (Branche, Kampagnentyp, KPIs wie CPL oder Session-Zahlen) von opt-in Workspaces an Claude Haiku (Anthropic) zur plattformweiten Insights-Generierung übermittelt. Es werden ausschließlich anonymisierte Zahlenreihen ohne Workspace-IDs, Unternehmensnamen oder personenbezogene Daten übermittelt. Generierte Insights werden als KI-generiert gekennzeichnet (Sparkles-Icon + Label „KI-generiert", EU AI Act Art. 50). Risikoklasse: Minimal (keine automatisierten Entscheidungen über Personen). Teilnahme erfordert explizites Opt-in durch Agentur-Admin.
• Automatische Bug-Triage: Bei technischen Fehlern wird die Fehlermeldung und der Stack Trace (ohne personenbezogene Daten) an Claude Haiku (Anthropic) zur Severity-Einschätzung und Fix-Vorschlag übermittelt. Die Analyse ist rein technisch — es werden keine Nutzernamen, E-Mails oder andere personenbezogene Daten an die KI gesendet. Ergebnisse werden als KI-generiert gekennzeichnet.
• Hilfe-Center-Suche: Nutzt OpenAI Embeddings zur semantischen Suche in Hilfe-Artikeln. Es werden keine personenbezogenen Daten an OpenAI übermittelt.
• Meeting-Transkription & KI-Zusammenfassung: Meeting-Aufzeichnungen werden nach dem Meeting automatisch transkribiert (Deepgram Nova-3 mit Sprecher-Erkennung) und zusammengefasst (Claude Haiku). Die Transkription identifiziert automatisch verschiedene Sprecher und ordnet ihnen anhand der Beitrittsreihenfolge der Meeting-Teilnehmer echte Namen zu. Das Transkript wird vor Übermittlung an Anthropic anonymisiert (sanitizePii). Die Zusammenfassung wird als KI-generiert gekennzeichnet (EU AI Act) und ordnet Action Items den jeweiligen Sprechern zu. Deepgram verarbeitet Audio-Daten nur transient (API-Aufruf, keine dauerhafte Speicherung). Aufbewahrung: Transkript und Transkript-Segmente werden nach konfigurierter Aufbewahrungsfrist gelöscht (Standard 30 Tage), Zusammenfassung bleibt bestehen.
Datenschutzstufen der KI-Mitarbeiter:
| KI-Mitarbeiter | Anonymisierungsstufe | Übermittelte Datenkategorien |
|---|---|---|
| KI-Redakteur | Anonymisiert | SSOT-Kundendaten (Personas, Markenziele) — keine Klarnamen |
| KI-Projektassistent | Teilanonymisiert | Aufgaben, Sprint-Daten — Mitarbeiternamen als Anzeigenamen |
| KI-Vertriebsassistent | Klartext (CRM-Daten) | Kontaktname, Firma, E-Mail, Pipeline-Stage, Kommentare |
| KI-Buchhalter | Pseudonymisiert (Lohndaten), Klartext (Belege) | Lieferantennamen, Beträge, Kontonummern; Lohndaten mit Pseudonymen |
| KI-Kreativmitarbeiter | Anonymisiert | SSOT-Markendaten, Kampagnen-Briefings — keine personenbezogenen Daten |
Die Verarbeitung erfolgt auf Grundlage von Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an Automatisierung). Für den KI-Vertriebsassistenten, der CRM-Kontaktdaten Dritter an Claude übermittelt, stützt sich die Verarbeitung auf Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an effizienter Vertriebssteuerung). Betroffene Dritte (Kontakte) werden nicht direkt über die KI-Verarbeitung informiert; die Daten werden ausschließlich zur internen Vertriebsoptimierung genutzt und nicht an weitere Dritte weitergegeben. Jeder KI-Mitarbeiter kann einzeln durch den Workspace-Administrator deaktiviert werden. Es findet keine automatisierte Entscheidungsfindung im Sinne von Art. 22 DSGVO statt — alle KI-Ergebnisse sind Vorschläge, die manuell geprüft werden. KI-generierte Inhalte sind stets als maschinell erzeugt erkennbar (EU AI Act Transparenzpflicht).
Widerspruchsrecht (Art. 21 DSGVO): Soweit die KI-Verarbeitung auf berechtigtem Interesse (Art. 6 Abs. 1 lit. f DSGVO) basiert, steht Ihnen ein Widerspruchsrecht zu. Sie können einzelne KI-Mitarbeiter über die Workspace-Einstellungen deaktivieren. Für einen vollständigen Widerspruch gegen KI-Funktionen wenden Sie sich bitte an den Verantwortlichen. Eine zentrale Opt-out-Möglichkeit wird in einer zukünftigen Version bereitgestellt.
8. Office Management — Reinigungskraft-Portal (PROJ-1225)
Das Office-Management-Modul ermöglicht die Verwaltung von Reinigungspersonal und betrieblichen Aufgaben ohne NeulandOS-Login.
Verarbeitete Daten:
• Arbeitsstunden (office_stunden): Datum, Stundenanzahl und optionale Notiz der Reinigungskraft. Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung / Arbeitsverhältnis). Aufbewahrung: 6 Jahre gemäß § 147 AO; keine Änderung oder Löschung nach dem Speichern möglich (GoBD-konforme Unveränderlichkeit).
• Einkaufszettel (office_einkaufszettel): Bezeichnung, Menge und Erledigungsstatus von Bedarfsartikeln. Keine personenbezogenen Daten im Pflichtfeld; das Feld „added_by" enthält „portal" (automatisch) oder einen frei gewählten Namen. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an betrieblicher Organisation). Aufbewahrung: bis zur manuellen Löschung oder Workspace-Löschung (CASCADE).
• Aufgaben-Fahrplan (office_fahrplan): Bezeichnung, Wiederholungsintervall und Fälligkeitsdaten für Reinigungsaufgaben. Keine personenbezogenen Pflichtfelder. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO. Aufbewahrung: bis zur manuellen Löschung oder Workspace-Löschung.
• NFC-Links (office_nfc_links): Bezeichnung und Aktionstyp; Zähler ausgelöster Scans und gehashter IP-Fingerprint des letzten Scans (SHA-256, keine Rückführbarkeit auf einzelne Person). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO. Aufbewahrung: bis zur manuellen Löschung.
• PIN-Versuche (office_pin_attempts): Fehlversuch-Zähler pro Workspace und gehashte IP-Adresse (SHA-256). Kein Klarnamen- oder Personenbezug. Automatische Löschung nach 24 Stunden.
• Portal-Einstellungen (office_settings): Gehashter PIN-Wert (pbkdf2-SHA256, 100.000 Iterationen), optionaler Anzeigename des Portals sowie die konfigurierte WhatsApp-Empfängernummer (E.164-Format, z. B. +49151…). Die Nummer wird ausschließlich zum Versand betrieblicher NFC-Scan-Benachrichtigungen verwendet.
• WhatsApp-Benachrichtigungen (PROJ-1240): Beim Scan eines NFC-Links wird — sofern konfiguriert — eine WhatsApp-Nachricht über den Dienst Twilio Inc. (375 Beale Street, Suite 300, San Francisco, CA 94105, USA; https://www.twilio.com) an die hinterlegte Nummer gesendet. Die Nachricht enthält den Titel der ausgelösten Aktion (z. B. Einkaufsartikel) und einen Portal-Link. Twilio ist als Auftragsverarbeiter gemäß Art. 28 DSGVO vertraglich gebunden (Twilio Data Processing Agreement). Die Übermittlung in die USA erfolgt auf Basis von Standardvertragsklauseln (Art. 46 Abs. 2 lit. c DSGVO). Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an betrieblicher Kommunikation). Die WhatsApp-Empfängernummer wird nicht an Dritte weitergegeben und kann jederzeit in den Office-Einstellungen entfernt werden.
Betroffene Personen: Reinigungspersonal und andere externe Dienstleister des Workspaces, die das PIN-Portal nutzen.
Löschung: Alle office_*-Daten werden bei Löschung des Workspaces vollständig entfernt (CASCADE). Einzelne Einkaufszettel- und Fahrplan-Einträge können vom Admin manuell gelöscht werden. Arbeitsstunden-Einträge sind nach dem Speichern nicht löschbar (GoBD-Compliance).
Auskunft und Rechte: Für Auskunft über gespeicherte Arbeitsstunden können sich betroffene Personen an den Workspace-Verantwortlichen wenden.
9. Ihre Rechte als betroffene Person
Sie haben gegenüber dem Verantwortlichen folgende Rechte hinsichtlich Ihrer personenbezogenen Daten:
• Recht auf Auskunft (Art. 15 DSGVO): Sie können Auskunft über Ihre verarbeiteten personenbezogenen Daten verlangen.
• Recht auf Berichtigung (Art. 16 DSGVO): Sie können die Berichtigung unrichtiger Daten verlangen.
• Recht auf Löschung (Art. 17 DSGVO): Sie können die Löschung Ihrer Daten verlangen, sofern keine gesetzliche Aufbewahrungspflicht besteht.
• Recht auf Einschränkung der Verarbeitung (Art. 18 DSGVO): Sie können die Einschränkung der Verarbeitung unter bestimmten Voraussetzungen verlangen.
• Recht auf Datenübertragbarkeit (Art. 20 DSGVO): Sie können verlangen, dass Ihre Daten in einem gängigen Format an Sie oder einen anderen Verantwortlichen übermittelt werden.
• Widerspruchsrecht (Art. 21 DSGVO): Sie können der Verarbeitung Ihrer Daten widersprechen, soweit diese auf berechtigtem Interesse basiert.
• Recht auf Widerruf der Einwilligung (Art. 7 Abs. 3 DSGVO): Sie können eine erteilte Einwilligung jederzeit mit Wirkung für die Zukunft widerrufen.
10. Datensicherheit
Wir setzen umfangreiche technische und organisatorische Maßnahmen ein, um Ihre Daten zu schützen:
• Transportverschlüsselung: Alle Datenübertragungen erfolgen über TLS/SSL (HTTPS).
• Datenbankschutz: Row Level Security (RLS) stellt sicher, dass Nutzer nur auf ihre eigenen Daten zugreifen können.
• Verschlüsselung: Sensible Daten (OAuth-Token, API-Keys) werden mit AES-256-GCM verschlüsselt gespeichert.
• Passwörter: Werden ausschließlich als kryptographisch gehashte Werte gespeichert (bcrypt).
• HMAC-Signierung: Der Workspace-Memberships-Cache wird mit HMAC signiert, um Manipulation zu verhindern.
• Rate-Limiting: Schutz gegen Brute-Force-Angriffe auf allen API-Endpunkten.
• CSRF-Schutz: Origin-Validierung auf allen schreibenden API-Endpunkten.
• Security Headers: X-Frame-Options, Content-Security-Policy, Strict-Transport-Security.
11. Drittlandtransfer
Einige unserer Auftragsverarbeiter verarbeiten Daten in den USA. Die Datenübermittlung erfolgt auf Grundlage von:
• EU-US Data Privacy Framework: Für Anbieter, die unter dem DPF zertifiziert sind.
• Standardvertragsklauseln (SCCs): Gemäß Art. 46 Abs. 2 lit. c DSGVO für Anbieter ohne DPF-Zertifizierung.
• Data Processing Agreements (DPA): Mit allen Auftragsverarbeitern bestehen gesonderte Auftragsverarbeitungsverträge.
Details zu den einzelnen Auftragsverarbeitern und ihren Standorten finden Sie in der Auftragsverarbeiter-Tabelle oben.
12. Beschwerderecht bei der Aufsichtsbehörde
Unbeschadet eines anderweitigen verwaltungsrechtlichen oder gerichtlichen Rechtsbehelfs steht Ihnen das Recht auf Beschwerde bei einer Aufsichtsbehörde zu, wenn Sie der Ansicht sind, dass die Verarbeitung der Sie betreffenden personenbezogenen Daten gegen die DSGVO verstößt.
Die für uns zuständige Aufsichtsbehörde ist:
Der Landesbeauftragte für den Datenschutz und die Informationsfreiheit des jeweiligen Bundeslandes.
13. Kontakt für Datenschutzanfragen
Zur Ausübung Ihrer Rechte oder bei Fragen zum Datenschutz wenden Sie sich bitte an:
NEULAND. GmbH
E-Mail: datenschutz@neuland-agentur.com