Saltar a contenido

Reglas de arquitectura hexagonal — Backend

Capas y dependencias

  • domain/: solo entidades y errores de dominio. No puede importar infrastructure, adapters ni repository.
  • adapters/: handlers HTTP y WS. Pueden usar crate::repository (re-export de infrastructure) y crate::domain::entities para DTOs/validaciones. Objetivo a medio plazo: que los handlers llamen a una capa de aplicación (use cases) y no a repos directamente.
  • infrastructure/: persistencia, config, email, activity_log. Puede importar domain::entities para tipos. No debe importar adapters.

Lógica de negocio

  • Reglas de negocio (validaciones, cálculos, permisos) no deben vivir solo en handlers. Mover a funciones en módulos de dominio o a un futuro módulo application/ (commands/queries).
  • Handlers: extraer parámetros, llamar a aplicación/dominio, mapear a respuesta HTTP. No poner algoritmos complejos (ej. auto_assign) dentro del handler; extraer a módulo dedicado que el handler solo invoque.

Prohibido (lógica en handler)

// Dentro de time_control_handler.rs
if req.staff_id.is_some() && req.actor_session_id.is_none() {
    repository::place::check_place_manage(...).await?;
}
// + toda la lógica de distancia, resolución de actor, etc.
Correcto
// Handler solo orquesta
let result = time_control::clock_in(&state.pool, &req, auth.user_id).await?;
Ok(Json(TimeControlResponse::from(result)))
(Lógica en módulo time_control o en domain/application.)

Imports

  • En handlers: use crate::repository::*, use crate::db::AppState, use crate::error::AppError, y si aplica use crate::domain::entities::*. No importar rutas de infrastructure::persistence::postgres::* directamente; usar siempre crate::repository.
  • En domain: solo módulos bajo domain/ y tipos estándar. Sin crate::repository, crate::infrastructure, crate::adapters.

Repos y SQLx

  • Los repos pueden devolver structs propios (ej. ShiftRow) que contengan datos de fila. Evitar filtrar datos por tenant (place_id) solo en el handler; el repo debe recibir place_id cuando corresponda y filtrar en la query.