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