Problems API
Die Problems API verwaltet IT-Probleme nach ITIL: Root-Cause-Analyse, Workaround-Dokumentation, eine Known-Error-Database mit automatischem Matching auf Tickets, Status mit SLA-Pause (ON_HOLD/WAITING_VENDOR), Verknüpfung mit anderen Vorgängen über die Entity-Linking API und das gemeinsame Schließen verknüpfter Tickets und Incidents (Cascading Close).
Endpoints Übersicht
| Method | Endpoint | Beschreibung |
|---|---|---|
GET | /api/problems | Alle Problems (RBAC-gefiltert, { data, pagination }); ?deleted=1 = Papierkorb |
GET | /api/problems/stats | Counts pro Status |
GET | /api/problems/:id | Einzelnes Problem (per ID oder Nummer) |
GET | /api/problems/:id/unified-timeline | Aggregierte Timeline (Problem + verlinkte Tickets/Incidents) |
GET | /api/problems/:id/impact-tree | Voller Downstream-Impact (Tickets + Incidents + SLA + Access) |
POST | /api/problems | Neues Problem erstellen |
POST | /api/problems/from-incidents | Problem aus mehreren Incidents (oder PIR) erstellen + Auto-Link |
PATCH | /api/problems/:id | Problem aktualisieren (inkl. Status/Assignment) |
DELETE | /api/problems/:id | Problem löschen (Soft-Delete, kritische Aktion) |
POST | /api/problems/:id/restore | Gelöschtes Problem wiederherstellen → 204 (verlangt problems.restore UND problems.viewDeleted) |
POST | /api/problems/:id/timeline | Timeline-Eintrag/Notiz hinzufügen → 201 mit dem angelegten Eintrag |
KEDB: Den Known-Error-Vorschlag für ein Ticket liefert die Tickets API:
GET /api/tickets/:id/suggest-known-errors(erfordertproblems.viewOwn). Siehe Abschnitt Known Error Database unten.
Problem-Kategorien (CRUD)
| Method | Endpoint | Permission |
|---|---|---|
GET | /api/problems/categories | problems.view* ODER settings.manageCategories |
POST | /api/problems/categories | settings.manageCategories |
PUT | /api/problems/categories/:id | settings.manageCategories |
DELETE | /api/problems/categories/:id | settings.manageCategories |
Kategorie-Felder: name (1-50), description (≤200), color (#RRGGBB), isActive.
Status-Maschine
Problems haben 8 Status. Enum-Werte werden in Großschreibung gesendet und geliefert; kleingeschriebene Werte ergeben 400. Der Status wird per PATCH /:id gesetzt und erfordert problems.changeStatus. Das Wiederöffnen eines terminalen Problems (CLOSED/RESOLVED → INVESTIGATING) läuft ebenfalls über PATCH /:id, erfordert aber das eigene Recht problems.reopen und einen reopenReason (optional reopenNote).
NEW → INVESTIGATING → IDENTIFIED → WORKAROUND → RESOLVED → CLOSED
↕
ON_HOLD / WAITING_VENDOR (SLA pausiert)
• NEW = Erkannt, noch nicht untersucht
• INVESTIGATING = Root-Cause-Analyse läuft
• IDENTIFIED = Root-Cause bekannt (Known Error)
• WORKAROUND = Workaround verfügbar
• ON_HOLD = SLA pausiert — wartet auf interne Entscheidung
• WAITING_VENDOR = SLA pausiert — wartet auf externe Analyse
• RESOLVED = Permanent gelöst (z.B. via Change)
• CLOSED = Geschlossen & archiviert
Problem erstellen
Request
POST /api/problems
Eingabe-Konvention: priority und businessImpact werden in Großschreibung übergeben (LOW, MEDIUM, HIGH, CRITICAL); kleingeschriebene Werte ergeben 400. reporter wird bei User-Auth automatisch auf den eingeloggten User gesetzt; bei API-Key-Auth ist reporterId im Body Pflicht.
{
"title": "Database performance degradation during peak hours",
"description": "Multiple incidents reported slow database queries between 9-11 AM over 5 days.",
"categoryId": "clx-performance-category",
"priority": "HIGH",
"businessImpact": "HIGH",
"impactDescription": "500+ users experience slow response times during peak hours",
"affectedUsers": 500,
"affectedServices": ["Database", "API", "Reporting"],
"symptoms": ["Query time +300%", "Connection pool exhaustion", "API timeouts"],
"assignedGroupId": "clx-db-team-group",
"tags": ["performance", "database", "peak-hours"]
}
Response (201 Created)
{
"id": "clx...",
"problemNumber": "PRB-2026-000015",
"title": "Database performance degradation during peak hours",
"status": "NEW",
"priority": "HIGH",
"businessImpact": "HIGH",
"category": { "id": "clx...", "name": "Performance", "color": "#f59e0b" },
"reporter": { "id": "clx...", "name": "John Doe", "email": "john@example.com" },
"assignedGroup": { "id": "clx...", "name": "Database Team" },
"affectedServices": ["Database", "API", "Reporting"],
"symptoms": ["Query time +300%", "..."],
"createdAt": "2026-01-27T16:00:00.000Z"
}
Felder
| Feld | Typ | Pflicht? | Beschreibung |
|---|---|---|---|
title | string | ✓ | Kurztitel |
description | string | ✓ | Beschreibung |
categoryId | string | ✓ | Kategorie (ID, Pflicht) |
priority | enum | ✓ | LOW, MEDIUM, HIGH, CRITICAL |
businessImpact | enum | ✓ | LOW, MEDIUM, HIGH, CRITICAL |
impactDescription | string | ✓ | Beschreibung des Business-Impacts |
affectedUsers | number | ✓ | Anzahl betroffener User (≥0) |
reporterId | string | (API-Key) | Bei User-Auth automatisch; bei API-Key Pflicht |
status | enum | Abweichung von NEW erfordert problems.changeStatus | |
assignedToId / assignedGroupId | string | Person oder Gruppe; Zuweisung erfordert problems.assign | |
affectedServices / symptoms / tags | string[] | Arrays | |
workaround / rootCause / resolution | string | RCA-Felder |
Aus Incidents erstellen (Problem from Incidents / PIR)
POST /api/problems/from-incidents
Erstellt ein Problem aus mehreren ausgewählten Incidents, verlinkt alle automatisch und schreibt Aktivitäten auf beiden Seiten. Erfordert problems.create UND incidents.linkToProblems.
{
"incidentIds": ["clx-inc-1", "clx-inc-2"],
"title": "Recurring database performance pattern",
"description": "Five incidents over two weeks with identical symptoms.",
"categoryId": "clx-performance-category",
"priority": "HIGH",
"businessImpact": "HIGH",
"impactDescription": "Peak-hour degradation across multiple services",
"affectedUsers": 500,
"originType": "FROM_INCIDENTS"
}
originType: FROM_INCIDENTS (Standard) oder FROM_PIR (Post-Incident-Review aus einem Major Incident). Betroffene Incident-Agents erhalten eine Notification (PROBLEM_CREATED_FROM_INCIDENTS / _PIR).
Known Error Database (KEDB)
Ein Problem mit dokumentierter rootCause und/oder workaround (typisch Status IDENTIFIED oder WORKAROUND) ist ein „Known Error". Eviworx matcht Known Errors automatisch — KEINE manuelle Verschlagwortung nötig:
| Richtung | Auslöser | Verhalten |
|---|---|---|
| Ticket → Known Errors | GET /api/tickets/:id/suggest-known-errors |
Schlägt passende Known Errors zum Ticket vor (mit relevanceScore) |
| Workaround → Tickets | Workaround am Problem hinterlegt | Findet offene Tickets mit zugewiesenem Agent und sendet KNOWN_ERROR_SUGGESTION |
Das Matching kombiniert Volltextsuche, eine tippfehlertolerante Ähnlichkeitssuche und den Kategorie-Abgleich und funktioniert für deutsche wie englische Texte. Zusätzlich können KB-Artikel am Problem verlinkt werden (linkedArticles) für Self-Service-Dokumentation.
// GET /api/tickets/:id/suggest-known-errors
[
{
"problemId": "clx...",
"problemNumber": "PRB-2026-000015",
"title": "Database performance degradation during peak hours",
"status": "WORKAROUND",
"workaround": "Daily VACUUM ANALYZE at 6 AM",
"relevanceScore": 0.87
}
]
Root-Cause-Analyse-Workflow
Alle Schritte laufen über PATCH /api/problems/:id (Statuswechsel: problems.changeStatus). Beispiel:
# 1. Start investigation
PATCH /api/problems/:id { "status": "INVESTIGATING" }
# 2. Record root cause (Known Error)
PATCH /api/problems/:id { "status": "IDENTIFIED",
"rootCause": "Missing index on tickets.createdAt (500k+ rows → full table scans)" }
# 3. Document workaround → matches open tickets, sends KNOWN_ERROR_SUGGESTION
PATCH /api/problems/:id { "status": "WORKAROUND",
"workaround": "Daily VACUUM ANALYZE at 6 AM. 80% fewer timeouts." }
# 4. Permanent solution: link the change, then resolve
POST /api/linking/problems/:id/link-change { "changeId": "clx-change-id" }
PATCH /api/problems/:id { "status": "RESOLVED",
"resolution": "Index added via CHG-2026-000042. Query times back to <500ms.",
"resolutionCode": "FIXED_BY_CHANGE" }
# 5. Close (checks linked tickets/incidents → cascading close)
PATCH /api/problems/:id { "status": "CLOSED", "confirmPartialClose": true }
Timeline-Einträge
POST /api/problems/:id/timeline
{
"type": "investigation",
"message": "Analyzed slow query logs. Found missing index on large table."
}
type(Pflicht — nur general, investigation, workaround, resolution; ein anderer Wert ist 400) undmessage(Pflicht) — weitere Felder nimmt die Route nicht an. Die Antwort ist der angelegte Eintrag; System-Aktivitäten (Statuswechsel usw.) schreibt der Server selbst; sie haben eigene Typen.- Konversations-Typen general / investigation / workaround / resolution lösen eine Benachrichtigung an Assignee/Gruppe aus.
- Ein geschlossenes Problem nimmt keine Notizen an (400 PROBLEM_ALREADY_CLOSED); zuerst wiedereröffnen.
- Recht: problems.addTimeline ODER Edit-Recht auf dieses Problem; vorab wird die Sichtbarkeit geprüft.
Problem aktualisieren
PATCH /api/problems/:id
Partielles Update. Editier-Autorität: problems.editAll ODER (problems.editOwn als Reporter/Assignee). Zusätzliche Rechte je Feld: jeder Statuswechsel → problems.changeStatus; (Re)Assignment inkl. Unassign → problems.assign. Optimistic Locking über version (Konflikt → 409).
- Aktualisierbar:
title,description,status,priority,categoryId,businessImpact,impactDescription,affectedUsers,assignedToId,assignedGroupId,symptoms,affectedServices,tags,rootCause,workaround,resolution,resolutionCode,linkedChangeIds,resolvedAt,closedAt,version confirmPartialClose– Schließen bestätigen, auch wenn einige verlinkte Tickets durch Mailbox-Rechte nicht schließbar sind
Impact Tree, Cascading Close & Unified Timeline
GET /:id/impact-tree– Direkte Tickets + verlinkte Incidents (mit deren Tickets, 2-Hop) + SLA-Info + Access-Checks. Basis für den Close-Dialog.GET /:id/unified-timeline– Aggregiert eigene Timeline + Aktivitäten verlinkter Tickets + Incidents (limit/offset).
Beim Schließen eines Problems werden zugängliche verlinkte Tickets/Incidents kaskadierend mitgeschlossen; das Ergebnis steht als cascadingClose im Update-Response.
Linking zu anderen Entities
Problems werden mit Incidents, Changes, Tickets, Assets und KB-Artikeln verknüpft. Das Verlinken selbst ist in einer zentralen Linking-Domain (/api/linking) gebündelt; die Verlinkungen erscheinen im Problem als tickets, linkedIncidents, linkedChanges, linkedAssets und linkedArticles. (Changes können zusätzlich direkt per PATCH linkedChangeIds gesetzt werden.)
Statistiken
GET /api/problems/stats
Liefert Counts pro Status (RBAC-gefiltert nach viewAll/viewOwn) für die Übersichts-Karten.
Problem löschen
DELETE /api/problems/:id → 204 No Content
Soft-Delete, kritische Aktion (problems.delete, wird auditiert; ein Entzug des Rechts wirkt sofort). Ein Problem mit aktiven Verknüpfungen zu Tickets, Changes oder KB-Artikeln kann nicht gelöscht werden (400 PROBLEM_HAS_ACTIVE_LINKS); diese Links zuerst entfernen. Verknüpfte Incidents blockieren das Löschen nicht. Löschen und Wiederherstellen prüfen außerdem die Sicht auf das Problem: Wer es nicht sehen darf, erhält 404, damit nicht erkennbar ist, ob es existiert. Wiederherstellen über POST /:id/restore erfordert problems.restore und zusätzlich problems.viewDeleted.
Liste & Filter
GET /api/problems?f.status=INVESTIGATING&f.priority=HIGH&page=1&per=20
RBAC-gefiltert (viewAll/viewOwn). Antwort:
{
"data": [ /* problems */ ],
"pagination": { "page": 1, "limit": 20, "total": 137, "totalPages": 7, "hasMore": true }
}
| Parameter | Beschreibung |
|---|---|
f.status, f.priority, f.categoryId, f.assignedToId | Filter (Enum-Werte in Großschreibung) |
q | Volltextsuche über Titel, Beschreibung und rootCause |
page / per / sort | Seitenweise Ausgabe (per Standard 50, serverseitig begrenzt) |
deleted=1 | Papierkorb: NUR gelöschte Problems (erfordert problems.viewDeleted) |
includeDeleted=true | Mischliste inkl. gelöschter (erfordert problems.viewDeleted) |
Problem vs. Incident
| Aspekt | Incident | Problem |
|---|---|---|
| Zweck | Störung schnell beheben | Root-Cause finden & präventiv lösen |
| SLA | ✓ Response/Resolution-Timer | Pause-Status (ON_HOLD/WAITING_VENDOR) |
| Timeline | Activity-Log | ✓ Investigation-Timeline + Unified Timeline |
| Known Error | — | ✓ rootCause/workaround + KEDB-Matching |
- ✓ Status via PATCH (problems.changeStatus)
- ✓ KEDB-Matching (Volltext + Fuzzy)
- ✓ SLA-Pause: ON_HOLD / WAITING_VENDOR
- ✓ Impact-Tree + Cascading Close
- ✓ Optimistic Locking (version)
problems.viewAll/viewOwn/viewDeletedproblems.create/editAll/editOwnproblems.assign/changeStatus/addTimelineproblems.delete/restoreincidents.linkToProblems(from-incidents),settings.manageCategories
Auth-/Rollenmodell: Permissions & RBAC
- Incidents API – from-incidents, Cascading, Major Incident → PIR
- Changes API – permanente Lösung verlinken
- Entity-Linking API – zentrale Verknüpfung, Batch-Resolve, Impact Tree
- Notification-System – KNOWN_ERROR_SUGGESTION, PROBLEM_*
- Reopen & Lifecycle – problems.reopen, Reopen-Gründe, PROBLEM_REOPENED