🔧 CR-Workflow — Programmablaufplan v8

Change Request Lifecycle · 26.03.2026 · Alle Schritte + E-Mails durchnumeriert

Prozess-Schritt
📧 E-Mail
◆ Entscheidung
🔄 Loop
✅ Live
❌ Abgelehnt
Gemeinsame Schritte
1

E-Mail empfangen

📦 Support-Bot (Container)
SMTP smtp-server Port 25 → processEmail()

Kunde sendet E-Mail an {siteId}@support.minicon.eu

2

LLM-Analyse

🤖 Support-Bot LLM (Claude → MiniMax → CF Workers AI)
LLM analysiert Inhalt → setzt [CHANGE] Tag wenn Änderungswunsch

Klassifizierung: Änderungswunsch → [CHANGE] oder normale Anfrage

3 [CHANGE] Tag gesetzt?
🤖 Support-Bot LLM (automatisch in Schritt [2])
LLM-Prompt: "Setze [CHANGE] wenn der Kunde eine Änderung an seiner Website wünscht"
processEmail() → if (llmResponse.includes('[CHANGE]'))
✅ Ja
→ Weiter zu [4]
❌ Nein
3a

Normale Antwort

🤖 Support-Bot

Bot antwortet direkt, kein CR erstellt

⏹ Ende

4

CR erstellen

📦 Support-Bot / 🌐 Kundenportal
ChangeRequest.create({ status: 'new', siteId, subject, description, requestedBy, attachments })
🐙 gh issue create --repo Minicon-eG/website-{siteId} --title "CR: {subject}" --label change-request
Zwei Eingänge:
📧 E-Mail → Support-Bot erstellt CR nach [CHANGE]-Erkennung [1]–[3]
🌐 KundenportalPOST /api/customers/me/requests → CR direkt erstellt (überspringt [1]–[3])
new
5

Komplexität prüfen

📦 Support-Bot
estimateComplexity()

Keywords: layout, redesign, navigation, menü, logo, branding, neue seite, responsive, formular, galerie
Ergebnis: costFactor (0 = einfach, >0 = komplex)

5a Andere CR für diese Site aktiv?
📦 Support-Bot (Queue-Manager)
ChangeRequest.findOne({ siteId, status: { $in: ["preview","ready","implementing","deployed","estimate"] }, _id: { $ne: cr._id } })
✅ Queue frei
→ Weiter zu [6] + M2
⏳ Queue belegt
5b

In Warteschlange einreihen

📦 Support-Bot
cr.status = 'queued', cr.queuePosition = N
new queued

⏹ Ende — wartet auf [F1]

📧 M2

Eingangsbestätigung (personalisiert + Zusammenfassung)

📦 Support-Bot
An: Kunde (requestedBy) · Von: Bot-Persona ({siteId}@support.minicon.eu)
LLM generiert personalisierte Bestätigung basierend auf CR-Beschreibung + costFactor
🟢 Einfach (cf=0)

"Wir haben verstanden: [Zusammenfassung]. Diese Änderung setzen wir direkt um — Sie werden benachrichtigt, sobald alles live ist."

🟡 Komplex (cf>0)

"Wir haben verstanden: [Zusammenfassung]. Da diese Änderung umfangreicher ist, erstellen wir zunächst eine Aufwandschätzung."

6 costFactor > 0? (Komplex?)
📦 Support-Bot (estimateComplexity)
🟢 Einfacher Pfad (costFactor = 0)
E1

Auto-Approve + Ready

📦 Support-Bot
status: 'ready', costFactor: 0
🐙 gh issue comment --body "Status: new → ready (Auto-Approve, cf=0)"

Support-Bot setzt direkt auf ready

new ready
🔄 E2 — CR Bridge Cron (extern, alle 5 Min)
E2a CR mit status: ready vorhanden?
🔁 CR Bridge (cr-bridge.ps1)
GET /api/admin/changes?status=ready&limit=1
❌ Nein
Warten (5 Min)
↩ Loop → [E2a]
✅ Ja
E2b

