← Volver al índice de anexos
Macrobloque 5a·Ejecución + Control·Anexo 31 / 40

Anexo 31 · Workflow + escalamiento

Etapa: Fases 8.3 y 8.4
DECK PARCIAL PENDIENTE

ANEXO 31

Workflow y escalamiento FARO

Este anexo corresponde a la Fase 8 — Ejecución, etapa “Workflow y escalamiento”. Es la capa donde FARO Connect controla que las acciones no queden solo creadas, sino que avancen, se acepten, se ejecuten, se validen, se escalen si se vencen y finalmente se cierren con evidencia.

Hasta el Anexo 30, FARO ya sabe:

qué acción crear,
quién es responsable,
quién aprueba,
quién consulta,
quién debe estar informado,
cuándo vence.

Ahora falta controlar:

¿La acción realmente avanza o queda dormida en el sistema?

Porque una empresa no falla solo por no decidir. Muchas veces falla porque decide… y después nadie sigue.


1. Objetivo del anexo

El objetivo del Anexo 31 — Workflow y escalamiento FARO es definir cómo FARO controla el ciclo completo de ejecución de una acción, alerta, tensión, diagnóstico o decisión.

Debe responder:

¿En qué estado está?
¿Quién la tiene?
¿La aceptó?
¿Está vencida?
¿Está bloqueada?
¿Quién debe aprobar?
¿Quién debe cargar evidencia?
¿Cuándo se escala?
¿A quién se escala?
¿Qué pasa si nadie responde?
¿Cómo se cierra?
¿Cómo se mide?

Ejemplo simple:

Acción:
Auditar descuentos mayores al 8%.

Responsable:
Gerente Comercial.

Vencimiento:
72 horas.

Workflow:
Created → Assigned → Accepted → In progress → Waiting evidence → Completed → Approved → Closed.

Escalamiento:
Si no acepta en 24 hs: alerta a Gerencia General.
Si vence en 72 hs: escalar a Dirección.
Si cierra sin evidencia: no permitir cierre.

Esto es lo que separa un sistema de dirección de una lista de tareas con traje.


2. Tesis del Anexo 31

La tesis es:

FARO Connect debe asegurar que la inteligencia se convierta en ejecución real.

La cadena completa hasta acá es muy potente:

Datos
→ KPIs
→ Señales
→ Reglas
→ Alertas
→ Tensiones
→ Diagnóstico
→ Confianza
→ Priorización
→ Recomendación
→ Action Guide
→ Acción
→ Responsable

Pero si la acción no avanza, todo queda en diagnóstico elegante.

Por eso FARO necesita workflow:

crear
asignar
aceptar
ejecutar
validar
aprobar
cerrar
medir
aprender

Y necesita escalamiento:

si no avanza,
si vence,
si falta evidencia,
si hay bloqueo,
si el responsable no responde,
si la prioridad es crítica.

Sin workflow, FARO informa. Con workflow, FARO dirige.


3. Qué es workflow FARO

Un workflow FARO es el circuito de estados, responsables, reglas, vencimientos y aprobaciones que una acción debe recorrer desde que nace hasta que se cierra.

Ejemplo:

Alerta:
Caja bajo mínimo.

Acción:
Actualizar plan de caja 7 días.

Workflow:
1. Se crea acción automática.
2. Se asigna a Finanzas.
3. Finanzas acepta.
4. Carga cashflow.
5. Dirección aprueba plan.
6. FARO mide caja proyectada.
7. Se cierra con evidencia.

Estructura conceptual:

{
  "workflow_code": "WF_FINANCE_CASH_001",
  "entity_type": "action",
  "entity_id": "ACT_001",
  "current_state": "in_progress",
  "responsible": "Finanzas",
  "approver": "Dirección",
  "due_date": "2026-05-30T18:00:00",
  "escalation_policy": "P1_CRITICAL",
  "evidence_required": true,
  "next_state": "waiting_approval"
}

4. Qué es escalamiento FARO

Escalamiento FARO es la regla que define qué pasa cuando una acción, alerta, diagnóstico o decisión no avanza como debería.

Ejemplos:

No aceptó acción.
No cargó evidencia.
Venció plazo.
Rechazó sin motivo.
Está bloqueada.
Es P1 y no tiene avance.
Falta aprobador.
Responsable sobrecargado.

Escalamiento no es castigo. Es gobierno.

Ejemplo:

Acción P1 vencida:
Escalar inmediatamente a Gerencia General y Dirección.

Acción P2 vencida 24 hs:
Escalar al responsable superior.

Acción sin responsable:
Escalar a FARO Admin / Gerencia General.

Acción sensible sin aprobación:
Bloquear cierre y notificar aprobador.

5. Diferencia entre workflow, tarea y escalamiento

Concepto Qué hace Ejemplo
Tarea / acción Lo que hay que hacer. Auditar descuentos.
Workflow Circuito que controla avance. Asignada → en proceso → aprobada → cerrada.
Escalamiento Qué pasa si no avanza. Vencida → Dirección.
Evidencia Prueba de ejecución. Informe cargado.
Cierre Validación final. Acción cerrada con evidencia y aprobación.

Una acción sin workflow se pierde. Un workflow sin escalamiento se vuelve decorativo. Un cierre sin evidencia es maquillaje. Y del caro.


6. Estados estándar del workflow FARO

