Saltar a contenido

Flujo de Datos

Secuencia tipica de creacion y despacho de una notificacion desde la GUI o la API.

Flujo: Crear y Despachar Notificacion

sequenceDiagram
    actor Usuario
    participant GUI as Streamlit GUI<br/>/:8501
    participant SC as ServiceContainer
    participant UC as CrearNotificacionUseCase
    participant Repo as SqlNotificacionRepository
    participant DB as PostgreSQL
    participant AL as SqlAuditLogger
    participant DW as DispatchWorker
    participant DS as EmailDispatcher<br/>WhatsAppDispatcher

    Usuario->>GUI: Formulario crear notificacion
    GUI->>SC: crear_notificacion.execute(request)
    SC->>UC: execute(CrearNotificacionRequest)

    UC->>Repo: proceso_repo.find_by_id(id_proceso)
    Repo->>DB: SELECT proceso
    DB-->>Repo: ProcesoModel
    Repo-->>UC: Proceso entity

    UC->>UC: Notificacion.crear(...) → Result[Notificacion, str]
    UC->>Repo: notificacion_writer.save(notificacion)
    Repo->>DB: INSERT notificacion
    DB-->>Repo: OK
    Repo-->>UC: Notificacion guardada

    UC->>AL: audit_logger.log(accion="CREAR", ...)
    AL->>DB: INSERT audit_log (append-only)

    UC-->>GUI: Success(CrearNotificacionResponse)
    GUI-->>Usuario: Notificacion creada

    Note over DW,DS: Flujo asincronico de despacho
    GUI->>SC: dispatch_notificacion.execute(id)
    SC->>DW: queue.put(DispatchJob)
    DW->>DS: dispatcher.send(notificacion)
    DS-->>DW: Success / Failure
    DW->>Repo: update(estado=ENVIADA/FALLIDA)
    DW->>AL: audit_logger.log(accion="DESPACHO")

Flujo: Autenticacion API

sequenceDiagram
    actor Client
    participant API as FastAPI :8000
    participant DEP as get_container()<br/>Depends
    participant AUTH as AuthService
    participant DB as PostgreSQL

    Client->>API: POST /auth/login {email, password}
    API->>DEP: yield ServiceContainer (session)
    DEP->>DB: Session open
    API->>AUTH: login(email, password)
    AUTH->>DB: SELECT usuario + intentos fallidos
    DB-->>AUTH: Usuario + LoginAttempts
    AUTH->>AUTH: Verificar lockout (TTL 15min)
    AUTH->>AUTH: bcrypt.verify(password, hash)

    alt Credenciales correctas
        AUTH->>AUTH: Generar JWT (sub=id, rol=rol, exp=480min)
        AUTH-->>API: Success(LoginResponse{token})
        API-->>Client: 200 {access_token, token_type}
    else Credenciales incorrectas
        AUTH->>DB: INSERT login_attempt (contador++)
        AUTH-->>API: Failure("Credenciales invalidas")
        API-->>Client: 401 Unauthorized
    end

    Note over DEP,DB: session.close() en finally

Flujo: Request Autenticado a API

sequenceDiagram
    actor Client
    participant API as FastAPI Endpoint
    participant MW as get_current_user()<br/>Depends
    participant DB as PostgreSQL

    Client->>API: GET /procesos<br/>Authorization: Bearer <token>
    API->>MW: decode JWT
    MW->>MW: jose.jwt.decode(token, secret_key)

    alt Token valido
        MW-->>API: CurrentUser{usuario_id, rol}
        API->>DB: SELECT procesos
        DB-->>API: [ProcesoModel...]
        API-->>Client: 200 [{proceso...}]
    else Token invalido/expirado
        MW-->>API: HTTPException 401
        API-->>Client: 401 Token invalido o expirado
    end