An CR Worker dispatchen

🔁 CR Bridge
sessions_send() → PATCH { status: "implementing" }
Optimistic Locking: findOneAndUpdate({ _id, status: "ready" }, { status: "implementing", assignedWorker })
matchedCount: 0 → bereits vergeben → nächste CR
ready implementing
🐙 gh issue comment --body "Status: ready → implementing | assignedWorker: {workerId}"
🔄 E3–E3b — Implementierung + QA (Retry-Loop)
E3

Implementierung

🤖 CR Worker (Agent)
git clone → edit → npm run build → git push origin preview

GitHub Actions deployt Preview-Container

🐙 gh issue comment --body "Commit: {sha} · Branch: preview"
Falls Assets/Infos fehlen: CR Worker erkennt fehlende Daten → Rückfrage an Kunde
implementing waiting
Wenn Kunde liefert → waiting ready → Bridge dispatcht erneut
E3b

QA-Review

🤖 CR Worker (nach Build, vor Callback)
runQAReview(cr, previewUrl)

Automatisches QA mit 9-Punkte-Checkliste

E3c QA bestanden?
✅ Ja
→ Weiter zu [E4] Callback
❌ Nein
Retry (max 2x):
1. Auto-Fix versuchen
2. Falls fehlgeschlagen → zurück zu [E3] Implementierung
Nach 2x fehl:
escalated + Telegram-Alert
🐙 GitHub: Comment "⚠️ QA fehlgeschlagen nach 2 Retries — Eskalation"
Admin-Action nötig: Status bleibt escalated bis Admin eingreift
→ Admin kann: ready (neuer Versuch) | rejected (abbrechen) | done (manuell genehmigt)
↩ Loop → bei QA-Fehler zurück zu [E3]
E4

Callback senden

🤖 CR Worker → 📦 Website-Service
📡 API Call
POST /api/internal/cr-deployed { crId, qaReport }
⚙️ Parameter
X-Internal-Secret Header
crId = eindeutiger Lookup
qaReport wird mitgesendet
🐙 gh issue comment --body "QA bestanden: 9/9 Checks ✅"
E5

Preview verarbeiten

📦 Website-Service
approvalToken generieren → status: 'deployed'
implementing deployed
🔄 E6 — Feedback-Loop (Preview)
E6 Kunde prüft Preview
👤 Kunde (per E-Mail-Button)
✅ Freigeben
E6a

Freigegeben

👤 Kunde → 📦 Website-Service
GET /api/cr/approve?token=xxx
deployed approved
✏️ Anpassen
E6b

Anpassung gewünscht

🤖 Support-Bot prüft zuerst
Bot-Logik:
Kleine Anpassung: → Direkt zu [E3] (Re-Implementierung)
Große Anpassung: → Support-Bot informiert Admin für Neu-Schätzung
E6c

Re-Implementierung

🔁 CR Bridge → 🤖 CR Worker
→ Zurück: [E2][E3][E4][E5]
deployed ready
↩ Loop → [E6]
❌ Ablehnen
E6d

Abgelehnt

👤 Kunde → 📦 Website-Service
deployed rejected

⏹ Ende

Freigegeben
E7

Production Deploy

📦 Website-Service
dispatchProductionDeploy() → merge preview → main

Preview-Branch löschen, Issue schließen

approved done
🐙 GitHub: Comment "✅ Live auf Production" + Issue close
E8

✅ Live auf Production

🌐 GitHub Actions → Cloudflare/Server
↓ Weiter zu [F1]
🟡 Komplexer Pfad (costFactor > 0)
K1

Aufwandschätzung + Umsetzungsplan erstellen