Estado Significado
Created FARO creó la acción o evento.
Assigned Ya tiene responsable.
Pending acceptance Espera aceptación del responsable.
Accepted Responsable aceptó la acción.
Rejected Responsable la rechazó con motivo.
Reassigned Fue reasignada.
In progress Está en ejecución.
Waiting data Falta información.
Waiting evidence Falta evidencia.
Waiting approval Falta aprobación superior.
Blocked No puede avanzar por dependencia.
Escalated Fue escalada.
Completed El responsable marcó finalización.
Under review Aprobador revisa cierre.
Approved Aprobador validó.
Measured Se midió impacto.
Closed Cerrada correctamente.
Cancelled Cancelada con motivo.
Overdue Vencida.
Recurring Se repite periódicamente.

7. Ciclo de vida completo de una acción FARO

1. Evento origen
2. Acción generada
3. Responsable asignado
4. Responsable acepta
5. Acción inicia
6. Se ejecutan pasos
7. Se cargan evidencias
8. Se solicita aprobación si corresponde
9. Se valida cierre
10. Se mide impacto
11. Se actualiza FARO Score
12. Se aprende
13. Se cierra

Flujo visual:

Alert / Tension / Diagnosis
        ↓
Recommendation
        ↓
Action Guide
        ↓
Action created
        ↓
Assigned
        ↓
Accepted
        ↓
In progress
        ↓
Evidence uploaded
        ↓
Approval
        ↓
Measured
        ↓
Closed
        ↓
Learning

8. Reglas básicas del workflow FARO

8.1 Toda acción debe tener responsable

No puede existir acción P1/P2 sin responsable.

8.2 Toda acción debe tener vencimiento

Si no tiene vencimiento, no hay presión de ejecución.

8.3 Toda acción sensible debe tener aprobador

Comisiones, canjes, crédito, precios, RRHH y proveedores estratégicos requieren aprobación.

8.4 Toda acción debe tener evidencia

No se cierra por comentario informal.

8.5 Toda acción vencida debe escalar

El vencimiento sin consecuencia enseña a la organización que el sistema no importa.

8.6 Toda acción cerrada debe medirse si impacta KPI

Cerrar no es hacer. Hacer tampoco es lograr. FARO debe medir.

9. Motor de estados

Cada acción cambia de estado según eventos.

Código conceptual:

def cambiar_estado_accion(accion, nuevo_estado, usuario, motivo=None):
    estados_validos = [
        "created",
        "assigned",
        "pending_acceptance",
        "accepted",
        "rejected",
        "reassigned",
        "in_progress",
        "waiting_data",
        "waiting_evidence",
        "waiting_approval",
        "blocked",
        "escalated",
        "completed",
        "under_review",
        "approved",
        "measured",
        "closed",
        "cancelled",
        "overdue"
    ]

    if nuevo_estado not in estados_validos:
        raise ValueError("Estado no válido")

    return {
        "action_id": accion["action_id"],
        "previous_status": accion["status"],
        "new_status": nuevo_estado,
        "changed_by": usuario,
        "change_reason": motivo,
        "changed_at": "now()"
    }

10. Transiciones permitidas

No cualquier estado puede pasar a cualquier otro.

Estado actual Próximos estados permitidos
Created Assigned, Cancelled
Assigned Pending acceptance, Accepted, Reassigned
Pending acceptance Accepted, Rejected, Escalated
Accepted In progress, Waiting data
In progress Waiting evidence, Waiting approval, Blocked, Completed
Waiting data In progress, Blocked
Waiting evidence Completed, Blocked
Waiting approval Approved, Rejected, Reassigned
Blocked In progress, Reassigned, Escalated
Completed Under review, Measured
Under review Approved, Waiting evidence, Rejected
Approved Measured, Closed
Measured Closed
Overdue Escalated, Reassigned, Completed
Escalated In progress, Reassigned, Closed
Rejected Reassigned, Cancelled
Cancelled No sigue
Closed No sigue

Código:

def transicion_permitida(estado_actual, nuevo_estado):
    mapa = {
        "created": ["assigned", "cancelled"],
        "assigned": ["pending_acceptance", "accepted", "reassigned"],
        "pending_acceptance": ["accepted", "rejected", "escalated"],
        "accepted": ["in_progress", "waiting_data"],
        "in_progress": ["waiting_evidence", "waiting_approval", "blocked", "completed"],
        "waiting_data": ["in_progress", "blocked"],
        "waiting_evidence": ["completed", "blocked"],
        "waiting_approval": ["approved", "rejected", "reassigned"],
        "blocked": ["in_progress", "reassigned", "escalated"],
        "completed": ["under_review", "measured"],
        "under_review": ["approved", "waiting_evidence", "rejected"],
        "approved": ["measured", "closed"],
        "measured": ["closed"],
        "overdue": ["escalated", "reassigned", "completed"],
        "escalated": ["in_progress", "reassigned", "closed"],
        "rejected": ["reassigned", "cancelled"],
        "cancelled": [],
        "closed": []
    }

    return nuevo_estado in mapa.get(estado_actual, [])

11. Matriz de escalamiento por prioridad

Prioridad Primer aviso Escalamiento Escalamiento fuerte
P1 Inmediato Al vencer +24 hs vencida
P2 24 hs antes 24 hs vencida 72 hs vencida
P3 Al vencer 72 hs vencida 7 días vencida
P4 Resumen semanal 7 días vencida Comité mensual
P5 Observación Solo si recurrente No aplica

12. A quién escala FARO

