diff --git a/src/models.py b/src/models.py index 769e78b..06ba553 100644 --- a/src/models.py +++ b/src/models.py @@ -62,6 +62,9 @@ class IncidentCreate(BaseModel): include_telegram: bool = False include_x: bool = False visibility: str = Field(default="public", pattern="^(public|private)$") + # KI-Weg dieser Lage (EU-Umbau). Leer/None = Vorgabe der Organisation + # bzw. globaler Default. 'cli' = Anthropic, 'bedrock' = EU (Frankfurt + staan). + ai_backend: Optional[str] = Field(default=None, pattern="^(cli|bedrock)$") class IncidentUpdate(BaseModel): @@ -77,6 +80,10 @@ class IncidentUpdate(BaseModel): include_telegram: Optional[bool] = None include_x: Optional[bool] = None visibility: Optional[str] = Field(default=None, pattern="^(public|private)$") + # KI-Weg. Leerstring "" setzt bewusst auf "Vorgabe der Organisation" zurueck, + # deshalb hier auch der Leerstring erlaubt (exclude_none im Router laesst + # None durchfallen, "" kommt an und wird zu NULL). + ai_backend: Optional[str] = Field(default=None, pattern="^(cli|bedrock|)$") class DescriptionEnhanceRequest(BaseModel): @@ -108,6 +115,7 @@ class IncidentResponse(BaseModel): international_sources: bool = True include_telegram: bool = False include_x: bool = False + ai_backend: Optional[str] = None created_by: int created_by_username: str = "" created_at: str @@ -137,6 +145,7 @@ class IncidentListItem(BaseModel): international_sources: bool = True include_telegram: bool = False include_x: bool = False + ai_backend: Optional[str] = None created_by: int created_by_username: str = "" created_at: str diff --git a/src/routers/incidents.py b/src/routers/incidents.py index dd32e98..1231480 100644 --- a/src/routers/incidents.py +++ b/src/routers/incidents.py @@ -22,6 +22,7 @@ router = APIRouter(prefix="/api/incidents", tags=["incidents"]) INCIDENT_UPDATE_COLUMNS = { "title", "description", "type", "status", "refresh_mode", "refresh_interval", "refresh_start_time", "retention_days", "international_sources", "include_telegram", "include_x", "visibility", + "ai_backend", } @@ -89,7 +90,7 @@ async def list_incidents( query = ( "SELECT id, title, description, type, status, refresh_mode, refresh_interval, " "refresh_start_time, retention_days, visibility, " - "international_sources, include_telegram, include_x, created_by, created_at, updated_at, " + "international_sources, include_telegram, include_x, ai_backend, created_by, created_at, updated_at, " "CASE WHEN summary IS NOT NULL AND summary != '' THEN 1 ELSE 0 END AS has_summary " "FROM incidents WHERE tenant_id = ? AND (visibility = 'public' OR created_by = ?)" ) @@ -121,8 +122,8 @@ async def create_incident( cursor = await db.execute( """INSERT INTO incidents (title, description, type, refresh_mode, refresh_interval, refresh_start_time, retention_days, international_sources, include_telegram, include_x, visibility, - tenant_id, created_by, created_at, updated_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", + ai_backend, tenant_id, created_by, created_at, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", ( data.title, data.description, @@ -135,6 +136,7 @@ async def create_incident( 1 if data.include_telegram else 0, 1 if data.include_x else 0, data.visibility, + data.ai_backend or None, tenant_id, current_user["id"], now, @@ -385,6 +387,9 @@ async def update_incident( continue if field in ("international_sources", "include_telegram", "include_x"): updates[field] = 1 if value else 0 + elif field == "ai_backend": + # Leerstring = "Vorgabe der Organisation", wird als NULL gespeichert. + updates[field] = value or None else: updates[field] = value diff --git a/src/static/css/style.css b/src/static/css/style.css index 45eaf7e..e5af820 100644 --- a/src/static/css/style.css +++ b/src/static/css/style.css @@ -6180,3 +6180,18 @@ body.tutorial-active .tutorial-cursor { .pipeline-block.status-active { box-shadow: var(--glow-accent); } .pipeline-stage.is-looping .pipeline-loop { animation: none !important; opacity: 1; } } + +/* EU-Kennzeichen in der Lagen-Kopfzeile (EU-Umbau) */ +.incident-eu-badge { + display: inline-flex; + align-items: center; + padding: 2px 8px; + border-radius: 999px; + font-size: 11px; + font-weight: 700; + letter-spacing: 0.5px; + background: rgba(16, 185, 129, 0.16); + color: #10B981; + flex-shrink: 0; +} +.incident-eu-badge[hidden] { display: none; } diff --git a/src/static/dashboard.html b/src/static/dashboard.html index c5135dd..1904b01 100644 --- a/src/static/dashboard.html +++ b/src/static/dashboard.html @@ -164,6 +164,7 @@

+
@@ -411,6 +412,14 @@
+
+ + +