Clean Architecture is a software design philosophy that separates concerns into distinct layers with clear boundaries. The core principle is the Dependency Rule: dependencies point inward toward the domain, never outward.
enum EstadoReserva { pendiente, confirmada, cancelada,}class Reserva { final String id; final String mesaId; final DateTime fechaHora; final int numeroPersonas; final int duracionMinutos; EstadoReserva estado; final String? contactoCliente; final String? nombreCliente; // Business logic method DateTime get horaFin => fechaHora.add(Duration(minutes: duracionMinutos)); void confirmar() { if (estado == EstadoReserva.cancelada) { throw Exception('No se puede confirmar una reserva cancelada.'); } if (estado == EstadoReserva.confirmada) { throw Exception('La reserva ya está confirmada.'); } estado = EstadoReserva.confirmada; }}
Key Point: The Reserva entity knows nothing about Firestore, Flutter, or any external framework. It’s pure business logic.
class CrearReserva { final ReservaRepositorio reservaRepositorio; final MesaRepositorio? mesaRepositorio; final HorarioAperturaRepositorio? horarioAperturaRepositorio; final NegocioRepositorio? negocioRepositorio; final ServicioEmail? servicioEmail; Future<Reserva> ejecutar( String mesaId, DateTime fecha, DateTime hora, int numeroPersonas, { required String negocioId, }) async { // 1. Validate future date if (fechaHora.isBefore(DateTime.now())) { throw Exception('La fecha y hora deben ser futuras.'); } // 2. Validate table capacity final mesa = await mesaRepositorio!.obtenerMesaPorId(mesaId); if (!mesa.puedeAcomodar(numeroPersonas)) { throw Exception('Mesa capacity mismatch'); } // 3. Check business hours final estaAbierto = await horarioAperturaRepositorio!.estaAbiertoEn( negocioId, fechaHora, ); // 4. Check table availability final mesaDisponible = await reservaRepositorio.mesaDisponible( mesaId: mesaId, fecha: fecha, hora: fechaHora, duracionMinutos: duracionMinutos, ); // 5. Create reservation final reserva = await reservaRepositorio.crearReserva(reservaTemporal); // 6. Send notifications await servicioEmail?.notificarReservaConfirmada(reserva); return reserva; }}
Key Point: Use cases depend on repository interfaces, not concrete implementations. They orchestrate the business flow without knowing about Firestore.