Evento Escala a
Acción P1 vencida Dirección / Gerencia General
Acción P2 vencida Responsable superior
Acción P3 vencida Responsable de área
Acción sin responsable FARO Admin / Gerencia General
Acción rechazada sin motivo Responsable superior
Acción bloqueada Dueño de dependencia
Acción sensible sin aprobación Aprobador asignado
Evidencia incompleta Responsable + Aprobador
Tensión recurrente Comité de Dirección
Responsable sobrecargado Gerencia General

Código:

def determinar_escalamiento(accion):
    if accion.get("status") == "overdue":
        if accion["priority_level"] == "P1":
            return "Dirección / Gerencia General"
        if accion["priority_level"] == "P2":
            return "Responsable superior"
        if accion["priority_level"] == "P3":
            return "Responsable de área"

    if not accion.get("responsible_id"):
        return "FARO Admin / Gerencia General"

    if accion.get("status") == "blocked":
        return accion.get("dependency_owner", "Responsable superior")

    if accion.get("requires_approval") and not accion.get("approver_id"):
        return "Dirección"

    return None

13. Fórmula de riesgo de vencimiento

FARO puede anticipar si una acción probablemente se va a vencer.

Riesgo de vencimiento =
avance bajo × 30%
+ poco tiempo restante × 25%
+ responsable sobrecargado × 20%
+ acción bloqueada × 15%
+ prioridad alta × 10%

Código:

def riesgo_vencimiento(
    avance_bajo,
    poco_tiempo_restante,
    responsable_sobrecargado,
    accion_bloqueada,
    prioridad_alta
):
    return round(
        avance_bajo * 0.30 +
        poco_tiempo_restante * 0.25 +
        responsable_sobrecargado * 0.20 +
        accion_bloqueada * 0.15 +
        prioridad_alta * 0.10,
        2
    )

Lectura:

Score Riesgo
80-100 Alto
60-79 Medio-alto
40-59 Medio
<40 Bajo

14. SLA de acciones

FARO puede manejar SLA según prioridad.

Prioridad Tiempo para aceptar Tiempo para primer avance Tiempo de cierre recomendado
P1 2 hs 6 hs 24 hs
P2 8 hs 24 hs 48-72 hs
P3 24 hs 48 hs 7 días
P4 72 hs 7 días 15-30 días
P5 No aplica No aplica Observación

Código:

def sla_por_prioridad(priority):
    mapa = {
        "P1": {"accept_hours": 2, "first_progress_hours": 6, "close_hours": 24},
        "P2": {"accept_hours": 8, "first_progress_hours": 24, "close_hours": 72},
        "P3": {"accept_hours": 24, "first_progress_hours": 48, "close_hours": 168},
        "P4": {"accept_hours": 72, "first_progress_hours": 168, "close_hours": 720},
        "P5": {"accept_hours": None, "first_progress_hours": None, "close_hours": None}
    }

    return mapa.get(priority)

15. Reglas de aceptación

El responsable debe aceptar o rechazar la acción.

15.1 Si acepta

La acción pasa a estado Accepted.
Empieza a correr el SLA de primer avance.

Código:

def aceptar_accion(accion, usuario):
    return {
        "action_id": accion["action_id"],
        "status": "accepted",
        "accepted_by": usuario,
        "accepted_at": "now()"
    }

15.2 Si rechaza

Debe indicar motivo.

def rechazar_accion(accion, usuario, motivo, responsable_sugerido=None):
    if not motivo:
        raise ValueError("Debe indicar motivo de rechazo")

    return {
        "action_id": accion["action_id"],
        "status": "rejected",
        "rejected_by": usuario,
        "rejection_reason": motivo,
        "suggested_responsible": responsable_sugerido,
        "requires_reassignment": True
    }

Motivos posibles:

Responsable incorrecto.
Falta información.
Depende de otra área.
No corresponde al área.
Acción duplicada.
Requiere aprobación previa.

16. Reglas de bloqueo

Una acción puede bloquearse por:

falta de datos
falta de aprobación
dependencia de otra acción
responsable ausente
sistema no disponible
evidencia insuficiente
conflicto entre áreas
decisión pendiente

Ejemplo:

{
  "action_id": "ACT_001",
  "status": "blocked",
  "block_reason": "Falta costo unitario para calcular margen",
  "blocked_by": "ACT_DATA_COMPLETE_COSTS",
  "dependency_owner": "Compras"
}

Código:

def bloquear_accion(accion, motivo, bloqueada_por=None):
    return {
        "action_id": accion["action_id"],
        "status": "blocked",
        "block_reason": motivo,
        "blocked_by": bloqueada_por,
        "blocked_at": "now()"
    }

17. Dependencias de workflow

Algunas acciones dependen de otras.

Ejemplos:

No se puede revisar comisión si no está calculado el margen por vendedor.
No se puede aprobar canje sin valuación legal y financiera.
No se puede cerrar margen bajo si faltan costos.
No se puede emitir reposición si no se validó stock físico.

Código:

def verificar_dependencias(accion, acciones):
    pendientes = []

    for dep_id in accion.get("dependencies", []):
        dep = acciones.get(dep_id)

        if not dep or dep["status"] != "closed":
            pendientes.append(dep_id)

    return {
        "can_continue": len(pendientes) == 0,
        "pending_dependencies": pendientes
    }

18. Reglas de aprobación

Una acción puede requerir aprobación antes de ejecutarse o antes de cerrarse.

18.1 Aprobación antes de ejecutar

Ejemplos:

bloquear cliente
aceptar canje
cambiar comisión
cambiar política de crédito
subir precios masivamente

18.2 Aprobación antes de cerrar

Ejemplos:

plan de caja
política comercial
simulación de comisión
canje evaluado
diagnóstico estratégico