🤖 Support-Bot LLM
estimateComplexity() → Stunden + Kategorie + Umsetzungsplan
LLM generiert:
  • Stunden-Schätzung — z.B. 4h
  • Kategorie — z.B. "Neues Feature", "Redesign", "Content-Update"
  • Umsetzungsplan — konkrete Schritte:
    1. Neue Unterseite "/galerie" anlegen (Next.js Page)
    2. Galerie-Komponente mit Lightbox implementieren
    3. 12 Bilder optimieren (WebP, responsive)
    4. Navigation um "Galerie"-Link erweitern
    5. Mobile-Ansicht testen + anpassen
  • Betroffene Dateien/Bereiche — z.B. "Navigation, neue Page, Bilder"
  • Risiken/Abhängigkeiten — z.B. "Bilder müssen vom Kunden geliefert werden"
new estimate
K1b Admin prüft Schätzung
👤 Admin (per E-Mail/Telegram/Portal)
✅ Kostenpflichtig
Kunde muss zahlen
billable: true
units: 3
🎁 Kostenfrei
billable: false
estimate ready
✏️ Anpassen
Stunden/Plan korrigieren
→ dann an Kunde
❌ Ablehnen
Nicht umsetzbar
estimate rejected
⏳ Assets fehlen
Bilder/Texte fehlen
Rückfrage an Kunde
estimate waiting
K1b2 Assets/Infos vollständig?
🤖 LLM (zuerst) → 👤 Admin (Fallback)
LLM-First-Logik: LLM prüft automatisch. Nur wenn unsicher → Admin entscheidet manuell.
✅ Alles da
→ Weiter zu [K1c] Billable?
⏳ Fehlt etwas
K1b3

Warten auf Zulieferung

📦 Support-Bot
cr.status = 'waiting', cr.waitingFor = "Bilder / Texte / Logo / ..."
waiting
⏸ Wartet auf Kunden-Mail mit Assets
T3 Follow-up-Erkennung: Kunden-Mail → CR updaten → weiter zu [K1c]
T2 Reminder: 7d Erinnerung, 30d Auto-Close
K1c Billable?
📦 Support-Bot (basierend auf Admin-Entscheidung)
🎁 Kostenfrei (billable: false)
→ Direkt auf ready[K3] Bridge dispatcht
💰 Kostenpflichtig (billable: true)
→ Weiter zu M3 (Schätzung an Kunde)
🔄 Feedback-Loop (Aufwand)
K2 Kunde entscheidet
👤 Kunde (per E-Mail-Button)
✅ Freigeben
K2a

Aufwand akzeptiert

👤 Kunde → 📦 Website-Service
GET /api/cr/approve-estimate?token=xxx
estimate ready
✏️ Feedback
K2c

Feedback gesendet

👤 Kunde
K2d

Neu bewerten

📦 Support-Bot
↩ Loop → [K2]
❌ Ablehnen
K2b

Abgelehnt

👤 Kunde → 📦 Website-Service
estimate rejected

⏹ Ende

Freigegeben → ready
🔄 K3 — CR Bridge Cron (extern, alle 5 Min)
K3a CR mit status: ready vorhanden?
🔁 CR Bridge (cr-bridge.ps1)
❌ Nein
Warten (5 Min)
↩ Loop → [K3a]
✅ Ja
K3b

An CR Worker dispatchen

🔁 CR Bridge
sessions_send() → PATCH { status: "implementing", assignedWorker }
Optimistic Locking: findOneAndUpdate({ _id, status: "ready" })
ready implementing
🔄 K4–K4b — Implementierung + QA (Retry-Loop)
K4

Implementierung

🤖 CR Worker (Agent)
git clone → edit → build → push preview
Falls Assets/Infos fehlen: CR Worker erkennt fehlende Daten → Rückfrage an Kunde
implementing waiting
Wenn Kunde liefert → waiting ready → Bridge dispatcht erneut
K4b

QA-Review: Automatische Qualitätsprüfung

