Chronus es la entrega del Hito 3 del Curso de Java de Desafío Latam y Globant.
El proyecto implementa el backend Java puro de una aplicación de agendamiento para profesionales de la salud. Gestiona citas, datos de pacientes, pagos y recordatorios, sin depender de bases de datos, frameworks web ni servicios externos reales.
En un centro de salud, coordinar horarios, mantener los datos de contacto de los pacientes y confirmar pagos requiere reglas claras para evitar errores de agenda y comunicaciones incompletas.
Chronus centraliza esas reglas en clases Java puras. El sistema valida que las citas sean futuras y que sus identificadores no se repitan, modela los datos de contacto con value objects, acepta únicamente pagos enteros positivos y prepara recordatorios por email y WhatsApp.
La entrega se revisa contra los tres criterios de la rúbrica compartida.
El código está separado en tres capas:
domain: entidades, value objects, excepciones, servicios de dominio y contratos de repositorio.application: casos de uso y puertos de entrada y salida.infrastructure: adaptadores de persistencia y notificación.
El dominio no depende de aplicación ni infraestructura. El dominio y la aplicación tampoco importan Spring, JPA, Jackson u otros frameworks externos.
El dominio utiliza entidades con identidad explícita y ciclo de actualización, además de value objects inmutables implementados como record:
PatientIdFullNameEmailPhoneNumberAppointmentIdAppointmentDateTimePaymentIdPaymentAmount
Cada value object valida sus reglas en el constructor compacto. Las entidades mantienen sus datos tipados con value objects, crean sus identificadores y nombres mediante esos objetos al instanciarse, y exponen su estado mediante getters descriptivos.
AppointmentRepository, PatientRepository y PaymentRepository viven en domain.repository y funcionan como contratos de persistencia. Sus implementaciones en memoria viven en infrastructure.persistence. Los casos de uso reciben repositorios y puertos mediante inyección por constructor.
El núcleo de la aplicación se orquesta desde CreatePatientUseCase, CreateAppointmentUseCase, AcceptPaymentUseCase y SendAppointmentReminderUseCase.
- Fecha de cita válida: una cita debe estar estrictamente en el futuro. Una fecha pasada o igual al momento actual genera
InvalidDateAppointmentException. - Identidad de cita: no se pueden registrar dos citas con el mismo identificador. La segunda solicitud genera
RuntimeException. - Datos del paciente: el nombre, el email y el teléfono se modelan con value objects auto-validados (
FullName,EmailyPhoneNumber), que rechazan valores nulos, vacíos o con formato inválido. - Pago válido: el monto debe ser un número entero estrictamente positivo. Montos negativos, cero o fraccionarios generan
InvalidPaymentException. - Recordatorios: una cita puede enviar un recordatorio al email y WhatsApp registrados para el paciente.
- Tres capas:
domain(modelo y contratos),application(casos de uso) einfrastructure(adaptadores). El dominio no importa aplicación ni infraestructura. - Java puro en el núcleo:
domainyapplicationno usan Spring, JPA ni Jackson. No hay@Service,@Repositoryni@Entityde framework. - Casos de uso concretos: cada acción de negocio es una clase en
application.usecaseque recibe sus dependencias mediante el constructor y exponeexecute(...). - Repositorios como frontera: las interfaces viven en
domain.repository. Las listas en memoria están eninfrastructure.persistence, incluyendo la creación y consulta de pacientes. - Inyección por constructor: los casos de uso reciben repositorios y puertos de notificación, nunca las clases concretas.
- Doubles de prueba: la suite usa mocks de Mockito para los casos de uso y repositorios en memoria para las pruebas de persistencia.
- Regla de dependencia:
ArchitectureTest(ArchUnit) falla el build si dominio o aplicación se acopla a infraestructura o a un framework.
- JDK 17 o superior.
- Maven 3.8 o superior.
El bytecode se compila mediante maven.compiler.release para Java 17.
Ejecuta los siguientes comandos desde la raíz del proyecto.
mvn clean testEjecuta las pruebas JUnit 5, los dobles de Mockito y el reporte de cobertura en consola.
mvn clean verifyEjecuta la suite, genera el reporte JaCoCo y valida los mínimos configurados de cobertura.
Después de ejecutar los tests:
mvn jacoco:reportEl reporte visual de JaCoCo está disponible en:
También se puede regenerar localmente con mvn clean verify; el archivo se encuentra en:
target/site/jacoco/index.html
chronus/
├── src/main/java/com/chronus/
│ ├── application/
│ │ ├── port/ EmailNotifier, WhatsAppNotifier
│ │ └── usecase/ CreatePatientUseCase, CreateAppointmentUseCase,
│ │ AcceptPaymentUseCase, SendAppointmentReminderUseCase
│ ├── domain/
│ │ ├── entity/ Appointment, Patient, Payment
│ │ ├── exception/
│ │ ├── repository/ interfaces AppointmentRepository, PatientRepository,
│ │ │ PaymentRepository
│ │ ├── service/ AppointmentConflictChecker
│ │ └── valueobject/ PatientId, FullName, Email, PhoneNumber,
│ │ AppointmentId, AppointmentDateTime,
│ │ PaymentId, PaymentAmount
│ └── infrastructure/
│ ├── notification/ NoOpEmailNotifier, NoOpWhatsAppNotifier
│ └── persistence/ InMemoryAppointmentRepository, InMemoryPatientRepository,
│ InMemoryPaymentRepository
└── src/test/java/com/chronus/ espejo de los mismos paquetes
- Java 17
- Maven
- JUnit 5
- Mockito
- ArchUnit
- JaCoCo