Código:

def requiere_aprobacion_workflow(accion):
    return accion.get("requires_approval", False)


def aprobar_accion(accion, aprobador, comentario=None):
    if not accion.get("requires_approval"):
        return None

    return {
        "action_id": accion["action_id"],
        "status": "approved",
        "approved_by": aprobador,
        "approval_comment": comentario,
        "approved_at": "now()"
    }

19. Workflow por tipo de acción

19.1 Acción operativa simple

Created
→ Assigned
→ Accepted
→ In progress
→ Completed
→ Closed

Ejemplo:

Actualizar stock físico.

19.2 Acción con evidencia

Created
→ Assigned
→ Accepted
→ In progress
→ Waiting evidence
→ Completed
→ Under review
→ Closed

Ejemplo:

Auditar descuentos.

19.3 Acción con aprobación

Created
→ Assigned
→ Accepted
→ In progress
→ Waiting approval
→ Approved
→ Completed
→ Closed

Ejemplo:

Modificar política de crédito.

19.4 Acción sensible

Created
→ Assigned
→ Accepted
→ Simulation required
→ Waiting approval
→ Approved / Rejected
→ Action plan
→ Measured
→ Closed

Ejemplo:

Cambiar comisión.
Aceptar canje.
Bloquear cliente.

20. Workflow de alertas

Una alerta también tiene workflow.

Detected
→ Open
→ Acknowledged
→ Assigned
→ Converted to action
→ In progress
→ Resolved
→ Closed

Regla:

Una alerta no se cierra solo porque fue vista.
Se cierra si se resolvió, se justificó o se convirtió en acción.

Código:

def cerrar_alerta(alerta):
    condiciones = [
        alerta.get("resolved", False),
        alerta.get("resolution_reason") is not None,
        alerta.get("evidence_complete", False)
    ]

    if all(condiciones):
        return {
            "alert_id": alerta["alert_id"],
            "status": "closed",
            "closed_at": "now()"
        }

    return {
        "status": "cannot_close",
        "reason": "Falta resolución, motivo o evidencia"
    }

21. Workflow de tensiones

Las tensiones requieren más gobierno porque son sistémicas.

Detected
→ Observed
→ Validated
→ Action plan required
→ Actions created
→ In progress
→ Measured
→ Resolved
→ Closed

Ejemplo:

Tensión:
Crecimiento no rentable.

Debe generar:
- auditoría descuentos,
- revisión comisión,
- plan cobranza,
- análisis margen.

Regla:

Una tensión no se cierra por cerrar una acción.
Se cierra cuando el patrón que la originó mejora o se justifica.

Código:

def puede_cerrar_tension(tension, acciones_relacionadas, kpis):
    acciones_cerradas = all(a["status"] == "closed" for a in acciones_relacionadas)
    kpis_mejoraron = all(k["improved"] for k in kpis)

    return acciones_cerradas and kpis_mejoraron

22. Workflow de diagnósticos

Detected
→ Reviewed
→ Validated
→ Recommendation generated
→ Action Guide generated
→ Actions created
→ Measured
→ Closed

Un diagnóstico puede cerrarse si:

se ejecutaron acciones,
se resolvió tensión,
mejoraron KPIs,
se validó evidencia,
o se descartó con motivo.

23. Workflow de recomendaciones

Suggested
→ Reviewed
→ Accepted / Rejected
→ Simulation required
→ Converted to Action Guide
→ Converted to Action
→ Measured
→ Closed

Regla:

Toda recomendación rechazada debe tener motivo.

Código:

def rechazar_recomendacion(recomendacion, usuario, motivo):
    if not motivo:
        raise ValueError("Debe indicar motivo")

    return {
        "recommendation_id": recomendacion["recommendation_id"],
        "status": "rejected",
        "rejected_by": usuario,
        "reason": motivo
    }

24. Workflow de simulaciones

Requested
→ Inputs validated
→ Scenario built
→ Simulation run
→ Results reviewed
→ Decision required
→ Approved / Rejected / Pilot
→ Converted to action
→ Measured against real result
→ Closed

Ejemplo:

Simular cambio de comisión:
No puede pasar a acción hasta que Dirección apruebe escenario.

25. Workflow de decisiones

FARO también debe controlar decisiones.

Decision drafted
→ Data attached
→ Simulation attached if required
→ Responsible assigned
→ Approval requested
→ Approved / Rejected / Deferred
→ Actions created
→ Follow-up
→ Measured
→ Closed

Una decisión sin acciones asociadas debe generar alerta:

def alerta_decision_sin_accion(decision):
    if decision["status"] == "approved" and decision.get("actions_count", 0) == 0:
        return {
            "alert": "decision_without_action",
            "severity": "alta",
            "message": "La decisión fue aprobada pero no tiene acciones asociadas."
        }

    return None

26. Notificaciones del workflow

FARO debe notificar según evento, prioridad y rol.

Evento Notifica a
Acción asignada Responsable
Acción aceptada Responsable + aprobador si aplica
Acción rechazada Asignador / superior
Acción próxima a vencer Responsable
Acción vencida Responsable + superior
Acción P1 vencida Dirección
Evidencia cargada Aprobador
Acción cerrada Informados
Acción bloqueada Dueño de dependencia
Tensión recurrente Comité de Dirección

Canales:

FARO Connect
Email
WhatsApp ejecutivo para P1
Slack / Teams si existe
Reporte diario
Comité semanal

Regla:

WhatsApp solo para P1 o temas críticos. Si todo va por WhatsApp, nada es importante.


