Eviworx
Docs

Reopen- & Lifecycle-Governance

Reopen-Governance regelt einheitlich, ob, wie lange, durch wen und wie oft eine geschlossene Entität wieder geöffnet werden darf — über Ticket, Incident und Problem hinweg. Die Regeln sind für alle drei Entitätstypen gleich und je Typ in der Lifecycle-Config einstellbar. Dazu gehören Auto-Close (zeitgesteuertes Schließen gelöster Tickets), WC-Auto-Resolve (Auflösen unbeantworteter Waiting-Customer-Tickets), Stale-Reminder (Inaktivitäts-Eskalation über alle drei Domänen), Reopen-Eskalation (Qualitätssignal bei zu häufigem Wiederöffnen) und ein eigenes Analytics-Dashboard.

♻️
Funktionen
✓ Einheitliche Regeln für Ticket, Incident, Problem
✓ Einstellbar je Entitätstyp (Lifecycle-Config)
✓ Eigene Rechte (reopen / reopenOverride)
✓ Reopen-Fenster in Tagen und Maximalzahl
✓ Pflicht-Grund beim Reopen (+ optionale Notiz)
✓ Auto-Close mit Vorwarnung (standardmäßig aus)
✓ WC-Auto-Resolve (WAITING_CUSTOMER → RESOLVED)
✓ Stale-Reminder (Assignee → Lead → Manager)
✓ Reopen-Eskalation ab Schwellwert
✓ Lifecycle-Dashboard (Reopen-Rate, Top-Gründe)

🎫 Übersicht für Agents: automatische Ticket-Aktionen