🤖 CR Worker (nach Build, vor Callback)
runQAReview(cr, previewUrl)
Checkliste (aus DB konfigurierbar):
📋 Prompt-ID: qa_checklist_v8 · Quelle: MongoDB config.prompts
CR-Anforderungen erfüllt?LLM vergleicht CR-Beschreibung mit Code-Diff
Build erfolgreich?npm run build exit code 0
Keine ungewollten Änderungen?Diff-Check: nur relevante Dateien geändert
Site-Marker vorhanden?<!-- minicon:{siteId} --> in HTML
Preview erreichbar?HTTP 200 auf https://preview-{siteId}.minicon.eu
Keine Console-Errors?Playwright: page.on('console', err)
Responsive OK?Playwright: Screenshot Desktop + Mobile
Keine kaputten Links?Crawl: alle internen Links → HTTP 200
Performance akzeptabel?Lighthouse Score > 70
Ergebnis:
✅ Alle Checks bestanden
→ Weiter zu Callback [K5]
❌ Check(s) fehlgeschlagen
→ CR Worker versucht automatisch zu fixen
→ Nach 2 Versuchen: status: "escalated" + Admin-Alert
→ QA-Report wird an Admin geschickt
K4c QA bestanden?
✅ Ja
→ Weiter zu [K5] Callback
❌ Nein
Retry (max 2x):
1. Auto-Fix versuchen
2. Falls fehlgeschlagen → zurück zu [K4] Implementierung
Nach 2x fehl:
escalated + Telegram-Alert
🐙 GitHub: Comment "⚠️ QA fehlgeschlagen nach 2 Retries — Eskalation"
Admin-Action nötig: Status bleibt escalated bis Admin eingreift
→ Admin kann: ready (neuer Versuch) | rejected (abbrechen) | done (manuell genehmigt)
↩ Loop → bei QA-Fehler zurück zu [K4]
K5

Callback senden

🤖 CR Worker → 📦 Website-Service
POST /api/internal/cr-deployed { crId, qaReport }

QA-Report wird mitgesendet (Checkliste + Screenshots)

K6

Preview verarbeiten

📦 Website-Service
approvalToken generieren → status: 'deployed'
implementing deployed
🔄 Feedback-Loop (Preview)
K7 Kunde prüft Preview
👤 Kunde (per E-Mail-Button)
✅ Freigeben
K7a

Freigegeben / Bezahlt

👤 Kunde → 📦 Website-Service
Kostenfrei: GET /api/cr/approve?token=xxx
Kostenpflichtig: Stripe Checkout → Webhook checkout.session.completed
deployed approved
✏️ Anpassen
K7c

Anpassung gewünscht

🤖 Support-Bot prüft zuerst
Bot-Logik:
Kleine Anpassung: → Direkt zu [K4] (Re-Implementierung)
Große Anpassung: → Support-Bot informiert Admin für Neu-Schätzung
K7c1 Billable CR + Aufwand prüfen
👤 Admin prüft Feedback
Kleine Anpassung
Im Rahmen der bezahlten Einheiten
→ direkt Re-Implementierung
Keine Zusatzkosten
Komplexe Anpassung
Neuer Aufwand → Nachschätzung
units: 3 → 5 (+2)
Kunde?
💳 Zahlt Aufpreis
→ Re-Implementierung
mit erweitertem Scope
❌ Nein danke
→ Bleibt bei Original
units bleiben bei 3
→ zurück zu [K7] mit
unveränderter Preview
K7d

Re-Implementierung

🔁 CR Bridge → 🤖 CR Worker
→ Zurück: [K3][K4][K5][K6]
↩ Loop → [K7]
❌ Ablehnen
K7b

Abgelehnt

👤 Kunde → 📦 Website-Service
deployed rejected

⏹ Ende

Freigegeben
K8

Production Deploy

📦 Website-Service
dispatchProductionDeploy() → merge preview → main

Preview-Branch löschen, Issue schließen

approved done
K9

✅ Live auf Production