27. Motor de notificaciones

def canales_notificacion(priority, event_type):
    if priority == "P1":
        return ["FARO Connect", "email", "WhatsApp ejecutivo"]

    if priority == "P2":
        return ["FARO Connect", "email"]

    if event_type in ["weekly_summary", "low_priority"]:
        return ["FARO Connect", "resumen semanal"]

    return ["FARO Connect"]

Mensaje ejemplo:

Acción P1 vencida:
Actualizar plan de caja 7 días.
Responsable: Finanzas.
Venció: hoy 12:00.
Escalado a: Dirección.

28. Workflow y sobrecarga

FARO debe detectar si un responsable está sobrecargado.

Código:

def evaluar_carga_responsable(acciones):
    p1 = sum(1 for a in acciones if a["priority_level"] == "P1")
    p2 = sum(1 for a in acciones if a["priority_level"] == "P2")
    vencidas = sum(1 for a in acciones if a["status"] == "overdue")

    if p1 >= 3 or p1 + p2 >= 8 or vencidas >= 5:
        return {
            "alert": "responsable_sobrecargado",
            "severity": "alta",
            "suggested_action": "reasignar_acciones_o_revisar_prioridades"
        }

    return None

Esto es clave. A veces el problema no es falta de voluntad: es capacidad mal asignada.


29. Workflow y agenda ejecutiva

FARO puede generar agenda diaria o semanal.

Agenda diaria

1. P1 abiertas.
2. Acciones vencidas.
3. Acciones que vencen hoy.
4. Bloqueos.
5. Aprobaciones pendientes.
6. Evidencias pendientes.

Agenda semanal

1. Tensiones P1/P2.
2. Diagnósticos recurrentes.
3. Acciones cerradas.
4. Acciones vencidas.
5. Impacto en FARO Score.
6. Decisiones pendientes.

Código:

def generar_agenda_ejecutiva(eventos):
    return sorted(
        eventos,
        key=lambda e: (
            e.get("priority_score", 0),
            e.get("overdue", False),
            e.get("requires_approval", False)
        ),
        reverse=True
    )

30. Workflow y FARO Score

El workflow debe impactar el FARO Score.

Evento workflow Impacto sugerido
Acción P1 aceptada en plazo +1
Acción P1 cerrada con evidencia +3
Acción P2 cerrada con evidencia +2
Acción crítica vencida -5
Acción P2 vencida -3
Acción sin responsable -3
Acción bloqueada sin gestión -2
Evidencia incompleta -1
Tensión resuelta +4 a +8
Decisión aprobada sin acción -4
Responsable sobrecargado advertencia / ajuste

Código:

def impacto_workflow_score(evento):
    mapa = {
        "p1_accepted_on_time": 1,
        "p1_closed_with_evidence": 3,
        "p2_closed_with_evidence": 2,
        "critical_action_overdue": -5,
        "p2_action_overdue": -3,
        "action_without_responsible": -3,
        "blocked_without_management": -2,
        "incomplete_evidence": -1,
        "resolved_tension": 6,
        "decision_without_action": -4
    }

    return mapa.get(evento, 0)

31. Workflow y evidencia

El workflow no debe permitir cierre si falta evidencia requerida.

Código:

def validar_cierre_con_evidencia(accion):
    requeridas = set(accion.get("required_evidence", []))
    cargadas = set(accion.get("uploaded_evidence", []))

    faltantes = list(requeridas - cargadas)

    if faltantes:
        return {
            "can_close": False,
            "missing_evidence": faltantes,
            "next_status": "waiting_evidence"
        }

    return {
        "can_close": True,
        "next_status": "completed"
    }

Regla:

Sin evidencia, no hay cierre real.

32. Workflow y medición posterior

Una acción puede cerrarse operativamente, pero quedar pendiente de medición.

Ejemplo:

Auditoría descuentos:
cerrada cuando se presenta informe.

Medición:
30 días después se mide si bajó descuento y subió margen.

Estados:

Completed
→ Measured
→ Closed

Código:

def programar_medicion_posterior(accion):
    if accion.get("kpis_to_monitor"):
        return {
            "action_id": accion["action_id"],
            "measurement_required": True,
            "measurement_date": accion.get("measurement_date"),
            "kpis": accion["kpis_to_monitor"]
        }

    return {
        "measurement_required": False
    }

33. Workflow recurrente

Algunas acciones se repiten automáticamente.

Ejemplos:

Revisión diaria de caja.
Revisión diaria de stock crítico.
Revisión semanal de acciones vencidas.
Revisión mensual de margen por vendedor.
Revisión mensual de calidad de datos.

Código:

def crear_accion_recurrente(action_code, frequency, responsible):
    return {
        "action_code": action_code,
        "frequency": frequency,
        "responsible": responsible,
        "status": "active"
    }

Ejemplo:

{
  "action_code": "ACT_DAILY_CASH_REVIEW",
  "frequency": "daily_business_days",
  "responsible": "Finanzas",
  "due_time": "09:00"
}

34. Workflow por industria

34.1 Construcción / insumos

Workflows críticos:

Auditoría de descuentos.
Evaluación de canjes.
Validación de referidos.
Reposición de productos clave.
Cobranza de clientes de obra.
Revisión de comisiones.
Control de stock por sucursal.

34.2 Retail

Quiebre de producto estrella.
Promoción destructiva.
Redistribución de stock.
Control de merma.
Revisión de ticket promedio.

34.3 Logística

SLA incumplido.
Ruta no rentable.
Mantenimiento reactivo.
Combustible desalineado.
Reclamo recurrente.

