A learning-focused Spring Boot project that implements a simple clinic workflow:
- Manage Patients
- Manage Doctors
- Manage Appointments (create, list, update)
- Generate Available Slots for a doctor (next 2 days, fixed window, 15-minute slots)
- Appointment Cancel flow (soft-cancel using status)
- Java + Spring Boot
- Maven
- MySQL
- Spring Data JPA (Hibernate)
- Flyway (DB migrations)
- Bean Validation
- Lombok
- CRUD
- Validation + custom error responses
- CRUD
DoctorSpecialty
- Create / Update / List
- Validations:
- must be in the future
endTimemust be afterstartTime- minimum duration (example: 15 minutes)
- maximum duration (example: 2 hours)
- Overlap prevention (doctor cannot be double-booked)
- Cancel endpoint (status changes to
CANCELED)
- Rules:
- Next 2 days only
- Working hours fixed (example): 4:00 PM → 10:00 PM
- Slot size: 15 minutes
- Excludes already booked slots (ignoring
CANCELED) - Excludes past slots
- JWT auth (login/register)
- Roles: ADMIN / DOCTOR / PATIENT
- Link
userstodoctorsandpatients
- Doctor portal:
- mark appointments as
COMPLETED - dashboard summary (today/upcoming/completed/canceled)
- mark appointments as
- Admin portal:
- manage everything
- define working days/hours per doctor
- Patient portal:
- book from available slots
- view profile + appointments
- Publish events:
- AppointmentCreated / AppointmentCanceled / AppointmentCompleted
- Outbox pattern for reliability
- Notification/Audit/Analytics consumers
- Java (your project currently uses modern JDK)
- Maven
- MySQL running locally
Update src/main/resources/application.properties:
spring.application.name=patientmanagment
server.port=8082
spring.datasource.url=jdbc:mysql://localhost:3306/patientdb?createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
spring.flyway.enabled=true
spring.flyway.locations=classpath:db/migration
spring.flyway.baseline-on-migrate=true
spring.flyway.fail-on-missing-locations=true
spring.web.error.include-message=always
spring.web.error.include-binding-errors=always
spring.web.error.include-stacktrace=never