Drei zeitgesteuerte Automatismen wirken auf Tickets — alle vom Admin in den System-Settings konfigurierbar und abschaltbar:

  • 1. WC-Auto-Resolve (Waiting for Customer → Resolved): Antwortet der Kunde X Tage nicht, wird das Ticket automatisch auf Resolved gesetzt (Code „Auto-Resolved — No Response"); optional Y Tage vorher eine Vorwarnung an Kunde und Agent. Der Timer läuft ab der letzten öffentlichen Nachricht — egal ob vom Kunden oder vom Agent: eine Erinnerungs-Mail an den Kunden startet ihn neu. Interne Notizen und Feld-Änderungen zählen nicht.
  • 2. Stale-Reminder (Inaktivität): Aktive Tickets (Open, In Progress, Waiting for Support), die zu lange unbearbeitet liegen, lösen eine Erinnerung aus (gestaffelt: Bearbeiter → Gruppen-Lead → Manager). Hier setzt jede Änderung am Ticket den Timer zurück — Status-Wechsel, Kommentar, Feld-Änderung, E-Mail-Reply. Status oder SLA werden dabei nie verändert.
  • 3. Auto-Close (Resolved → Closed): Tickets im Status Resolved werden nach der konfigurierten Frist automatisch geschlossen — ebenfalls optional mit Vorwarnung.

Alle Fristen liegen in der Lifecycle-Config je Entitätstyp und sind per Default deaktiviert. Technische Details (Config-Keys, Notifications, Jobs) siehe unten.

Ablauf eines Reopens

Ob wiedergeöffnet werden darf, entscheidet eine zentrale Prüfung anhand der Lifecycle-Config. Danach setzt das System die Abschlussfelder zurück (u. a. Resolution-Code, closedAt/resolvedAt), erhöht reopenCount und schreibt Timeline-Eintrag, Audit und Benachrichtigung.

Lifecycle-Config (je Entität, admin-editierbar)
        │  reopenEnabled · reopenWindowDays · reopenWindowMode · maxReopenCount
        │  reasonRequired · notifyOnReopen · slaOnReopenFrom{Resolved,Closed}
        │  autoCloseEnabled · autoResolveWaitingEnabled · staleReminderEnabled · reopenEscalationThreshold
        ▼
Reopen-Prüfung (Fenster, Limit, Grund, Genehmigung)        │  → erlaubt / abgelehnt mit Fehlercode        ▼
Zurücksetzen je Entitätstyp   Ticket
   Incident (+ Genehmigung)
   Problem
        │  reset closedAt/resolvedAt/resolutionCode · reopenCount++ · reopenedAt
        ▼
   Audit REOPENED · sichtbarer Timeline-Eintrag · Notification (*_REOPENED)

Reopen-Auswertung (Policy-Schritte)

Die Prüfung läuft in fester Reihenfolge ab. reopenOverride umgeht NUR Fenster und Limit — NICHT die Grund-Pflicht und NICHT die Approval-Pflicht (Incident). Auch ein Admin braucht einen Grund.

Schritt Prüfung Override? Error-Code
1Reopen aktiviert? (reopenEnabled)REOPEN_DISABLED
2Quelle terminal? (CLOSED/SPAM/…)REOPEN_NOT_TERMINAL
3Innerhalb Reopen-Fenster? (reopenWindowDays ab closedAt)✅ umgangenREOPEN_WINDOW_EXPIRED
4Unter Maximalzahl? (reopenCount < maxReopenCount)✅ umgangenREOPEN_LIMIT_REACHED
5Gültiger Reopen-Grund? (+ Notiz wenn requiresNote)❌ immer PflichtREOPEN_REASON_REQUIRED / REOPEN_REASON_INVALID / REOPEN_NOTE_REQUIRED
6Approval nötig? (nur Incident, Default an)❌ nie umgangenREOPEN_REQUIRES_APPROVAL

onWindowExpired (Ticket): Ist das Reopen-Fenster eines Tickets abgelaufen, erzeugt eine Kundenantwort per E-Mail ein neues, mit dem alten verknüpftes Ticket (originContext EMAIL_FOLLOWUP) statt eines Reopens — der Kunde wird nie ausgesperrt.

reopenWindowMode: Das Reopen-Fenster zählt wahlweise in Kalendertagen (CALENDAR, Default) oder Business-Tagen (BUSINESS). BUSINESS zählt nach den Geschäftszeiten der Standard-SLA-Policy des jeweiligen entityType; fehlt eine Default-Policy bzw. BusinessHours-Config, fällt es sicher auf CALENDAR zurück.

Verhalten je Domäne

Domäne Quelle → Ziel Reopen-Pfade Approval
Ticket CLOSED/SPAMOPEN Manuell (PATCH), E-Mail-Antwort, Web-Kommentar (System-Reopen)
Incident CLOSEDACKNOWLEDGED Dedizierte Route POST /:id/reopen Ja (Default) — incidents.approveReopen
Problem CLOSED/RESOLVEDINVESTIGATING Manuell (PATCH)

Wichtig (Ticket): RESOLVED ist KEINE Reopen-Quelle — der Wechsel von RESOLVED zurück in einen aktiven Status ist ein normaler editStatus-Wechsel (kein Grund, kein Counter), damit die Reopen-KPI sauber bleibt. Reopen-Quellen sind ausschließlich CLOSED und SPAM. Ein Reopen eines gemergten Tickets wird auf das lebende Ziel-Ticket umgeleitet (mergedToTicketId).

Feature-Matrix je Domäne

FeatureTicketProblemIncident
Reopen-Governance✅ (3 Pfade)✅ (manuell)✅ (manuell + Approval)
Auto-Close
WC-Auto-Resolve
Stale-Reminder
Reopen-Eskalation
Anzeige Reopen-Fenster
SLA config-gesteuert

Alle Lifecycle-Automationen (Auto-Close, WC-Auto-Resolve, Stale-Reminder, Reopen-Eskalation) sind per Default AUS und werden je Entität in der Lifecycle-Config aktiviert. Die zugehörigen Jobs laufen planmäßig, tun aber nichts, solange die Funktion nicht aktiviert ist.

Permissions

Reopen ist ein eigenes Recht; editStatus und editAll schließen es nicht ein. Eine Rolle mit editAll, aber ohne reopen, kann nicht wiederöffnen.

Permission-Key Wirkung
tickets.reopen · incidents.reopen · problems.reopenDarf die jeweilige Entität wiederöffnen (mit Grund, im Fenster/Limit)
tickets.reopenOverride · incidents.reopenOverride · problems.reopenOverrideUmgeht Fenster + Limit (NICHT Grund-Pflicht, NICHT Approval). Standardmäßig nur Admin.

Die mitgelieferten Standardrollen sind so vorbelegt: Agent hat reopen, Admin hat reopen und reopenOverride, Endanwender und Genehmiger haben keines der beiden Rechte. Einer neu angelegten Rolle müssen beide Rechte ausdrücklich gegeben werden. Permissions & RBAC

Konfiguration (Admin)

Zwei Bereiche steuern die Governance — Admin-Center → Service-Konfiguration → Reopen & Lifecycle (/admin/lifecycle), Recht settings.editGeneral:

  • Reopen-Gründe — CRUD je Entität (Label mehrsprachig, Notiz-Pflicht je Grund, Sortierung, Soft-Delete → 204). Fehler: doppelter Code 409 REOPEN_REASON_CODE_EXISTS; letzter aktiver Grund einer Entität 409 REOPEN_REASON_LAST_ACTIVE; unbekannte ID 404 REOPEN_REASON_NOT_FOUND. Inaktive Gründe mitzulesen (?includeInactive=true) erfordert settings.editGeneral; ein Entzug dieses Rechts wirkt sofort. GET/POST/PATCH/DELETE /api/reopen-reasons
  • Lifecycle-Config — Fenster (Tage + Modus CALENDAR/BUSINESS), Maximalzahl, Grund-Pflicht je Rolle, notifyOnReopen, SLA-Verhalten bei Reopen (slaOnReopenFromResolved/Closed), Auto-Close, WC-Auto-Resolve, Stale-Reminder-Tiers, Eskalations-Schwelle. Die Settings-UI zeigt je Tab nur die für die Entität sinnvollen Felder (z.B. Auto-Close/WC-Auto-Resolve nur bei Ticket). GET /api/lifecycle-config · PUT /api/lifecycle-config/:entityType

Restlaufzeit des Reopen-Fensters: GET /api/lifecycle-config/:entityType/reopen-window liefert reopenEnabled/Days/From und braucht nur eine Anmeldung. Die Detail-Seitenleiste zeigt die Restlaufzeit an. Die vollständige Config erfordert settings.editGeneral.

Auto-Close

Auto-Close schließt fällige Tickets zeitgesteuert wie ein normaler Statuswechsel (closedAt, SLA und Verlauf werden gesetzt). Auto-Close gibt es nur für Tickets (autoCloseEnabled, standardmäßig aus). Incidents und Problems werden immer von Hand geschlossen, weil dort eine Genehmigung bzw. ein PIR den Abschluss bestimmt.

AspektDetail
Joblifecycle_auto_close (täglich ~02:30)
FälligkeitGREATEST(resolvedAt, neueste nicht-interne Nachricht, config.updatedAt)
GraceDie Frist zählt frühestens ab dem Speichern der Config (config.updatedAt), damit beim ersten Aktivieren nicht der gesamte Altbestand auf einmal geschlossen wird.
VorwarnungautoCloseWarnDays → Notification TICKET_AUTO_CLOSE_WARNING (Kunde primär); Kundenantwort verschiebt die Fälligkeit → Re-Warn

WC-Auto-Resolve (Waiting-Customer)

Als Vor-Stufe zu Auto-Close: Tickets im Status WAITING_CUSTOMER, auf die der Kunde nicht reagiert, werden nach einer konfigurierten Frist automatisch auf RESOLVED gesetzt (danach greift ggf. der normale Auto-Close-Pfad). Nur TICKET, opt-in.

AspektDetail
Joblifecycle_wc_auto_resolve (täglich ~02:00)
Fälligkeitletzte nicht-interne (öffentliche) Nachricht — Kunde ODER Agent (Fallback updatedAt) + autoResolveWaitingDays (Default 14)
VorwarnungautoResolveWaitingWarnDays (Default 3) → TICKET_WC_RESOLVE_WARNING (Kunde primär)
Resolution-CodeautoResolveWaitingCode (Default AUTO_RESOLVED_NO_RESPONSEnotifyCustomer=false, EXCLUDE_FROM_REPORTING)
ResetKundenantwort → Status WAITING_SUPPORT + wcResolveWarnedAt=null (Timer startet neu)

Stale-Reminder (Inaktivität)

Inaktivitäts-Erinnerung für TICKET, PROBLEM und INCIDENT. Meldet zu lange unbewegte Vorgänge gestaffelt an Assignee (Stufe 1) → Gruppen-Lead (Stufe 2) → Manager (Stufe 3), jeweils nur an Personen mit Sicht auf den Vorgang. Ändert nie Status oder SLA.

  • Job: lifecycle_stale_entity_reminder (täglich ~01:30)
  • Config: staleReminderEnabled, staleReminderDaysTier1/2/3 (je Entität)
  • Notification: TICKET_STALE_REMINDER / PROBLEM_STALE_REMINDER / INCIDENT_STALE_REMINDER
  • Ausschlüsse: terminal + je Typ (Ticket: ON_HOLD/WAITING_CUSTOMER/SLA-paused/offener Incident-Link; Problem: ON_HOLD/WAITING_VENDOR; Incident: ON_HOLD/PENDING_CLOSURE)

Reopen-Eskalation

Wird eine Entität öfter als die konfigurierte Schwelle wiederöffnet (reopenCount ≥ reopenEscalationThreshold), werden die Verantwortlichen proaktiv alarmiert — ein Qualitätssignal. Empfänger sind der Assignee plus Gruppen-Lead/Manager, jeweils nur, wenn sie den Vorgang sehen dürfen (wie bei SLA- und Stale-Erinnerungen). Findet sich niemand Berechtigtes, läuft die Eskalation die Management-Kette hoch; findet sich auch dort niemand, wird der Audit-Eintrag REOPEN_ESCALATION_NO_RECIPIENT geschrieben.

  • Job: lifecycle_reopen_escalation (täglich ~03:00)
  • Schwelle: reopenEscalationThreshold (null = aus; opt-in je Entität)
  • Dedup: reopenEscalatedCount — erneute Eskalation erst bei jedem weiteren Reopen über der Schwelle
  • Notification: REOPEN_ESCALATION (intern, nicht customerFacing)

Notifications

TypEmpfängerHinweis
TICKET_REOPENEDAgent / Gruppe / Kunde / FollowerKunde erhält generische Variante OHNE internen Grund/Notiz (Redaction)
INCIDENT_REOPENEDAssignee / Gruppe / Reporterintern
PROBLEM_REOPENEDAgent / Gruppe / Reporterintern
TICKET_AUTO_CLOSE_WARNINGKunde primärVorwarnung vor Auto-Close
REOPEN_ESCALATIONAssignee + Lead/Manager (nur mit Sicht auf den Vorgang)intern, Qualitätssignal
TICKET_WC_RESOLVE_WARNINGKunde primärVorwarnung vor WC-Auto-Resolve
TICKET_STALE_REMINDER · PROBLEM_STALE_REMINDER · INCIDENT_STALE_REMINDERAssignee → Lead → Manager (nur mit Sicht auf den Vorgang)intern, Inaktivitäts-Eskalation

Keine doppelte Benachrichtigung: Ein Reopen ist auch ein Statuswechsel. Empfänger erhalten dafür nur die Benachrichtigung *_REOPENED, nicht zusätzlich die allgemeine Statuswechsel-Benachrichtigung. Verlinkte Vorgänge werden über das Cascading-System informiert (LINKED_*_REOPENED). Cascading System

Felder & Analytics

Jede Entität trägt closedAt, reopenCount, reopenedAt und lastReopenReasonCode. Jeder Reopen erzeugt einen sichtbaren REOPENED-Timeline-Eintrag (Grund + Notiz) und ein Audit-Event. Daraus speist sich die Reopen-Analytik:

EndpointRechtZweck
GET /api/analytics/reopenreports.viewAll | viewTeamKPI über alle 3 Typen: everClosed/reopened/reopenRate/cumulativeReopens/Top-Gründe
GET /api/analytics/reopen/detailreports.viewAll | viewTeamZeitraum + Breakdown je Agent/Gruppe/Kategorie + Monats-Trend

In der UI: das Lifecycle-Dashboard unter /lifecycle-analytics (Reporting-Navigation) mit Entity-Tabs, Zeitraum, Summary-Cards, Trend und Ranked-Breakdowns; zusätzlich ein kompaktes Widget zur Reopen-Rate auf dem Haupt-Dashboard.

Verwandte Dokumentation