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 EB as EventBus
participant Handler as DispatchOnNotificacionCreada
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]
Note over UC,DB: UoW abre transaccion (SessionUnitOfWork)
UC->>Repo: notificacion_writer.save(notificacion)
Repo->>DB: INSERT notificacion (staged, no commit)
DB-->>Repo: OK
Repo-->>UC: Notificacion guardada
UC->>AL: audit_logger.flush(accion="CREAR", ...)
AL->>DB: flush audit_log (parte de la misma transaccion)
UC->>UC: uow.commit() — confirma INSERT + audit en una transaccion
UC->>EB: event_bus.publish(NotificacionCreadaEvent)
EB-->>Handler: DispatchOnNotificacionCreada (si dispatcher configurado)
UC-->>GUI: Success(CrearNotificacionResponse)
GUI-->>Usuario: Notificacion creada
Note over Handler,DS: Despacho via EventBus handler
Handler->>SC: dispatch_notificacion.execute(id)
SC->>DS: dispatcher.dispatch(notificacion)
DS-->>SC: Success / Failure
SC->>Repo: update(estado=ENVIADA/FALLIDA) via UoW
SC->>AL: audit_logger via UoW commit
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