🌐 GitHub Actions → Cloudflare/Server
Status Update: status: 'done'
Nächster Schritt: Bot führt automatisch [F1] Follow-up aus (CR Bridge Cron, alle 5 Min)
↓ Weiter zu [F1]
🔄 Follow-up nach Done/Rejected
⚡ Direkte Fortsetzung
Wird sofort vom Support-Bot durchgeführt, nachdem Website-Service die CR auf done gesetzt hat.
Kein separater Trigger — synchroner Folgeschritt.
F1 Weitere CRs für diese Site in Queue?
📦 Support-Bot
ChangeRequest.find({ siteId, status: 'queued' }).sort({ createdAt: 1 }).limit(5)
❌ Keine CRs in Queue

⏹ Fertig — nichts zu tun

✅ CRs warten
F2 Kunde entscheidet
👤 Kunde (per E-Mail-Button)
✅ Weiter
F2a

Nächste CR aktivieren

📦 Support-Bot
queued ready
→ Zurück zu [E2]/[K3] (Bridge pickt auf)
⏸ Pausieren
F2b

Queue pausiert

📦 Support-Bot
CRs bleiben in queued
Kunde kann jederzeit per Mail fortsetzen
❌ Stornieren
F2c

Queue leeren

📦 Support-Bot
queued rejected
📧 E-Mail-Übersicht
Nr.NameWannWer sendetButtons
M1Antwort-Mail (kein CR)[3a]Support-Bot
M2EingangsbestätigungNach [5a]Support-Bot
M2qQueue-Bestätigung[5b] Queue belegtSupport-Bot
M3aSchätzung + Plan → Admin-Review[K1]Support-Bot → Admin✅💰 🎁 ✏️ ❌
M3fKostenfreie Umsetzung Info[K1c] billable=falseSupport-Bot
M3/M3'Aufwandschätzung → Kunde (kostenpflichtig)[K1c] billable=true / LoopSupport-Bot✅ ✏️ ❌
M4Ablehnungs-Bestätigung[K2b]Support-Bot
M5/M5'Preview-Mail[K6] / LoopSupport-Bot💳/✅ ✏️ ❌
M5aNachschätzung (Anpassung kostet mehr)[K7c1] komplexe AnpassungSupport-Bot💳 ❌
M6Live-Bestätigung (komplex)[K8]Support-Bot
M7Preview abgelehnt[K7b]Support-Bot
M5e/M5e'Preview-Mail (einfach)[E5] / LoopSupport-Bot✅ ✏️ ❌
M7ePreview abgelehnt (einfach)[E6d]Support-Bot
M8Live-Bestätigung (einfach)[E7]Support-Bot
M9Queue-Fortsetzung[F1]Support-Bot✅ ⏸ ❌
M10Rückfrage: Assets/Infos fehlen[K1b]/[E3]/[K4] → waitingSupport-Bot
M11Admin-Info: Kunde will Anpassungen[E6b]/[K7c]Support-Bot → Admin
🏗️ Komponenten (v8)
KomponenteTypRolle (v8)Schritte
📦 Support-BotContainer (Prod)Zentraler Orchestrator + einziger E-Mail-Sender — E-Mail empfangen/senden, LLM, CR-Erstellung, Queue-Management, Status-Setzung[1]–[5b], [E1], [K1], M1–M9 (alle Mails), [F1][F2]
🔁 CR BridgeOpenClaw Cron (5min)Dispatcher — pollt ready CRs, sendet an Worker[E2], [K3]
🤖 CR WorkerOpenClaw AgentImplementierer — Code ändern, Build, Push, Callback[E3][E4], [K4][K5]
📦 Website-ServiceContainer (Prod)API + Deploy-Logik — Callback, Approval, Merge. Keine Mails — triggert Support-Bot[E5], [K6][K8]
⚠️ Edge Cases & Absicherungen
T1

Timeout + Progress-Monitoring: CR stuck in implementing

