|
| 1 | +# cq-demo-app-004 — Student Enrollment System (Java/Spring Boot) |
| 2 | + |
| 3 | +Code Quality demo application #4 — a **Student Enrollment Management System** built with Java 21 and Spring Boot 3.3. This app contains **intentional code quality violations** for scanner demonstration purposes. |
| 4 | + |
| 5 | +## Intentional Violations |
| 6 | + |
| 7 | +| Category | Count | Location | |
| 8 | +|----------|-------|----------| |
| 9 | +| **High Cyclomatic Complexity** | 3 | `StudentService.processEnrollment()` (CCN > 15), `StudentController.enrollStudent()`, `GradeCalculator.calculateGPA()` | |
| 10 | +| **Code Duplication** | 4 | Validation logic duplicated across `StudentService`, `CourseService`, `StudentController`, `CourseController` | |
| 11 | +| **Missing Javadoc** | 10+ | All public classes and methods across `controller/`, `service/`, `util/` | |
| 12 | +| **Magic Numbers** | 15+ | `GradeCalculator` (0.3, 0.7, 65, 70, 80, 90, 100), `StudentService` (2.0, 3.5, 21) | |
| 13 | +| **Long Methods** | 3 | `processEnrollment()` > 100 lines, `calculateClassStatistics()` > 50 lines, `calculateGPA()` > 50 lines | |
| 14 | +| **System.out.println** | 12+ | Throughout all classes instead of SLF4J logger | |
| 15 | +| **Raw Types** | 2 | `ReportFormatter.formatStudentReport(List)`, `formatCourseReport(List)` | |
| 16 | +| **String Concatenation in Loops** | 5 | `ReportFormatter` — all formatting methods | |
| 17 | +| **Unused Private Methods** | 3 | `ReportFormatter.padRight()`, `padLeft()`, `repeatChar()` | |
| 18 | +| **Low Test Coverage** | — | Only `contextLoads()` test — < 10% coverage | |
| 19 | + |
| 20 | +## API Endpoints |
| 21 | + |
| 22 | +### Students |
| 23 | +| Method | Path | Description | |
| 24 | +|--------|------|-------------| |
| 25 | +| GET | `/api/students` | List all students | |
| 26 | +| GET | `/api/students/{id}` | Get student by ID | |
| 27 | +| GET | `/api/students/{id}/summary` | Get student summary | |
| 28 | +| POST | `/api/students` | Create a student | |
| 29 | +| PUT | `/api/students/{id}` | Update a student | |
| 30 | +| DELETE | `/api/students/{id}` | Delete a student | |
| 31 | +| POST | `/api/students/{id}/enroll` | Enroll in a course | |
| 32 | +| GET | `/api/students/{id}/validate` | Validate enrollment eligibility | |
| 33 | + |
| 34 | +### Courses |
| 35 | +| Method | Path | Description | |
| 36 | +|--------|------|-------------| |
| 37 | +| GET | `/api/courses` | List all courses | |
| 38 | +| GET | `/api/courses/{id}` | Get course by ID | |
| 39 | +| GET | `/api/courses/{id}/summary` | Get course summary | |
| 40 | +| GET | `/api/courses/code/{code}` | Get course by code | |
| 41 | +| POST | `/api/courses` | Create a course | |
| 42 | +| PUT | `/api/courses/{id}` | Update a course | |
| 43 | +| DELETE | `/api/courses/{id}` | Delete a course | |
| 44 | +| POST | `/api/courses/{id}/validate-enrollment` | Validate course enrollment | |
| 45 | +| GET | `/api/courses/{id}/schedule-conflicts` | Check schedule conflicts | |
| 46 | + |
| 47 | +### Health |
| 48 | +| Method | Path | Description | |
| 49 | +|--------|------|-------------| |
| 50 | +| GET | `/actuator/health` | Spring Actuator health check | |
| 51 | + |
| 52 | +## Tech Stack |
| 53 | + |
| 54 | +- **Java 21** with **Spring Boot 3.3** |
| 55 | +- **Maven** build system |
| 56 | +- **JaCoCo** for coverage reporting |
| 57 | +- **Checkstyle** (Google style) for lint analysis |
| 58 | +- **Docker** multi-stage build |
| 59 | + |
| 60 | +## Run Locally |
| 61 | + |
| 62 | +Build and run with Docker (works in GitHub Codespaces): |
| 63 | + |
| 64 | +```bash |
| 65 | +docker build -t cq-demo-app-004 . |
| 66 | +docker run -p 8080:8080 cq-demo-app-004 |
| 67 | +``` |
| 68 | + |
| 69 | +Then browse to [http://localhost:8080/api/students](http://localhost:8080/api/students). |
| 70 | + |
| 71 | +### Run with Maven (requires Java 21) |
| 72 | + |
| 73 | +```bash |
| 74 | +mvn spring-boot:run |
| 75 | +``` |
| 76 | + |
| 77 | +### Run Tests |
| 78 | + |
| 79 | +```bash |
| 80 | +mvn test |
| 81 | +``` |
| 82 | + |
| 83 | +### Generate Coverage Report |
| 84 | + |
| 85 | +```bash |
| 86 | +mvn test jacoco:report |
| 87 | +``` |
| 88 | + |
| 89 | +Coverage report is generated at `target/site/jacoco/index.html`. |
| 90 | + |
| 91 | +### Run Checkstyle |
| 92 | + |
| 93 | +```bash |
| 94 | +mvn checkstyle:check |
| 95 | +``` |
| 96 | + |
| 97 | +## Azure Deployment |
| 98 | + |
| 99 | +This app deploys as a Docker container to Azure Web App for Containers via the GitHub Actions workflow in `.github/workflows/deploy.yml`. |
| 100 | + |
| 101 | +Infrastructure is defined in `infra/main.bicep` and provisions: |
| 102 | +- Azure Container Registry (ACR) with globally unique name |
| 103 | +- App Service Plan (Linux, B1) |
| 104 | +- Web App for Containers |
| 105 | + |
| 106 | +All resource names use `uniqueString(resourceGroup().id)` for global uniqueness across multiple workshop participants. |
0 commit comments