This project was initialy created during an internal training organized by my employer.
The Appointment Booking System allows clients to schedule appointments with specialists for various treatments (e.g. dental consultations, medical procedures). Key capabilities include:
- Clients can browse available treatments, book appointments, cancel them, and view their appointment history.
- Specialists can create and manage treatments, mark appointments as completed, and review their schedule history.
- Receptionists / Admins oversee the system and manage users.
- The system automatically validates scheduling conflicts, ensuring no two appointments overlap for the same specialist.
- Business Overview
- Live Demo (VPS)
- Login Credentials
- Technology Stack
- Java Version
- Used Libraries
- Available Endpoints
The application is deployed and available at: http://srv11.mikr.us:20109/
Current deployed version: 0.0.2.1-ALPHA (see pom.xml).
The following demo accounts are available (both on the VPS demo and locally):
| Role | Username | Password |
|---|---|---|
| Admin | admin |
admin |
| Specialist | specialist |
specialist |
| Receptionist | receptionist |
receptionist |
| Client | client |
client |
- Java 21
- Spring Boot 3.5 (Web, Data JPA, Security, Validation, Actuator)
- Spring Security (Basic Auth, in-memory users)
- Hibernate / JPA with QueryDSL for type-safe queries
- MapStruct for DTO/entity mapping
- Flyway for database migrations
- H2 in-memory database
- OpenAPI / Swagger (springdoc + openapi-generator-maven-plugin)
- Lombok
- Maven as the build tool
- JUnit 5 and Spring Security Test for testing
- Docker (see
Dockerfile) for containerized deployment on VPS
- React + Vite (bundled static assets served from
src/main/resources/static) - Axios for HTTP calls to the REST API
- Static HTML pages (
login.html,home.html,treatments.html,appointments.html) integrated with the Spring Boot backend
This project uses Java version: 21
List of libraries used in this project along with their versions:
- spring-boot-starter-web: 3.5.13
- spring-boot-starter-data-jpa: 3.5.13
- spring-boot-starter-security: 3.5.13
- spring-boot-starter-validation: 3.5.13
- spring-boot-starter-actuator: 3.5.13
- springdoc-openapi-starter-webmvc-ui: 2.8.5
- openapi-generator-maven-plugin: 7.11.0
- swagger-annotations: 2.2.28
- jackson-databind-nullable: 0.2.6
- mapstruct: 1.5.5.Final
- querydsl-jpa: 5.1.0
- flyway-core (managed by Spring Boot)
- h2 (managed by Spring Boot)
- lombok: 1.18.30
- spring-boot-starter-test: 3.5.13
- spring-security-test: 3.5.13
- junit-jupiter-api: 5.10.2
- URL:
/api/v1/treatments - Method:
GET - Auth required: Yes (Basic Auth)
- Code:
200 OK - Content:
[
{
"id": -1,
"name": "Konsultacja dentystyczna",
"duration": 30,
"specialistId": -1
}
]- URL:
/api/v1/treatments/{id} - Method:
GET - Auth required: Yes (Basic Auth)
- Code:
200 OK - Content:
{
"id": -1,
"name": "Konsultacja dentystyczna",
"description": "Konsultacja dentystyczna z diagnostyką i planem leczenia",
"duration": 30,
"specialist": {
"id": -1,
"name": "DENTIST"
}
}- Code:
404 NOT FOUND - Content:
{
"status": "404",
"message": "Treatment has not been found"
}- URL:
/api/v1/treatments - Method:
POST - Auth required: Yes (Basic Auth, role
SPECIALIST) - Body:
{
"name": "Konsultacja dentystyczna",
"description": "Konsultacja dentystyczna z diagnostyką i planem leczenia",
"duration": 30,
"specialistId": -1
}- URL:
/api/v1/appointments - Method:
GET - Auth required: Yes (Basic Auth)
- Code:
200 OK - Content:
[
{
"id": -1,
"clientId": -1,
"treatmentId": -1,
"dateTime": "2024-03-01T09:00:00Z",
"status": "SCHEDULED"
}
]- URL:
/api/v1/appointments - Method:
POST - Auth required: Yes (Basic Auth)
- Body:
{
"clientId": -1,
"treatmentId": -1,
"dateTime": "2024-06-01T09:00:00Z"
}- Code:
400 BAD REQUEST - Content:
{
"status": "400",
"message": "Specialist is not available at this time"
}- URL:
/api/v1/appointments/{id} - Method:
PATCH - Auth required: Yes (Basic Auth)
- Body:
{
"status": "CANCELLED"
}- URL:
/api/user/info - Method:
GET - Auth required: Yes (Basic Auth)
- Code:
200 OK - Content:
{
"authenticated": true,
"username": "client",
"roles": ["CLIENT"],
"id": -1,
"clientId": -1
}All responses are in application/json format.