📦 CR Bridge (Cron-Check, alle 5 Min) + OpenClaw Session-Timeout
Zwei Ebenen:
📊 Progress-Updates (CR Worker meldet sich):
PATCH /api/admin/changes/:id {
  implementationStep: "cloning" | "analyzing" | "editing" | "building" | "testing" | "pushing",
  lastProgress: Date.now()
}
CR Worker ruft nach jedem Schritt PATCH auf → Admin sieht in Echtzeit wo der Worker steht.
Wenn lastProgress > 15 Min alt → Worker hängt vermutlich.
⏱ Dynamischer Session-Timeout (Sicherheitsnetz):
🟢 Einfach (cf=0)runTimeoutSeconds: 180030 Min
🟡 Komplex (cf>0, units ≤ 3)runTimeoutSeconds: 540090 Min
🔴 Sehr komplex (units > 3)runTimeoutSeconds: 10800180 Min
OpenClaw killt die Agent-Session automatisch bei Timeout.
Kein cr-deployed Callback = CR Bridge erkennt Timeout.
Ablauf bei Timeout/Stuck:
  1. CR Bridge erkennt: status: "implementing" + kein Progress seit Timeout-Dauer
  2. Status zurück auf ready, assignedWorker löschen, retryCount++
  3. GitHub Issue Kommentar: "⚠️ Timeout bei Schritt [implementationStep] — Retry [N/3]"
  4. CR Bridge pickt beim nächsten Tick auf → neuer Worker
  5. Nach 3 Retries → Status escalated + Telegram-Alert an Admin mit letztem implementationStep
T2

Reminder: Kunde antwortet nicht

📦 Support-Bot (Cron-Check, täglich)
ChangeRequest.find({ status: { $in: ["estimate","deployed"] }, updatedAt: { $lt: now - 3d } })
Ablauf — Zwei Szenarien:
1️⃣ Estimate/Deployed (Angebot):
  1. CR seit 3 Tagen ohne Kundenreaktion
  2. 📧 Reminder-Mail: "Wir warten noch auf Ihre Rückmeldung zu [Zusammenfassung]"
  3. Nach 14 Tagen ohne Reaktion → Auto-Close: Status rejected + Info-Mail
2️⃣ Waiting (Assets erforderlich): [K1b3]
  1. CR wartet auf Assets-Lieferung
  2. Tag 7: 📧 Erinnerungs-Mail an Kunde
  3. Tag 30: Auto-Close → Status rejected + Info-Mail + GitHub Issue closed
Kunde kann jederzeit per E-Mail reaktivieren
T3

Follow-up Erkennung: Mail zu bestehender CR

🔲 Cloudflare Worker (Support-Bot) · Polling alle 30 Sekunden
Mailbox scannen → Reply-To abgleichen → Assets an CR anhängen
Implementierung:
  • Polling: Cloudflare Worker alle 30s (nicht 5 Min!)
  • Erkennung: Reply-To Header-Match zu bestehender CR
  • Speicherung: Mail + Attachments in MongoDB (communications-Array)
  • Bedingung: Nur wenn CR noch nicht done/live
    • ✅ Status: ready, implementing, deployed, waiting → Assets akzeptiert
    • ❌ Status: done → Neuer CR nötig (Support-Bot notifiziert)
  • Auto-Ready: Wenn CR in waiting → automatisch auf ready setzen
  • GitHub: Attachments als Binary Upload in GitHub Issue hinzufügen (noch TODO)
T4

Debounce: Mehrere Mails in kurzer Zeit

📦 Support-Bot
15-Minuten-Fenster pro siteId + requestedBy
Ablauf:
  1. Erste Mail mit [CHANGE] → CR erstellen, 15min Timer starten
  2. Weitere Mails innerhalb 15min vom gleichen Absender → an bestehende CR anhängen
  3. Nach 15min ohne neue Mail → CR finalisieren, weiter mit [5]
  4. Anhänge aus allen Mails werden gesammelt
T5

Build/Deploy schlägt fehl

🤖 CR Worker (erkennt Fehler) → 📦 Support-Bot (informiert Admin)
GitHub Actions Workflow failed → kein cr-deployed Callback
Ablauf:
  1. CR Worker pushed → GitHub Actions Build schlägt fehl
  2. Kein cr-deployed Callback → [T1] Timeout greift nach 30min
  3. CR Worker sollte Build-Ergebnis prüfen und bei Fehler:
    PATCH { status: "failed", devWorkerError: "Build failed: ..." }
  4. Status failed → Telegram-Alert an Admin
  5. Admin entscheidet: Retry oder Eskalation