34.4 Hotelería

Ocupación alta con tarifa baja.
Canal caro dominante.
Mantenimiento por reclamos.
Revisión de RevPAR.

34.5 Salud

Turnos perdidos.
Profesional saturado.
Costo por prestación.
Insumo crítico.
Reclamos recurrentes.

35. Ejemplo completo: acción comercial

Diagnóstico

Crecimiento no rentable.

Acción

Auditar descuentos mayores al 8%.

Workflow

Created:
FARO crea acción desde diagnóstico.

Assigned:
Se asigna a Gerente Comercial.

Pending acceptance:
Gerente Comercial debe aceptar en 8 hs.

Accepted:
Empieza plazo de 72 hs.

In progress:
Se exportan ventas, se calcula margen y se separa por vendedor.

Waiting evidence:
Debe cargar informe.

Under review:
Dirección revisa.

Approved:
Dirección aprueba propuesta.

Measured:
A los 30 días se mide descuento promedio y margen.

Closed:
Se cierra con evidencia y medición.

Escalamiento

Si no acepta en 8 hs:
notificar a Gerencia General.

Si vence en 72 hs:
escalar a Dirección.

Si carga informe incompleto:
volver a Waiting evidence.

36. Ejemplo completo: caja crítica

Diagnóstico

Caja bajo mínimo operativo.

Acción

Actualizar plan urgente de caja.

Workflow

Created automático.
Assigned a Finanzas.
Aceptación máxima: 2 hs.
Primer avance: 6 hs.
Cierre: 24 hs.
Aprobación: Dirección.
Evidencia: cashflow 7 días + plan cobranza + pagos críticos.

Escalamiento

Si no acepta en 2 hs:
escalar a Gerencia General.

Si no hay avance en 6 hs:
escalar a Dirección.

Si vence:
alerta crítica por WhatsApp ejecutivo + FARO Connect + email.

37. Ejemplo completo: canje

Diagnóstico

Canje pendiente de evaluación.

Workflow

Created:
FARO crea guía de evaluación de canje.

Assigned:
Finanzas / Dirección.

In progress:
Se carga valuación, liquidez, riesgo legal y costo financiero.

Waiting approval:
Directorio debe aprobar o rechazar.

Approved / Rejected:
Se registra decisión.

Converted to action:
Si se aprueba, se crean acciones legales, administrativas y comerciales.

Measured:
Se mide valor real recuperado.

Closed:
Se cierra al finalizar operación o liquidación.

Regla:

No se puede cerrar canje sin documentación, simulación y aprobación.

38. Ejemplo completo: acción bloqueada por datos

Diagnóstico

Margen deteriorado.

Problema

Faltan costos en 28% de las ventas.

Workflow

Acción comercial queda bloqueada.
Se crea acción de calidad de datos.
Responsable: Compras / Data Owner.
Una vez corregidos costos, se recalcula margen.
Luego se reabre diagnóstico comercial.

Código:

def bloquear_accion_por_baja_calidad(accion, data_quality_score):
    if data_quality_score < 0.70:
        return {
            "action_id": accion["action_id"],
            "status": "blocked",
            "reason": "Baja calidad de datos",
            "blocking_action": "ACT_DATA_COMPLETE_COSTS"
        }

    return None

39. Tabla SQL de workflows

CREATE TABLE workflows (
    workflow_id TEXT PRIMARY KEY,
    workflow_code TEXT NOT NULL,
    name TEXT NOT NULL,
    description TEXT,
    entity_type TEXT NOT NULL,
    applicable_entities JSONB,
    default_states JSONB,
    transition_rules JSONB,
    escalation_policy_code TEXT,
    active BOOLEAN DEFAULT true,
    version TEXT DEFAULT '1.0',
    created_at TIMESTAMP DEFAULT now(),
    updated_at TIMESTAMP DEFAULT now()
);

40. Tabla SQL de instancias de workflow

CREATE TABLE workflow_instances (
    workflow_instance_id TEXT PRIMARY KEY,
    workflow_code TEXT NOT NULL,
    entity_type TEXT NOT NULL,
    entity_id TEXT NOT NULL,
    company_id TEXT,
    branch_id TEXT,
    area_id TEXT,
    current_state TEXT NOT NULL,
    responsible_id TEXT,
    approver_id TEXT,
    priority_level TEXT,
    due_date TIMESTAMP,
    started_at TIMESTAMP DEFAULT now(),
    completed_at TIMESTAMP,
    closed_at TIMESTAMP,
    status TEXT DEFAULT 'active'
);

41. Tabla SQL de transiciones

CREATE TABLE workflow_transitions (
    transition_id TEXT PRIMARY KEY,
    workflow_instance_id TEXT NOT NULL,
    previous_state TEXT,
    new_state TEXT NOT NULL,
    changed_by TEXT,
    change_reason TEXT,
    metadata JSONB,
    changed_at TIMESTAMP DEFAULT now()
);

42. Tabla SQL de políticas de escalamiento

CREATE TABLE escalation_policies (
    escalation_policy_code TEXT PRIMARY KEY,
    name TEXT NOT NULL,
    description TEXT,
    priority_level TEXT,
    trigger_condition JSONB,
    escalation_steps JSONB,
    notification_channels JSONB,
    active BOOLEAN DEFAULT true,
    created_at TIMESTAMP DEFAULT now(),
    updated_at TIMESTAMP DEFAULT now()
);

Ejemplo de escalation_steps:

