---
module: incident.incident-management
title: Incident Management
tab: Architect
order: 30
audience: dev
---

> How the Incident Management screen is built. Owner service: **hiveops-incident**. See [platform.service-ownership], [platform.data-architecture], [platform.kafka].

## Shape

- **Frontend:** `hiveops-incident/frontend` — `components/Incident/IncidentList/IncidentList.svelte` (the Active/Parked grid, filters, bulk actions, link/group, fraud-close modal). API client `lib/api.ts` (`incidentAPI`, `journalEventAPI`, `helpdeskPersonAPI`), base `/api`.
- **Backend:** `hiveops-incident` (Spring Boot, port **8080**, NGINX `/api/incident/`). Two controllers back this screen:
  - `IncidentController` — `@RequestMapping("/api/incidents")` — reads/CRUD (`/paginated`, `/status/open`, `/severity/critical`, `/atm|device/{id}`).
  - `IncidentManagementController` — `@RequestMapping("/api/incident-management")` — workflow: assign, transition, notes, bulk, link/group, stats.
- **Database:** `hiveiq_incident` (Postgres) via **`DB_URL`** full JDBC URL; Flyway `validate`.

## Data it reads/writes

| Table / entity | Role in this feature |
|----------------|----------------------|
| `incidents` (`Incident`) | primary record — type, severity, status, assignment, timestamps |
| `incident_events` | audit stream (`IncidentEventService.record`, e.g. `STATUS_CHANGED`) |
| `incident_notes` / notes on the entity | free-text notes added via `/notes` and workflow transitions |
| `workflow_transitions` | valid status-edge definitions consulted by `workflowStateService` |
| `technicians`, `helpdesk_persons` | assignment targets |
| `atms` (`Atm`) | device the incident belongs to |
| `device_summary` | Kafka-fed mirror of device metadata (name/institution shown on rows) |
| `incident_embeddings` | Adoons/AI indexing of incidents |

## Workflow transition flow

`POST /api/incident-management/{id}/transition` (admin-gated):
1. Load incident, resolve `WorkflowTransition` for `(currentStatus → newStatus)`; reject 400 if no edge.
2. If `transition.requiresAssignment` and no assignee → 400.
3. `assertNoUnfixedChildren()` blocks closing a primary with unfixed linked children.
4. Mutate status; set `resolvedAt`/`actualResolutionTime` on RESOLVED, `closedAt` on CLOSED.
5. Append a note, record an `incident_events` `STATUS_CHANGED` row, re-index for Adoons.
6. Broadcast STOMP `/topic/incidents/status-changed` for live UI update.

`PARKED` is a first-class status: while any incident for a device is `PARKED`, `IncidentAutoCreationService` suppresses new auto-incidents for that device (#219).

## Kafka — incident lifecycle (producer side)

`IncidentLifecycleProducer` publishes on create and update (config `IncidentLifecycleKafkaConfig`, 3 partitions each):

| Topic | When |
|-------|------|
| `hiveops.incidents.created` | `publishCreated` — on incident create (`IncidentService:73`) |
| `hiveops.incidents.updated` | `publishUpdated` — non-resolved update (`IncidentService:189,433`) |
| `hiveops.incidents.resolved` | `publishUpdated` when status RESOLVED/CLOSED |

Downstream services (analytics, reports, messaging, etc.) consume these — this screen is the source of those events.

## Kafka — auto-creation (consumer side)

Incidents shown here are largely machine-generated. Consumers:

| Topic | Listener (group) | Effect |
|-------|------------------|--------|
| `hiveops.device.events` | `DeviceEventConsumer` (`hiveops-incident-device-sync`) | sync `device_summary`; `IncidentAutoCreationService` raises incidents from device events |
| `hiveops.aria.threats` | `AriaThreatEventConsumer` (`hiveops-incident-aria`) | raise incidents from ARIA threat events |
| `adoons.rule-suggestion.ready` | `RuleSuggestionResultConsumer` (`hiveops-incident-adoons`) | ingest completed Adoons rule suggestions |

Pattern: **executor/consumer → mutate incident → lifecycle producer → Kafka → downstream record stores**. The UI only ever sees the resulting `incidents` rows.

## Boundaries

- Agents do **not** hit this service directly. hiveops-agent-proxy calls incident `/api/internal/**` (secured by `X-Internal-Secret` → `ROLE_INTERNAL`) to ingest journal events / heartbeats that feed auto-creation. See [platform.service-ownership].
- Device master data is owned by **hiveops-devices**; incident holds a read-only `device_summary` mirror fed over Kafka — no reconciler, so publish-on-every-change is required upstream. See [platform.data-architecture].
- `JWT_SECRET` is shared with hiveops-auth / hiveops-mgmt; `mgmt.service.url` used for agent-token validation. See [platform.kafka] for bootstrap/topic conventions.