T6

Production Deploy schlägt fehl nach Approval

📦 Website-Service (erkennt Fehler) → 📦 Support-Bot (informiert)
dispatchProductionDeploy() returned false → Support-Bot: Telegram-Alert
Ablauf:
  1. Merge preview → main schlägt fehl (Konflikt, API-Fehler)
  2. Status auf failed statt done
  3. Telegram-Alert an Admin
  4. Kunde bekommt KEINE "ist live"-Mail (erst nach erfolgreichem Deploy)
  5. Admin fixt manuell → Status auf done[F1] triggert
T7

Reminder: Admin reviewt Schätzung nicht

📦 Support-Bot (Cron-Check, alle 4h)
ChangeRequest.find({ status: "estimate", adminReviewSentAt: { $lt: now - 24h }, adminReviewedAt: null })
Ablauf:
  1. M3a an Admin gesendet, aber seit 24h keine Reaktion
  2. Telegram-Reminder an Admin: "⏰ Offene Schätzung für [siteId]: [Zusammenfassung]"
  3. Nach 48h: Eskalation — zweiter Reminder mit Priorität
  4. Keine Auto-Action — Admin muss bewusst entscheiden
✨ UX-Verbesserungen
U1

ETA in Eingangsbestätigung (M2)

📦 Support-Bot
Einfach: "Einfache Änderungen sind in der Regel innerhalb von 1–2 Stunden live."
Komplex: "Sie erhalten die Aufwandschätzung innerhalb der nächsten Stunde."
U2

Änderungs-Zusammenfassung bei einfachen CRs (M8)

📦 Support-Bot
Auch einfache CRs bekommen eine inhaltliche Bestätigung:
"Folgende Änderung wurde umgesetzt: [LLM-generierte Zusammenfassung aus Diff/Commit]"
Optional: Vorher/Nachher-Screenshot (via Playwright auf Server)
U3

Status-Link in jeder E-Mail

📦 Support-Bot
Jede E-Mail enthält Link zum Kundenportal:
https://mein.minicon.eu/requests
Dort sieht der Kunde alle CRs mit Status, Queue-Position, Zeitstempel
U4

Fehlklassifizierung korrigierbar

📦 Support-Bot
Wenn LLM falsch klassifiziert (einfach statt komplex oder umgekehrt):
  • Kunde antwortet auf M2/M8: "Das war aber mehr als eine kleine Änderung"
  • Follow-up-Erkennung [T3] → Support-Bot re-evaluiert
  • Admin kann über Portal jede CR manuell umklassifizieren
📝 Tracking & Dokumentation
D1

Kommunikations-Log (MongoDB)

📦 Support-Bot / Website-Service
Jede Interaktion wird auf der CR dokumentiert:
cr.communications: [
  {
    timestamp, direction: "inbound" | "outbound",
    type: "email" | "portal" | "system",
    from, to,
    subject, body, attachments[],
    emailId, // Referenz auf SupportEmail
    mailType // M1, M2, M3, M5, M9 etc.
  }
]
Geloggt wird:
📥Eingehende Kunden-Mail[1] processEmail()
📤Jede ausgehende E-MailM1–M9, M3a, M3f, M5a
👤Kunden-AktionenApprove, Reject, Feedback (mit Inhalt)
👨‍💼Admin-AktionenSchätzung geprüft, kostenfrei/kostenpflichtig, Anpassung
🤖System-EventsStatus-Änderungen, QA-Report, Timeouts, Retries
📋Portal-AktionenCR über Portal eingereicht, Feedback über Portal
Abrufbar über:
• Admin-Portal: GET /api/admin/changes/:id/communications
• Kunden-Portal: GET /api/customers/me/requests/:id (nur eigene Kommunikation)
• Lückenlose Historie für Streitfälle, Nachvollziehbarkeit, DSGVO-Auskunft
D2

