Volver a la wiki

Tarea Huey: Abrir incidencia ITSM por veredicto de drift (open_integrity_drift_ticket)

Tarea Huey: Abrir incidencia ITSM por veredicto de drift (open_integrity_drift_ticket)\n\nArchivo: racks/tasks.py \nDecorador: @db_task() \nIntroducido: v1.61.0 (2026-07-17)\n\n## Propósito\n\nEncola la creación de una incidencia AIInsight documentacional en background cuando un usuario emite veredicto “Real change” en la Barra de Integridad.\n\nRationale: La llamada al proveedor de IA y recomputo del contexto del sujeto pueden tomar segundos. No caben en el request HTTP del usuario (que debe ser <100ms). El campo itsm en la respuesta del endpoint dice {\"queued\": true} siempre que el target exista; la tarea corre en background.\n\n## Signature\n\npython\n@db_task()\ndef open_integrity_drift_ticket(ack_id):\n \"\"\"F3: veredicto \"Real change\" → incidencia CNS/ITSM con la explicación de la IA.\n\n Fuera del request a propósito: recomputa la evidencia fresca del sujeto y\n llama al proveedor de IA (segundos). Best-effort — si falla (rate limit,\n proveedor caído), el aviso sigue viviendo en la cola del radar.\n \"\"\"\n\n\n## Parámetro\n\n| Parámetro | Tipo | Descripción |\n|-----------|------|-------------|\n| ack_id | int | ID del IntegrityAck a procesar. |\n\n## Flujo\n\npython\n@db_task()\ndef open_integrity_drift_ticket(ack_id):\n from racks.services import integrity_itsm\n\n try:\n insight_id = integrity_itsm.open_drift_ticket(ack_id)\n if insight_id:\n logger.info(f\"[integrity] drift ticket {insight_id} for ack {ack_id}\")\n except Exception:\n logger.exception(f\"[integrity] drift ticket failed for ack {ack_id}\")\n\n\n### 1. Importa el servicio\n\npython\nfrom racks.services import integrity_itsm\n\n\n### 2. Llama open_drift_ticket(ack_id)\n\nResponsabilidades del servicio:\n- Load ack con select_related para evitar SynchronousOnlyOperation.\n- Validar que siga siendo “real_change”.\n- Resolver MonitoringTarget (devuelve None si no hay).\n- Recomputar contexto fresco del sujeto.\n- Llamar a create_drift_insight() (async → async_to_sync).\n- Vincular ack.insight = insight y guardar.\n- Log.\n\nRetorno: int (insight.id) o None (sin target).\n\n### 3. Log de éxito\n\npython\nif insight_id:\n logger.info(f\"[integrity] drift ticket {insight_id} for ack {ack_id}\")\n\n\n### 4. Manejo de errores (best-effort)\n\npython\nexcept Exception:\n logger.exception(f\"[integrity] drift ticket failed for ack {ack_id}\")\n\n\nSi falla:\n- Rate limit: Se loguea warning, el ticket no se abre pero el ack sigue existiendo.\n- Proveedor caído: Fallback automático a “static” rules en create_drift_insight.\n- DB error: Se loguea exception.\n\nEl aviso de integrity sigue viviendo en la cola del radar en cualquier caso. No hay retry automático; el reintento es manual o vía scheduled task.\n\n## Invocación\n\nDesde racks/api/integrity.ack_finding() (POST /api/racks/integrity/ack):\n\npython\nif data.verdict == integrity.VERDICT_REAL_CHANGE:\n if resolve_ticket_target(org, device=device, profile=profile):\n open_integrity_drift_ticket(ack.id) # ← Encola\n itsm = {\"queued\": True}\n else:\n itsm = {\"queued\": False, \"reason\": \"subject has no monitoring target\"}\n\n\nComportamiento:\n- Inmediato (HUEY.immediate=True en tests): La tarea corre inline, el ticket está creado al retornar el endpoint.\n- En producción (HUEY.immediate=False): La tarea se encola, el endpoint retorna rápido, la tarea corre en segundos.\n\n## Dependencias\n\n- racks.services.integrity_itsm.open_drift_ticket()\n- monitoring.services.insight_service.create_drift_insight() (async)\n- monitoring.models_insight.AIInsight (modelo)\n- Proveedor IA (default: “static”, fallback automático si falla otro).\n\n## Logging\n\nTodos los eventos clave se loguean con prefijo [integrity]:\n\n\n[integrity] drift ticket 42 for ack 10\n[integrity] drift ticket failed for ack 10: rate_limit_exceeded\n[integrity] no drift ticket for ack 11: subject has no monitoring target\n\n\n## Testing\n\nHUEY.immediate en settings de test → la tarea corre inline.\n\nCubierto por 2 de 8 tests:\n- ✅ Tarea abre ticket y vincula al ack.\n- ✅ Idempotencia: si ack ya tiene insight, no abre otro.\n\n## Errores esperados\n\n| Error | Causas | Acción |\n|-------|--------|--------|\n| Rate limit | Demasiadas incidencias en el target en poco tiempo. | Log warning, no se abre ticket. |\n| Proveedor IA caído | Endpoint /analyze_incident no responde. | Fallback a “static” rules (determinista, sin IA). |\n| Ack no existe | ID inválido o fue eliminado. | Se loguea, no falla. |\n| Ack no es real_change | Veredicto cambió o fue alterado. | Se loguea, no se abre ticket. |\n| DB error | Fallo en SELECT/UPDATE del ack. | Log exception, el ticket no se vincula. |\n\n## Mejoras futuras\n\n- Retry automático: Si falla, reintentar N veces con backoff exponencial.\n- Webhook a Observatory: Notificar usuario cuando el ticket esté listo.\n- Bulking: Agrupar múltiples acks del mismo sujeto (evitar tickets duplicados por mismo problema).\n\n

Véase también

Subir