refactor(backend/api): extract Incident services (Step 4 — file 11 of 18)

compliance/api/incident_routes.py (916 LOC) -> 280 LOC thin routes +
two services + 95-line schemas file.

Two-service split for DSGVO Art. 33/34 Datenpannen-Management:

  incident_service.py (460 LOC):
    - CRUD (create, list, get, update, delete)
    - Stats, status update, timeline append, close
    - Module-level helpers: _calculate_risk_level, _is_notification_required,
      _calculate_72h_deadline, _incident_to_response, _measure_to_response,
      _parse_jsonb, _append_timeline, DEFAULT_TENANT_ID

  incident_workflow_service.py (329 LOC):
    - Risk assessment (likelihood x impact -> risk_level)
    - Art. 33 authority notification (with 72h deadline tracking)
    - Art. 34 data subject notification
    - Corrective measures CRUD

Both services use raw SQL via sqlalchemy.text() — no ORM models for
incident_incidents / incident_measures tables. Migrated from the Go
ai-compliance-sdk; Python backend is Source of Truth.

Legacy test compat: tests/test_incident_routes.py imports
_calculate_risk_level, _is_notification_required, _calculate_72h_deadline,
_incident_to_response, _measure_to_response, _parse_jsonb,
DEFAULT_TENANT_ID directly from compliance.api.incident_routes — all
re-exported via __all__.

Verified:
  - 223/223 pytest pass (173 core + 50 incident)
  - OpenAPI 360/484 unchanged
  - mypy compliance/ -> Success on 141 source files
  - incident_routes.py 916 -> 280 LOC
  - Hard-cap violations: 8 -> 7

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sharang Parnerkar
2026-04-09 08:35:57 +02:00
parent 0c2e03f294
commit cc1c61947d
6 changed files with 1292 additions and 982 deletions

View File

@@ -19563,218 +19563,6 @@
"title": "ConsentCreate",
"type": "object"
},
"compliance__api__incident_routes__IncidentCreate": {
"properties": {
"affected_data_categories": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Affected Data Categories"
},
"affected_data_subject_count": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": 0,
"title": "Affected Data Subject Count"
},
"affected_systems": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Affected Systems"
},
"category": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": "data_breach",
"title": "Category"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description"
},
"detected_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Detected At"
},
"severity": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": "medium",
"title": "Severity"
},
"title": {
"title": "Title",
"type": "string"
}
},
"required": [
"title"
],
"title": "IncidentCreate",
"type": "object"
},
"compliance__api__incident_routes__IncidentUpdate": {
"properties": {
"affected_data_categories": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Affected Data Categories"
},
"affected_data_subject_count": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Affected Data Subject Count"
},
"affected_systems": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Affected Systems"
},
"category": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Category"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description"
},
"severity": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Severity"
},
"status": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Status"
},
"title": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Title"
}
},
"title": "IncidentUpdate",
"type": "object"
},
"compliance__api__incident_routes__StatusUpdate": {
"properties": {
"status": {
"title": "Status",
"type": "string"
}
},
"required": [
"status"
],
"title": "StatusUpdate",
"type": "object"
},
"compliance__api__legal_document_routes__VersionCreate": {
"properties": {
"content": {
@@ -20361,6 +20149,218 @@
},
"title": "VersionUpdate",
"type": "object"
},
"compliance__schemas__incident__IncidentCreate": {
"properties": {
"affected_data_categories": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Affected Data Categories"
},
"affected_data_subject_count": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": 0,
"title": "Affected Data Subject Count"
},
"affected_systems": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Affected Systems"
},
"category": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": "data_breach",
"title": "Category"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description"
},
"detected_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Detected At"
},
"severity": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": "medium",
"title": "Severity"
},
"title": {
"title": "Title",
"type": "string"
}
},
"required": [
"title"
],
"title": "IncidentCreate",
"type": "object"
},
"compliance__schemas__incident__IncidentUpdate": {
"properties": {
"affected_data_categories": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Affected Data Categories"
},
"affected_data_subject_count": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Affected Data Subject Count"
},
"affected_systems": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Affected Systems"
},
"category": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Category"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description"
},
"severity": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Severity"
},
"status": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Status"
},
"title": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Title"
}
},
"title": "IncidentUpdate",
"type": "object"
},
"compliance__schemas__incident__StatusUpdate": {
"properties": {
"status": {
"title": "Status",
"type": "string"
}
},
"required": [
"status"
],
"title": "StatusUpdate",
"type": "object"
}
}
},
@@ -30056,7 +30056,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response List Incidents Api Compliance Incidents Get",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -30118,7 +30122,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/compliance__api__incident_routes__IncidentCreate"
"$ref": "#/components/schemas/compliance__schemas__incident__IncidentCreate"
}
}
},
@@ -30128,7 +30132,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response Create Incident Api Compliance Incidents Post",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -30176,7 +30184,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response Get Stats Api Compliance Incidents Stats Get",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -30218,7 +30230,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response Delete Incident Api Compliance Incidents Incident Id Delete",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -30258,7 +30274,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response Get Incident Api Compliance Incidents Incident Id Get",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -30298,7 +30318,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/compliance__api__incident_routes__IncidentUpdate"
"$ref": "#/components/schemas/compliance__schemas__incident__IncidentUpdate"
}
}
},
@@ -30308,7 +30328,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response Update Incident Api Compliance Incidents Incident Id Put",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -30376,7 +30400,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response Assess Risk Api Compliance Incidents Incident Id Assess Risk Post",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -30444,7 +30472,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response Close Incident Api Compliance Incidents Incident Id Close Post",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -30512,7 +30544,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response Add Measure Api Compliance Incidents Incident Id Measures Post",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -30574,7 +30610,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response Update Measure Api Compliance Incidents Incident Id Measures Measure Id Put",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -30626,7 +30666,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response Complete Measure Api Compliance Incidents Incident Id Measures Measure Id Complete Post",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -30694,7 +30738,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response Notify Authority Api Compliance Incidents Incident Id Notify Authority Post",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -30762,7 +30810,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response Notify Subjects Api Compliance Incidents Incident Id Notify Subjects Post",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -30820,7 +30872,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/compliance__api__incident_routes__StatusUpdate"
"$ref": "#/components/schemas/compliance__schemas__incident__StatusUpdate"
}
}
},
@@ -30830,7 +30882,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response Update Status Api Compliance Incidents Incident Id Status Put",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -30898,7 +30954,11 @@
"200": {
"content": {
"application/json": {
"schema": {}
"schema": {
"additionalProperties": true,
"title": "Response Add Timeline Entry Api Compliance Incidents Incident Id Timeline Post",
"type": "object"
}
}
},
"description": "Successful Response"
@@ -35673,7 +35733,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/compliance__api__incident_routes__StatusUpdate"
"$ref": "#/components/schemas/compliance__schemas__incident__StatusUpdate"
}
}
},