[
  {
    "after_hours": 0,
    "role": "Responsable superior",
    "channel": ["FARO Connect", "email"]
  },
  {
    "after_hours": 24,
    "role": "Dirección",
    "channel": ["FARO Connect", "email", "WhatsApp ejecutivo"]
  }
]

43. Tabla SQL de escalamiento

CREATE TABLE escalation_events (
    escalation_id TEXT PRIMARY KEY,
    workflow_instance_id TEXT,
    entity_type TEXT NOT NULL,
    entity_id TEXT NOT NULL,
    company_id TEXT,
    priority_level TEXT,
    escalation_reason TEXT,
    escalated_from TEXT,
    escalated_to TEXT,
    escalation_level INTEGER,
    channels JSONB,
    status TEXT DEFAULT 'open',
    created_at TIMESTAMP DEFAULT now(),
    acknowledged_at TIMESTAMP,
    resolved_at TIMESTAMP
);

44. Tabla SQL de bloqueos

CREATE TABLE workflow_blocks (
    block_id TEXT PRIMARY KEY,
    workflow_instance_id TEXT NOT NULL,
    entity_type TEXT,
    entity_id TEXT,
    block_reason TEXT,
    blocked_by_entity_type TEXT,
    blocked_by_entity_id TEXT,
    dependency_owner_id TEXT,
    status TEXT DEFAULT 'active',
    created_at TIMESTAMP DEFAULT now(),
    resolved_at TIMESTAMP
);

45. Tabla SQL de SLA

CREATE TABLE workflow_sla_rules (
    sla_rule_id TEXT PRIMARY KEY,
    priority_level TEXT NOT NULL,
    entity_type TEXT,
    accept_hours INTEGER,
    first_progress_hours INTEGER,
    close_hours INTEGER,
    escalation_after_hours INTEGER,
    active BOOLEAN DEFAULT true,
    created_at TIMESTAMP DEFAULT now()
);

46. Motor general de workflow

def motor_workflow(evento, workflow_config):
    instancia = {
        "workflow_code": workflow_config["workflow_code"],
        "entity_type": evento["entity_type"],
        "entity_id": evento["entity_id"],
        "current_state": "created",
        "responsible_id": evento.get("responsible_id"),
        "priority_level": evento.get("priority_level"),
        "due_date": evento.get("due_date")
    }

    if instancia["responsible_id"]:
        instancia["current_state"] = "assigned"

    return instancia

47. Motor de monitoreo de workflow

from datetime import datetime

def monitorear_workflows(instancias):
    eventos = []

    for wf in instancias:
        if wf["status"] != "active":
            continue

        if wf.get("due_date") and datetime.now() > wf["due_date"]:
            eventos.append({
                "workflow_instance_id": wf["workflow_instance_id"],
                "event": "overdue",
                "requires_escalation": True
            })

        if wf["current_state"] == "pending_acceptance":
            eventos.append({
                "workflow_instance_id": wf["workflow_instance_id"],
                "event": "pending_acceptance"
            })

        if wf["current_state"] == "blocked":
            eventos.append({
                "workflow_instance_id": wf["workflow_instance_id"],
                "event": "blocked"
            })

    return eventos

48. Motor de escalamiento

def motor_escalamiento(workflow_event, escalation_policy):
    escalations = []

    for step in escalation_policy["escalation_steps"]:
        if workflow_event["hours_overdue"] >= step["after_hours"]:
            escalations.append({
                "escalate_to_role": step["role"],
                "channels": step["channel"],
                "reason": workflow_event["reason"]
            })

    return escalations

49. Herramientas posibles

Necesidad Herramientas
Backend workflow FastAPI, Django, NestJS
Base de datos PostgreSQL
Estados y transiciones PostgreSQL + lógica backend
Colas de tareas Celery, BullMQ, RabbitMQ
Orquestación compleja Temporal, Airflow, Prefect
Notificaciones Email, WhatsApp API, Slack, Teams
Auditoría Tablas de historial
Frontend React / Next.js
Permisos RBAC
IA explicativa OpenAI API con payload estructurado

Para MVP, no hace falta empezar con Temporal o una arquitectura gigante. Puede arrancar con PostgreSQL + backend + jobs programados. Pero el modelo debe nacer bien diseñado, porque después corregir workflow roto es cirugía con la empresa despierta.


50. Prompt interno para IA explicativa

La IA puede explicar el estado del workflow, pero no debe inventar estados ni responsables.

Actúa como analista ejecutivo FARO.

Con base únicamente en el payload estructurado recibido, redacta un resumen claro del workflow.

No inventes datos.
Incluye:
1. estado actual,
2. responsable,
3. vencimiento,
4. bloqueos,
5. evidencia pendiente,
6. próximos pasos,
7. escalamiento si corresponde.

Payload:
{workflow_payload}

51. Testing del workflow

Test transición válida

def test_transicion_valida():
    assert transicion_permitida("assigned", "accepted") is True

Test transición inválida

def test_transicion_invalida():
    assert transicion_permitida("closed", "in_progress") is False

Test acción vencida escala

def test_accion_p1_vencida_escala():
    accion = {
        "status": "overdue",
        "priority_level": "P1",
        "responsible_id": "USER_001"
    }

    destino = determinar_escalamiento(accion)

    assert destino == "Dirección / Gerencia General"

Test cierre sin evidencia

def test_no_cerrar_sin_evidencia():
    accion = {
        "required_evidence": ["informe"],
        "uploaded_evidence": []
    }

    resultado = validar_cierre_con_evidencia(accion)

    assert resultado["can_close"] is False

52. Errores comunes en workflow

