UNICAM Course Enrollment Service
Jakarta EE 11 · JPA · CDI · JAX-RS · Bean Validation · JTA
This is a study project. Every class is commented to explain what it does,
why it is built that way, and what the industry term for it is.
Start with README.md, then docs/ARCHITECTURE.md.
Pages
Those four are the fieldbook's own multi-user layer, and they are the
only authenticated thing here. The enrollment API below is deliberately
left open, because it is the specimen chapter 15 dissects.
See docs/ACCOUNTS.md.
Courses
| GET | /api/courses/open | Courses whose enrollment window is open right now |
| GET | /api/courses?year=2025&semester=FALL | Catalogue, paginated |
| GET | /api/courses/{id} | One course, with prerequisites |
| GET | /api/courses/{id}/enrollments | Course roster |
| POST | /api/courses | Create a course |
| PUT | /api/courses/{id}/prerequisites/{prereqId} | Add a prerequisite |
| PATCH | /api/courses/{id}/capacity?value=50 | Change capacity |
Students
| GET | /api/students?name=ferrari&status=ACTIVE | Search, paginated |
| GET | /api/students/{id} | Detail, with full transcript |
| GET | /api/students/by-number/{matricola} | Lookup by matricola |
| GET | /api/students/{id}/enrollments | The student's enrollments |
| POST | /api/students | Register a student |
| PATCH | /api/students/{id} | Partial update |
| POST | /api/students/{id}/suspension | Suspend |
| DEL | /api/students/{id}/suspension | Reinstate |
| DEL | /api/students/{id} | Delete (cascades to enrollments) |
Enrollments
| POST | /api/enrollments | Enrol — enforces every business rule |
| GET | /api/enrollments/{id} | One enrollment |
| POST | /api/enrollments/{id}/grade | Record a pass (18–30, optional lode) |
| POST | /api/enrollments/{id}/failure | Record a failure |
| POST | /api/enrollments/{id}/retake | Re-activate after a failure |
| DEL | /api/enrollments/{id} | Withdraw (status change, not a delete) |
Professors
| GET | /api/professors | All teaching staff |
| GET | /api/professors/{id} | One professor |
Mail
Enrolling a student queues a confirmation; recording a grade queues the
result. The messages are written to an outbox table inside the same
transaction and delivered by a scheduled dispatcher — see
docs/ARCHITECTURE.md ยง7c. In the Docker stack they land in
Mailpit and go no further.
These endpoints need a signed-in fieldbook account, because the outbox
holds real addresses and message bodies. Sending anything needs the
author role.
| GET | /api/mail/status | Live transport, configuration, and the count in every state |
| GET | /api/mail/outbox?status=PENDING | The queue, newest first |
| GET | /api/mail/outbox/{id} | One message, with the body that was rendered |
| POST | /api/mail/outbox/{id}/requeue | Try a dead message again (author) |
| POST | /api/mail/outbox/{id}/cancel | Stop one that has not gone yet (author) |
| POST | /api/mail/dispatch | Run a dispatch pass now instead of waiting (author) |
| POST | /api/mail/test | Queue one test message (author) |
Try it
curl http://localhost:8280/enrollment/api/courses/open
curl -X POST http://localhost:8280/enrollment/api/enrollments \
-H "Content-Type: application/json" \
-d '{"studentId": 1, "courseId": 1}'
Business rules you can trigger
| COURSE_FULL | CS401 has a capacity of 3 — enrol four students |
| ENROLLMENT_WINDOW_CLOSED | CS150's window closed last year |
| PREREQUISITES_NOT_MET | CS401 requires CS101 and CS301 |
| STUDENT_NOT_ELIGIBLE | Student 100004 is suspended |
| DUPLICATE_RESOURCE | Enrol the same student twice |
| INVALID_GRADE | Award lode with a grade below 30 |