GitHub Issue (pro CR)

📦 Support-Bot (bei CR-Erstellung) / Website-Service (bei Updates)
Issue wird automatisch erstellt und gepflegt:
Erstellung [4]:
🐙 gh issue create --repo Minicon-eG/website-{siteId}
  --title "CR: {subject}"
  --body "{description}\n\nCR-ID: {crId}"
  --label "change-request"
  --label "{costFactor > 0 ? 'complex' : 'simple'}"
Automatische Updates als Kommentare:
📋Status-Änderung"Status: ready → implementing"
💰Schätzung"Aufwand: 3 Einheiten · Plan: [Schritte]"
👨‍💼Admin-Review"Admin: Freigegeben (kostenpflichtig/kostenfrei)"
👤Kunden-Feedback"Kunde: Anpassung gewünscht — [Feedback-Text]"
🤖Implementation"Commit: abc1234 · Branch: preview"
QA-Report"QA bestanden: 9/9 Checks ✅"
💳Zahlung"Stripe: 3 Einheiten bezahlt"
🔁Retry/Eskalation"Retry 2/3 — Build fehlgeschlagen"
Issue schließen bei:
status: done → Issue close mit Kommentar "✅ Live auf Production"
status: rejected → Issue close mit Label rejected
• CR-ID wird im Issue referenziert, Issue-Number wird auf CR gespeichert: cr.githubIssue: 42
📊 Status-Übersicht
StatusBedeutungWer setztTimeout
newCR erstellt, wird verarbeitetSupport-Bot [4]
queuedWartet auf andere CR für gleiche SiteSupport-Bot [5b]
previewCR in Bearbeitung (Preview-Zyklus)Support-Bot [5a]
estimateAufwandschätzung gesendet, wartet auf KundeSupport-Bot [K1]3d Reminder, 14d Auto-Close [T2]
readyBereit für ImplementierungSupport-Bot [E1]/[K2a]
implementingCR Worker arbeitet dranCR Bridge [E2b]/[K3b]Dynamisch: 30/90/180min [T1]
deployedPreview live, wartet auf KundeWebsite-Service [K6]3d Reminder, 14d Auto-Close [T2]
approvedKunde hat freigegebenWebsite-Service [K7a]
doneLive auf ProductionWebsite-Service [E5]/[K8]— → [F1]
rejectedAbgelehnt oder Auto-CloseKunde / Timeout [T2]— → [F1]
failedBuild/Deploy fehlgeschlagenCR Worker [T5] / Website-Service → Support-Bot [T6]Admin-Eskalation
escalated3x Retry fehlgeschlagenTimeout [T1]Admin muss handeln
waitingWartet auf externe Zulieferung (Bilder, Texte, Assets)Admin / Support-Bot7d Reminder, 30d Auto-Close [T2]
⚙️ System Configuration

Konfigurierbare LLM-Prompts

Folgende Prompts können über MongoDB config.prompts editiert und konfiguriert werden:

Prompt-IDSchrittFunktion
qa_checklist_v8K4b — QA-ReviewLLM-Prompt für automatische Qualitätsprüfung: 9-Punkte-Checkliste generieren und evaluieren
estimate_complexity_v3[5] Komplexität prüfenLLM-Prompt zur Analyse von CR-Anforderungen und Berechnung von costFactor (0 = einfach, >0 = komplex)
estimate_plan_v2K1 — AufwandschätzungLLM-Prompt für Erstellung von Implementierungsplänen mit Stundenaufwand und Schritte
change_classification_v1[2] LLM-AnalyseLLM-Prompt zur Klassifizierung: setzt [CHANGE] Tag wenn Änderungswunsch erkannt
Konfiguration:
db.config.findOneAndUpdate( { "prompts.id": "qa_checklist_v8" }, { $set: { "prompts.$.template": "..." } } )
Änderungen wirken sofort ohne Neustart → nächste QA wird mit neuem Prompt durchgeführt