Files
kbcrm/ai-context/konzept-für-telefon-akquise-workflow.md
gg 5a39c64880 docs(ai-context): Konzept für Telefon-Akquise-Workflow hinzugefügt
Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-09-20 20:21:40 +02:00

415 lines
17 KiB
Markdown

# 📌 CRM-Konzept für den Telefon-Akquise-Workflow
---
## **📂 1. Datenmodell (Anpassungen)**
---
### **1.1. Bestehende Tabellen (ohne Änderungen)**
- **`User`** (Mitarbeiter)
- **`Customer`** (Kunde)
- **`Project`** (Projekt)
- **`Contact`** (Kontakt)
- **`ProjektUser`** (Zuordnung User → Projekt)
- **`CallLogsTag`** (Zuordnung CallLog → Tag)
---
### **1.2. Anpassungen an bestehenden Tabellen**
#### **`Tag` (Erweiterung für Wiedervorlage-Logik)**
| **Feld** | **Typ** | **Beschreibung** | **Standardwert** |
| -------------------------------- | ------------ | ---------------------------------------------------------------------------------- | ---------------- |
| `id` | Integer | Primärschlüssel | - |
| `name` | String(200) | Name des Tags | - |
| `description` | String(2000) | Beschreibung (optional) | `NULL` |
| `color` | String(20) | Farbe für UI (optional) | `NULL` |
| `parent_id` | Integer | Selbstreferenz für hierarchische Tags | `NULL` |
| `is_parent` | Boolean | `True` = Gruppierungsknoten | `False` |
| **`is_erledigend`** | **Boolean** | **`True` = Kontakt wird als *erledigt* markiert, wenn dieser Tag zugewiesen wird** | **`False`** |
| **`loest_wiedervorlage_aus`** | **Boolean** | **`True` = Tag löst eine Wiedervorlage aus** | **`False`** |
| **`wiedervorlage_abstand_tage`** | **Integer** | **Anzahl Tage bis zur Wiedervorlage (falls `loest_wiedervorlage_aus = True`)** | **`NULL`** |
---
#### **`CallLog` (Anpassung für Wiedervorlage-Datum)**
| **Feld** | **Typ** | **Beschreibung** | **Standardwert** |
| ------------------------- | -------- | -------------------------------------------------------------------------- | ------------------- |
| `id` | Integer | Primärschlüssel | - |
| `contact_id` | Integer | Fremdschlüssel → `Contact` | - |
| `user_id` | Integer | Fremdschlüssel → `User` | - |
| `note_text` | Text | Text der Gesprächsnotiz | - |
| `created_at` | DateTime | Erstellungsdatum | `CURRENT_TIMESTAMP` |
| **`wiedervorlage_datum`** | **Date** | **Wiedervorlage-Datum (automatisch berechnet oder manuell überschrieben)** | **`NULL`** |
---
#### **`Contact` (Anpassung für optimistisches Locking)**
| **Feld** | **Typ** | **Beschreibung** | **Standardwert** |
| ------------- | ----------- | --------------------------------------------- | ---------------- |
| `id` | Integer | Primärschlüssel | - |
| `project_id` | Integer | Fremdschlüssel → `Project` | - |
| `first_name` | String(100) | Vorname des Kontakts | - |
| `last_name` | String(100) | Nachname des Kontakts | - |
| `phone` | String(20) | Telefonnummer | - |
| `email` | String(100) | E-Mail (optional) | `NULL` |
| **`version`** | **Integer** | **Versionsnummer für optimistisches Locking** | **`0`** |
---
#### **`Project` (kein Status-Feld)**
| **Feld** | **Typ** | **Beschreibung** | **Standardwert** |
| ------------- | ----------- | --------------------------- | ------------------- |
| `id` | Integer | Primärschlüssel | - |
| `customer_id` | Integer | Fremdschlüssel → `Customer` | - |
| `name` | String(200) | Name des Projekts | - |
| `created_at` | DateTime | Erstellungsdatum | `CURRENT_TIMESTAMP` |
---
### **1.3. Neue Methoden (Statusberechnung)**
#### **Methode für `Contact`: `is_erledigt()`**
- **Zweck**: Dynamisch prüfen, ob ein Kontakt als *erledigt* gilt.
- **Logik**:
- Falls der Kontakt **keine Gesprächsnotizen** hat → `False` (nicht erledigt).
- Falls **alle Gesprächsnotizen** des Kontakts **mindestens einen Tag mit `is_erledigend = True`** haben → `True` (erledigt).
- Sonst → `False` (nicht erledigt).
**Pseudocode:**
```python
# Methode in der Contact-Klasse
def is_erledigt(self):
if not self.call_logs:
return False
for notiz in self.call_logs:
for tag in notiz.tags:
if not tag.is_erledigend:
return False
return True
```
---
#### **Methode für `Project`: `is_erledigt()`**
- **Zweck**: Dynamisch prüfen, ob ein Projekt als *erledigt* gilt.
- **Logik**:
- Falls das Projekt **keine Kontakte** hat → `True` (erledigt).
- Falls **alle Kontakte** des Projekts `is_erledigt() = True` sind → `True` (erledigt).
- Sonst → `False` (nicht erledigt).
**Pseudocode:**
```python
# Methode in der Project-Klasse
def is_erledigt(self):
if not self.contacts:
return True
for kontakt in self.contacts:
if not kontakt.is_erledigt():
return False
return True
```
---
### **1.4. Neue Tabellen (für spätere Protokollierung)**
#### **`KontaktLog` (optional)**
| **Feld** | **Typ** | **Beschreibung** |
| ------------ | ---------- | ---------------------------------------------------------- |
| `id` | Integer | Primärschlüssel |
| `kontakt_id` | Integer | Fremdschlüssel → `Contact` |
| `user_id` | Integer | Fremdschlüssel → `User` |
| `timestamp` | DateTime | Zeitstempel der Änderung |
| `aktion` | String(50) | Art der Änderung (z. B. *"Notiz hinzugefügt"*) |
| `alte_werte` | JSON | Alte Werte (z. B. `{"wiedervorlage_datum": "2026-09-20"}`) |
| `neue_werte` | JSON | Neue Werte (z. B. `{"wiedervorlage_datum": "2026-09-25"}`) |
---
---
---
## **🖥️ 2. Benutzeroberfläche (Masken &amp; Workflows)**
---
### **2.1. Hauptmenü**
- **Menüpunkte**:
- **Tages-Workflow**
- **Projekte**
- **Kontakte**
- **Statistiken**
---
### **2.2. Tages-Workflow: Gefilterte Liste**
#### **Anzeige**
- **Tabellenansicht** mit Spalten:
| **Spalte** | **Beschreibung** | **Beispiel** |
| ------------- | ----------------------------------------- | ------------------------- |
| Kunde | Name des Kunden | "Muster GmbH" |
| Projekt | Name des Projekts | "Neukundengewinnung 2026" |
| Kontakt | Name des Ansprechpartners | "Max Mustermann" |
| Telefon | Telefonnummer | "+49 123 45678" |
| Letzte Notiz | Kurztext der letzten Gesprächsnotiz | "Nicht erreicht" |
| Wiedervorlage | Nächstes Wiedervorlage-Datum | "20.09.2026" |
| **Status** | **Dynamisch berechnet (`is_erledigt()`)** | "Offen" / "Erledigt" |
- **Sortierung**:
1. Überfällige Wiedervorlagen
2. Kontakte ohne Gesprächsnotizen
3. Kontakte mit Wiedervorlage in der aktuellen Woche
---
#### **Filterleiste**
| **Filter** | **Typ** | **Mögliche Werte** |
| ------------------- | ---------------- | ----------------------------------------------------------------------- |
| Kunde | Dropdown | Alle Kunden, die der Mitarbeiter bearbeiten darf |
| Projektstatus | Dropdown | *Offen*, *In Bearbeitung* (dynamisch berechnet) |
| **Tag-Kategorie** | **Dropdown** | **`Erledigend`**, **`Nicht-erledigend`**, **`Wiedervorlage-Tags`** |
| **Einzelne Tags** | **Multi-Select** | **Alle verfügbaren Tags** (z. B. *"Nicht erreicht"*, *"Wiedervorlage"*) |
| Wiedervorlage-Datum | Dropdown | *Heute*, *Nächste 3 Tage*, *Überfällig*, *Aktuelle Woche* |
- **Aktionsbuttons**:
- **"Filter anwenden"** (Aktualisiert die Liste)
- **"Zurücksetzen"** (Setzt alle Filter zurück)
- **"Workflow beginnen"** (Startet die Bearbeitung mit dem ersten Eintrag)
---
### **2.3. Bearbeitungsmaske**
#### **Kopfzeile: Projekt- und Kontaktinformationen**
- **Kundeninfo**: Name des Kunden und Projektname.
- **Kontaktinfo**: Name, Telefonnummer, E-Mail.
- **Button**: *"Kontakt bearbeiten"*
**Beispiel:**
```
Kunde: Muster GmbH
Projekt: Neukundengewinnung 2026
Kontakt: Max Mustermann | +49 123 45678 | max@muster.de
```
---
#### **Tabelle der bisherigen Gesprächsnotizen**
| **Spalte** | **Beschreibung** | **Beispiel** |
| ------------- | ---------------------------- | ------------------------------- |
| Datum | Erstellungsdatum und Uhrzeit | "19.09.2026, 14:30" |
| Mitarbeiter | Name des Mitarbeiters | "Gerd Goldberg" |
| Notiz | Text der Gesprächsnotiz | "Nicht erreicht" |
| Tags | Zugewiesene Tags | "Nicht erreicht, Wiedervorlage" |
| Wiedervorlage | Wiedervorlage-Datum | "20.09.2026" |
- **Sortierung**: Neueste Notiz zuerst.
- **Funktionen**:
- Klick auf Notiz → Details anzeigen.
- **Button**: *"Notiz bearbeiten"*
---
#### **Formular für neue Gesprächsnotiz**
- **Felder**:
- **Notiztext** (Textarea, Pflichtfeld)
- **Tags** (Multi-Select-Dropdown mit allen verfügbaren Tags)
- **Wiedervorlage-Datum** (Datumspicker, **automatisch berechnet oder manuell überschreibbar**)
- **Buttons**:
- **"Speichern und weiter"** (Speichert und lädt den nächsten Kontakt)
- **"Speichern"** (Speichert und bleibt auf dem aktuellen Kontakt)
- **"Abbrechen"** (Verwirft Änderungen, Rückkehr zur Liste)
---
#### **Navigation**
- **Button: "Zurück zur Liste"**:
- Kehrt zur **gefilterten Liste** zurück.
- Die Liste berücksichtigt bereits alle Änderungen (z. B. neue Notizen, Statusänderungen).
- **Button: "Nächster Kontakt"**:
- Lädt manuell den nächsten Kontakt aus der Liste.
---
### **2.4. Konfliktmeldung (bei optimistischem Locking)**
- **Anzeige**:
```
Dieser Kontakt wurde von [Mitarbeiter] bearbeitet und als erledigt markiert.
Möchten Sie die aktuelle Version neu laden?
```
- **Optionen**:
- *"Neu laden"* (Lädt die aktuelle Version des Kontakts).
- *"Trotzdem speichern"* (Überschreibt die Änderungen, **nur für Admins**).
---
### **2.5. Hinweis bei übersprungenen Kontakten**
- **Automatisches Überspringen** von Kontakten, die nicht mehr den Filterkriterien entsprechen.
- **Hinweis in der UI**:
```
Kontakt [Name] wurde übersprungen, da er nicht mehr den Filterkriterien entspricht
(Grund: [z. B. 'Wiedervorlage-Datum außerhalb der gefilterten Woche' oder 'Kontakt wurde als erledigt markiert']).
```
---
---
---
## **🔄 3. Workflows &amp; Logik**
---
### **3.1. Wiedervorlage-Datum Berechnung**
- **Automatische Berechnung**:
- Falls **kein manuelles `wiedervorlage_datum`** in der Notiz gesetzt ist:
- **Minimum** der `wiedervorlage_abstand_tage` aller ausgewählten Tags mit `loest_wiedervorlage_aus = True`.
- **Wiedervorlage-Datum = Erstellungsdatum der Notiz + Minimum-Abstand**.
- **Manuelle Überschreibung**:
- Der Mitarbeiter kann das **`wiedervorlage_datum`** jederzeit manuell ändern (z. B. über den Datumspicker).
---
### **3.2. Statusberechnung (dynamisch)**
- **Kontaktstatus**:
- Wird **dynamisch** über die Methode `is_erledigt()` berechnet (siehe [1.3](#13-neue-methoden-statusberechnung)).
- **Kein statisches `status`-Feld** in der Datenbank.
- **Projektstatus**:
- Wird **dynamisch** über die Methode `is_erledigt()` berechnet.
---
### **3.3. Tages-Workflow (Ablauf)**
1. **Aufruf des Tages-Workflows**:
- Mitarbeiter wählt **"Tages-Workflow"** aus.
- **System**: Zeigt die **priorisierte Liste** der Kontakte an (sortiert nach Wiedervorlage-Datum).
2. **Filter anwenden**:
- Mitarbeiter wählt Filter (z. B. Kunde, Tag-Kategorie, einzelne Tags).
- **System**: Aktualisiert die Liste basierend auf den Filtern.
3. **Workflow beginnen**:
- Mitarbeiter klickt auf **"Workflow beginnen"**.
- **System**: Lädt den **ersten Kontakt** aus der gefilterten Liste in die Bearbeitungsmaske.
4. **Bearbeitung des Kontakts**:
- Mitarbeiter erfasst eine **neue Gesprächsnotiz** (Text, Tags, **Wiedervorlage-Datum**).
- **System**:
- Berechnet das **`wiedervorlage_datum`** (falls nicht manuell gesetzt).
- Inkrementiert die **`version`** des Kontakts (für optimistisches Locking).
5. **Speichern und weiter**:
- Mitarbeiter klickt auf **"Speichern und weiter"**.
- **System**:
- Speichert die Notiz und prüft die **`version`** des Kontakts.
- Falls **Konflikt** (Version stimmt nicht überein **UND** Status wurde Wesentlich geändert):
- Zeigt **Konfliktmeldung** an.
- Lädt den **nächsten Kontakt** aus der Liste, der die **Filterkriterien erfüllt**.
- Falls kein Kontakt mehr passt:
- Zeigt Meldung: *"Keine weiteren Kontakte entsprechen den Filterkriterien."*
- Kehrt zur **gefilterten Liste** zurück.
---
### **3.4. Dynamische Filterprüfung**
- **Beim Laden des nächsten Kontakts**:
- **System prüft**:
- Ist der Kontakt noch **nicht erledigt** (`is_erledigt() = False`)?
- Liegt das **Wiedervorlage-Datum** noch im gefilterten Zeitraum?
- Falls der Kontakt **nicht mehr passt**:
- Lädt den **nächsten Kontakt**, der die Kriterien erfüllt.
---
---
---
## **📊 4. Beispiel-Daten**
---
### **4.1. Tags**
| **Name** | **`is_erledigend`** | **`loest_wiedervorlage_aus`** | **`wiedervorlage_abstand_tage`** |
| ------------------ | ------------------- | ----------------------------- | -------------------------------- |
| Uninteressiert | `True` | `False` | `NULL` |
| Wiedervorlage | `False` | `True` | `7` |
| Nicht erreicht | `False` | `True` | `3` |
| Rückruf vereinbart | `False` | `True` | `1` |
| Falsche Nummer | `False` | `False` | `NULL` |
| Erfolgreich | `False` | `False` | `NULL` |
| Termin vereinbart | `False` | `True` | `14` |
---
### **4.2. Gesprächsnotizen**
| **Kontakt** | **Notiz** | **Tags** | **Wiedervorlage-Datum** | **Berechnung** |
| -------------- | -------------------- | ------------------ | ----------------------- | ----------------------------- |
| Max Mustermann | "Nicht erreicht" | Nicht erreicht | **20.09.2026** | Heute + 3 Tage (Tag-Abstand) |
| Anna Schmidt | "Rückruf vereinbart" | Rückruf vereinbart | **21.09.2026** | Heute + 1 Tag (Tag-Abstand) |
| Peter Müller | "Termin vereinbart" | Termin vereinbart | **04.10.2026** | Heute + 14 Tage (Tag-Abstand) |
---
---
---
## **🔍 5. Zusammenfassung der Änderungen**
| **Bereich** | **Änderung / Neuerung** |
| ---------------------- | --------------------------------------------------------------------------------------------- |
| **Datenmodell** | **Kein `status`-Feld** in `Project` oder `Contact` → **dynamische Methoden `is_erledigt()`**. |
| **`CallLog`** | **Einziges `wiedervorlage_datum`-Feld** (automatisch berechnet oder manuell überschrieben). |
| **`Contact`** | **`version`-Feld** für optimistisches Locking. |
| **Filter** | **Einzelne Tags** als Filteroption (Mehrfachauswahl). |
| **Bearbeitungsmaske** | **Wiedervorlage-Datum** ist manuell änderbar, wird aber automatisch aus Tags berechnet. |
| **Workflow-Logik** | Dynamische Filterprüfung beim Laden des nächsten Kontakts. |
| **Konfliktbehandlung** | Optimistisches Locking mit `version`-Feld + Meldung bei **wesentlichen Änderungen**. |