Error Consecuencia
Permitir cerrar sin evidencia Se simula ejecución.
No exigir aceptación Nadie se hace cargo.
No escalar vencimientos El sistema pierde autoridad.
Tener demasiados estados Confunde al usuario.
Tener pocos estados No refleja la realidad.
No manejar bloqueos Las acciones se traban sin explicación.
No manejar dependencias Se ejecuta en orden incorrecto.
No medir impacto No hay aprendizaje.
Notificar demasiado El usuario ignora alertas.
No distinguir P1/P2/P3 Todo parece igual.

53. Riesgos si no existe esta capa

Riesgo Consecuencia
Acciones creadas pero no ejecutadas FARO pierde poder real.
Responsables no aceptan tareas No hay accountability.
Acciones vencidas sin consecuencia Se normaliza incumplimiento.
Cierres sin evidencia Dirección cree que algo se resolvió cuando no.
Decisiones sin seguimiento Se pierde control.
Tensiones recurrentes Se atacan síntomas, no causas.
Score sin ejecución real FARO Score pierde credibilidad.
Baja adopción El usuario ve FARO como otro tablero, no como sistema de dirección.

54. Output final del Anexo 31

Al finalizar este anexo, FARO debe tener definido:

1. Estados estándar de workflow.
2. Transiciones permitidas.
3. Workflow por acción.
4. Workflow por alerta.
5. Workflow por tensión.
6. Workflow por diagnóstico.
7. Workflow por recomendación.
8. Workflow por simulación.
9. Workflow por decisión.
10. Reglas de aceptación.
11. Reglas de rechazo con motivo.
12. Reglas de bloqueo.
13. Reglas de dependencias.
14. Reglas de aprobación.
15. SLA por prioridad.
16. Matriz de escalamiento.
17. Motor de notificaciones.
18. Motor de monitoreo.
19. Motor de escalamiento.
20. Workflow recurrente.
21. Detección de sobrecarga.
22. Agenda ejecutiva.
23. Impacto en FARO Score.
24. Evidencia obligatoria.
25. Medición posterior.
26. Tablas SQL de workflow.
27. Testing de workflow.
28. Uso controlado de IA explicativa.
29. Aprendizaje por ejecución.

55. Conexión con otros anexos

Próximo anexo Qué recibe desde Anexo 31
Anexo 21 — Alertas FARO Alertas que ingresan a workflow.
Anexo 22 — Biblioteca de tensiones Tensiones que requieren plan y seguimiento.
Anexo 23 — Diagnóstico ejecutivo Diagnósticos que originan flujos de acción.
Anexo 25 — Priorización ejecutiva Prioridad que define SLA y escalamiento.
Anexo 26 — Recomendaciones FARO Recomendaciones aceptadas, rechazadas o convertidas.
Anexo 27 — Simulación de escenarios Simulaciones que requieren aprobación y decisión.
Anexo 28 — FARO Action Guide Guías que se transforman en pasos del workflow.
Anexo 29 — Biblioteca de acciones Acciones que entran al flujo operativo.
Anexo 30 — Responsables y RACI Responsables, aprobadores y consultados.
Anexo 32 — Evidencia y cierre Evidencia requerida para completar y cerrar.
Anexo 33 — Seguimiento y medición Medición de avances y resultados.
Anexo 35 — FARO Score Impacto de workflow, atrasos y cierres.
Anexo 36 — Aprendizaje Aprendizaje según efectividad real.
Anexo 37Recalibración Ajuste de SLA, reglas y acciones según comportamiento.

El módulo de Workflow y Escalamiento FARO controla que cada acción, alerta, tensión, diagnóstico, recomendación o decisión avance por estados claros: asignación, aceptación, ejecución, evidencia, aprobación, medición y cierre. Además define vencimientos, bloqueos, dependencias, notificaciones y escalamiento automático cuando algo no avanza.

Versión 1.0 · Última revisión: 2026-05-28 Anexo 31 de 40 · Fases 8.3 y 8.4

Profundización técnica v2.0 · Manejo de rechazos y excepciones

Máquina de estados expandida (con casos límite)

[Nueva] → [En análisis] → [En ejecución] → [En verificación] → [Cerrada]
                ↓              ↓                    ↓
            [Rechazada]   [Bloqueada]        [Reabierta]
                ↓              ↓                    ↓
            [Reasignada]  [Escalada]         [Pendiente evidencia]

Reglas de manejo de excepciones

CasoEstado destinoTriggerResponsable destino
Responsable rechaza`Rechazada` → `Reasignada`Usuario click "Rechazar" + motivoAprobador RACI · A
Vence SLA P1 (48hs)`En ejecución` → `Escalada`Cron + 48hs sin cambioAprobador + 1 nivel arriba
Falta evidencia al cerrar`En verificación` → `Pendiente evidencia`Click "Cerrar" sin EVD adjuntaMismo responsable
Retrabajo solicitado`Cerrada` → `Reabierta`Aprobador click "Reabrir" + motivoResponsable original
Acción no aplica`Nueva` → `Descartada`Justificación documentadaAprobador A
Acción duplicada`Nueva` → `Fusionada`Detectado por ACT-NNN repetidoSistema automático

SLA por prioridad + escalamiento

P1 Crítica (48h): Aviso 12h antes → Escala +1 nivel → Comité 24h
P2 Alta (7d):     Aviso 24h antes → Escala +1 nivel → +3d
P3 Media (14d):   Aviso 48h antes → Escala +1 nivel
P4 Baja (30d):    Sin escala automática