A Spring Boot based RESTful web application to manage Students, Courses, Instructors, and Enrollments using a layered architecture with role-based access control, validations, pagination, and Swagger API documentation.
- The Course Enrollment System is a production-grade monolithic RESTful web application built with Spring Boot 3.5.5.
- It demonstrates enterprise-level concepts like layered architecture, role-based access control (RBAC), audit logging, validation, pagination, and standardized API responses.
This project implements a course enrollment platform with 4 main modules:
- Student Module → Manages student profiles with validation and audit fields.
- Instructor Module → Manages instructor profiles with email/mobile uniqueness and role-based access.
- Course Module → Handles courses with CRUD operations, search by title/duration/fee, and status management.
- Enrollment Module → Manages course enrollments with status transitions, pagination, and access restrictions for students and admins.
The system provides functionality for:
- 🔐 Authentication & Authorization (Role-based Access: STUDENT, INSTRUCTOR, ADMIN)
- 👤 Student & Instructor Management (CRUD, search, validations, audit logging)
- 🏫 Course Management (CRUD, search, status updates, fee & duration filters)
- 📚 Enrollment Management (Enroll, fetch by student/course, withdraw, status transitions)
- 📄 Standardized API Responses (RequestDTO & ResponseDTO pattern)
- ⚡ Layered Architecture (Controller → Service → Repository → DTO → Mapper)
- 📊 Swagger/OpenAPI documentation for all endpoints
- Language: Java 17
- Framework: Spring Boot 3.5.5
- Database: MySQL
- Security: Spring Security (Role-based)
- Validation: Jakarta Validation (Bean Validation)
- Logging: SLF4J
- API Documentation: Swagger/OpenAPI (springdoc-openapi)
- Build Tool: Maven
- Testing: JUnit, Mockito
============================================================================================================
COURSE ENROLLMENT SYSTEM - ASCII ARCHITECTURE
============================================================================================================
┌──────────────────────────────────────────────────┐
│ User Agent │ Clients (Browser / Postman / curl) |
└──────────────────────┬───────────────────────────┘
│ requests (CRUD / enrollments)
v
┌──────────────────────────────────────────────────┐
│ Spring Boot App │
│ (9080) │
│ - Controller layer (REST APIs) │
│ - Service layer (Business logic, validation) │
│ - Repository/DAO layer (Database access) │
│ - Mapper layer (DTO <-> Entity conversions) │
└──────────────────────┬───────────────────────────┘
|
v
┌──────────────────────────────────────────────────┐
│ MySQL DB │
│ - students, courses, instructors, enrollments │
└──────────────────────────────────────────────────┘
============================================================================================================
Typical flow examples:
1) Student creation flow:
Client -> [Controller] -> Service layer -> Repository -> MySQL
Service validates input, checks duplicates, maps DTO to Entity, persists in DB
Response returned: ResponseDTO with created entity info and audit fields
2) Course enrollment flow:
Client -> [Controller] -> Service layer
Service layer checks student & course existence, validates enrollment rules
Repository persists enrollment in DB
Response returned: EnrollmentResponseDTO with status and dates
3) Audit & Logging:
BaseEntity fields: createdAt, createdBy, updatedAt, updatedBy
Service layer uses SLF4J logging for info, error, and debug messages
4) DTO & Mapper usage:
Controllers receive RequestDTO, pass to Service
Service maps RequestDTO to Entity using Mapper
Service maps Entity to ResponseDTO for Controller response
============================================================================================================
ROLE_ADMIN→ full control over all entities (students, courses, instructors, enrollments).ROLE_STUDENT→ can view available courses, enroll in courses, and manage their own profile.ROLE_INSTRUCTOR→ can manage courses they teach and view enrolled students.
-
Enforced at controller layer using
@PreAuthorizewith SpEL expressions. -
Fine-grained ownership checks handled in service layer:
StudentSecurity→ ensures users access only their own student profile or admin access.InstructorSecurity→ validates if the logged-in instructor manages the course.EnrollmentSecurity→ validates enrollment ownership or course ownership (for instructors/admin).
-
Defense in depth:
- Controllers validate JWT token and roles.
- Service layer performs additional ownership and business rule validations.
-
Entities use status enums instead of hard deletes to maintain history and auditing:
StudentStatus { ACTIVE, SUSPENDED, DELETED, EXPIRED }InstructorStatus { ACTIVE, SUSPENDED, DELETED, EXPIRED }CourseStatus { CREATED, IN_PROGRESS, COMPLETED, DELETED }EnrollmentStatus { ENROLLED, DROPPED }
-
Status semantics:
ACTIVE / ENROLLED / IN_PROGRESS→ normal operational use.DELETED / DROPPED / SUSPENDED / EXPIRED→ logically removed or restricted but retained for audit/history.
-
Status enums persisted with
@Enumerated(EnumType.STRING)→ safe from enum reordering issues. -
Database constraints and indexing for uniqueness, query performance, and filtering:
- Student →
student_id(unique),email(unique),mobile(unique) - Instructor →
instructor_id(unique),email(unique),mobile(unique) - Course →
course_id(unique),title(unique) - Enrollment →
enrollment_id(unique)
- Student →
-
All entities extend a common
BaseEntityproviding automatic auditing:createdAt→ Timestamp of creationcreatedBy→ Username of creator (SYSTEMfor background tasks)updatedAt→ Timestamp of last updateupdatedBy→ Username of last modifier
-
Implemented with Spring Data JPA Auditing using
@CreatedDate,@LastModifiedDate,@CreatedBy,@LastModifiedBy. -
Automatically tracks user or system actions without manual intervention, ensuring a consistent audit trail.
- Internal helper methods (service-to-service within the monolith) enforce business rules, e.g., validating student enrollment or instructor course ownership.
- Not exposed externally; only accessible via controller endpoints with proper authorization.
- Authentication → JWT-based (
/api/auth/login). - Authorization → Role-based + ownership checks.
- Passwords are BCrypt hashed before persistence.
- JWT uses a 256-bit secret key stored in
application.yml. - Tokens carry both username and role, parsed via
JwtAuthenticationFilter.
- Follows RESTful conventions.
- DTO layer for request/response decoupling.
- Global Exception Handler standardizes error responses.
- Swagger/OpenAPI annotations for all DTOs & controllers.
============================================================================================================
COURSE ENROLLMENT SYSTEM - ROLES & ENTITY FLOW
============================================================================================================
+----------------+ +----------------+ +----------------+ +----------------+
| ROLE_ADMIN | | ROLE_USER | | ROLE_INSTRUCTOR| | SYSTEM |
+----------------+ +----------------+ +----------------+ +----------------+
| Full control | | View courses | | Manage own | | Background ops |
| over all | | Enroll in | | courses & | | (auto-audit) |
| entities | | courses | | students | | |
+-------+--------+ +-------+--------+ +-------+--------+ +-------+--------+
| | | |
v v v v
+----------------+ +----------------+ +----------------+ +----------------+
| Student | | Course | | Instructor | | Enrollment |
+----------------+ +----------------+ +----------------+ +----------------+
| student_id | | course_id | | instructor_id | | enrollment_id |
| name, email | | title, status | | name, email | | student_id |
| mobile, status | | description | | mobile, status | | course_id |
+-------+--------+ | fee, duration | +-------+--------+ | status |
| +----------------+ | | enrollmentDate |
| | | | completionDate |
| | | +-------+--------+
| | | |
v v v v
+-------------------------------------------------------------------------------+
| STATUS MANAGEMENT / AUDIT |
+-------------------------------------------------------------------------------+
| StudentStatus { ACTIVE, SUSPENDED, DELETED, EXPIRED } |
| InstructorStatus { ACTIVE, SUSPENDED, DELETED, EXPIRED } |
| CourseStatus { CREATED, IN_PROGRESS, COMPLETED, DELETED } |
| EnrollmentStatus { ENROLLED, DROPPED } |
| BaseEntity fields: createdAt, createdBy, updatedAt, updatedBy |
+-------------------------------------------------------------------------------+
-
The application uses a single centralized configuration file:
application.yml. -
Configurations are externalized to make the application portable across environments (dev, staging, prod).
-
Configurations managed in
application.ymlinclude:- Database: MySQL datasource URL, username, password, driver class.
- JPA / Hibernate: dialect,
ddl-auto, SQL logging, and formatting. - Server: port configuration (
9080). - Actuator: management endpoints exposure (
*enabled for dev). - Swagger/OpenAPI: enabled in
devprofile for API documentation. - Security: JWT properties (secret key, expiration time).
-
Benefits:
- Environment-specific configurations are isolated and easy to manage.
- Sensitive values (JWT secret, DB password) are centralized in one place.
- Simplifies deployment: only the config file changes per environment, not the code.
- Easy to extend with additional custom properties.
============================================================================================================
COURSE ENROLLMENT SYSTEM - CONFIGURATION FLOW
============================================================================================================
┌──────────────────────────────────────────────────┐
│ application.yml │
│ - Common properties (DB, JPA, server, actuator) │
│ - Custom JWT properties │
└──────────────────────┬───────────────────────────┘
│
v
┌──────────────────────────────────────────────────┐
│ Profile-specific overrides │
│ application-dev.yml | application-prod.yml │
│ - dev DB configs | - prod DB configs │
│ - Swagger enabled | - Swagger disabled │
│ - Actuator full | - Restricted actuator│
└──────────────────────┬───────────────────────────┘
│
v
┌──────────────────────────────────────────────────┐
│ Spring Boot Application Startup │
│ - Loads `spring.profiles.active` (e.g., dev) │
│ - Merges common + profile configs │
│ - Injects properties into beans via @Value / │
│ @ConfigurationProperties │
└──────────────────────────────────────────────────┘
============================================================================================================
All endpoints are fully documented with Swagger OpenAPI (@Operation, @ApiResponses, @Schema annotations).
Swagger UI is available at: /swagger-ui.html (enabled only in dev profile).
POST /api/auth/login— login, returns JWT (public)POST /api/auth/student/register— register student (public)POST /api/auth/instructor/register— register instructor (public)POST /api/auth/admin/register— register admin (ADMIN only)GET /api/auth/admin— get all admins (ADMIN only)GET /api/auth/admin/active— get all active admins (ADMIN only)GET /api/auth/admin/deleted— get all deleted admins (ADMIN only)PUT /api/auth/change-password— change password (ADMIN, INSTRUCTOR, STUDENT)PUT /api/auth/admin/change-username— change admin username (ADMIN only (self))PUT /api/auth/user/status— update user status (ADMIN only)DELETE /api/auth/user/{userName}— soft delete user (ADMIN, self)POST /api/auth/user/restore/{userName}— restore user (ADMIN, self)DELETE /api/auth/user/permanent/{userName}— permanent delete user (ADMIN only)POST /api/auth/logout— logout, invalidate token (ADMIN, INSTRUCTOR, STUDENT)
GET /api/students/{studentId}— get student by studentId (ADMIN, STUDENT (self))GET /api/students— get all students (ADMIN only)GET /api/students/by-mobile/{mobile}— get student by mobile (ADMIN, STUDENT (self))GET /api/students/by-email/{email}— get student by email (ADMIN, STUDENT (self))PUT /api/students/{studentId}— update student (ADMIN, STUDENT (self))
GET /api/instructors/{instructorId}— get instructor by instructorId (ADMIN, INSTRUCTOR (self))GET /api/instructors— get all instructors (ADMIN only)GET /api/instructors/by-mobile/{mobile}— get instructor by mobile (ADMIN, INSTRUCTOR (self))GET /api/instructors/by-email/{email}— get instructor by email (ADMIN, INSTRUCTOR (self))PUT /api/instructors/{instructorId}— update Instructor (ADMIN, INSTRUCTOR (self))
POST /api/courses— create course (ADMIN, INSTRUCTOR)PUT /api/courses/start/{courseId}— start course (ADMIN only)PUT /api/courses/complete/{courseId}— complete course (ADMIN only)GET /api/courses/{courseId}— get course by courseId (ADMIN, INSTRUCTOR, STUDENT)GET /api/courses— get all courses (ADMIN, INSTRUCTOR, STUDENT)GET /api/courses/title/{title}— get course by title (ADMIN, INSTRUCTOR, STUDENT)GET /api/courses/search/{title}— search courses by title (ADMIN, INSTRUCTOR, STUDENT)GET /api/courses/duration/{duration}— search courses by duration (ADMIN, INSTRUCTOR, STUDENT)GET /api/courses/fee-range/{minFee}/{maxFee}— search courses by fee-range (ADMIN, INSTRUCTOR, STUDENT)GET /api/courses/instructors/{instructorId}— get courses by instructorId (ADMIN, INSTRUCTOR (self))GET /api/courses/students/{studentId}— get courses by studentId (ADMIN, STUDENT (self))PUT /api/courses/{courseId}— update course (ADMIN, INSTRUCTOR (course owner))DELETE /api/courses/{courseId}— delete course (ADMIN, INSTRUCTOR (course owner))GET /api/courses/{courseId}/students— get students by courseId (ADMIN)GET /api/courses/{courseId}/instructor— get instructors by courseId (ADMIN)
POST /api/enrollments— enroll student in a course (ADMIN, STUDENT (self))GET /api/enrollments/{enrollmentId}— get enrollment by enrollmentId (ADMIN, STUDENT (self))GET /api/enrollments— get all enrollments (ADMIN)GET /api/enrollments/student/{studentId}— get enrollments by studentId (ADMIN, STUDENT (self))GET /api/enrollments/course/{courseId}— get enrollments by courseId (ADMIN)PUT /api/enrollments/{enrollmentId}— withdraw enrollment (ADMIN, STUDENT (self))
- JDK 21+
- Maven 3.9+
- MySQL running locally with schema:
course_enrollment_db
-- Create database
CREATE DATABASE course_enrollment_db; git clone https://github.com/your-repo/course-enrollment-system.git
cd course-enrollment-system mvn clean install -U mvn spring-boot:runor run directly via IDE (main class: CourseEnrollmentSystemApplication.java).
- App Base URL → http://localhost:9080
- Swagger/OpenAPI UI → http://localhost:9080/swagger-ui/index.html
- Actuator Health Check → http://localhost:9080/actuator/health
A complete Postman Collection is provided to test all APIs of the system:
- Auth Module → user registration, login, JWT validation
- Student Module → student CRUD and search APIs
- Instructor Module → instructor CRUD and search APIs
- Course Module → course CRUD, search, status update APIs
- Enrollment Module → enrollment CRUD, status transitions
Features:
- Organized by module (Auth, Student, Instructor, Course, Enrollment).
- Pre-configured environment variable for base URL (
http://localhost:9080). - Includes sample requests for login and testing JWT-protected APIs.
- Provides example payloads for create/update operations across modules.
👉 Import the collection into Postman and start testing after running the application locally.
-
Spring Boot Actuator endpoints are enabled:
- Health check →
/actuator/health - Application info →
/actuator/info - Metrics →
/actuator/metrics
- Health check →
-
Future Enhancements:
- Integrate Prometheus for metrics collection.
- Visualize metrics and create dashboards using Grafana.
- Add request/response logging and tracing for detailed observability.
-
Unit Testing:
- Implemented using JUnit 5 and Mockito for mocking dependencies.
- Services and mappers are covered with unit tests for business logic validation.
-
Integration Testing:
- Spring Boot Test used to test API endpoints, repository interactions, and service layers.
- Testcontainers can be integrated for testing with a real MySQL instance.
-
CI/CD Pipeline (Future Scope):
-
GitHub Actions or Jenkins can be used to automate:
- Build (
mvn clean install) - Run unit & integration tests
- Generate reports
- Build (
-
- Follow the project coding conventions (naming, formatting, log levels, DTO patterns).
- Add unit and integration tests for any new feature.
- Update Swagger/OpenAPI documentation when adding or modifying APIs.
- Contributions: open pull requests with proper tests, documentation, and clear commit messages.
- License: MIT
- Containerization with Docker for the application.
- Docker Compose for easy multiservice/local environment setup (if modules are split later).
- Centralized logging with ELK (Elasticsearch, Logstash, Kibana) or similar.
- Resilience and retry mechanisms (Resilience4j) for critical operations.
- Advanced API documentation publishing via SwaggerHub or Redoc.
- CI/CD pipelines for automatic build, test, and deployment (GitHub Actions, Jenkins, etc.).
- Potential modularization or microservices migration in future for scalability.