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

tutorial.html The fieldbook — the 30-chapter course this project is built around
signin.html Sign in, so your progress follows you between machines
register.html Create an account
area-riservata.html Area riservata — mastery, streak, chapters, notes, and the account itself

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/openCourses whose enrollment window is open right now
GET/api/courses?year=2025&semester=FALLCatalogue, paginated
GET/api/courses/{id}One course, with prerequisites
GET/api/courses/{id}/enrollmentsCourse roster
POST/api/coursesCreate a course
PUT/api/courses/{id}/prerequisites/{prereqId}Add a prerequisite
PATCH/api/courses/{id}/capacity?value=50Change capacity

Students

GET/api/students?name=ferrari&status=ACTIVESearch, paginated
GET/api/students/{id}Detail, with full transcript
GET/api/students/by-number/{matricola}Lookup by matricola
GET/api/students/{id}/enrollmentsThe student's enrollments
POST/api/studentsRegister a student
PATCH/api/students/{id}Partial update
POST/api/students/{id}/suspensionSuspend
DEL/api/students/{id}/suspensionReinstate
DEL/api/students/{id}Delete (cascades to enrollments)

Enrollments

POST/api/enrollmentsEnrol — enforces every business rule
GET/api/enrollments/{id}One enrollment
POST/api/enrollments/{id}/gradeRecord a pass (18–30, optional lode)
POST/api/enrollments/{id}/failureRecord a failure
POST/api/enrollments/{id}/retakeRe-activate after a failure
DEL/api/enrollments/{id}Withdraw (status change, not a delete)

Professors

GET/api/professorsAll 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/statusLive transport, configuration, and the count in every state
GET/api/mail/outbox?status=PENDINGThe queue, newest first
GET/api/mail/outbox/{id}One message, with the body that was rendered
POST/api/mail/outbox/{id}/requeueTry a dead message again (author)
POST/api/mail/outbox/{id}/cancelStop one that has not gone yet (author)
POST/api/mail/dispatchRun a dispatch pass now instead of waiting (author)
POST/api/mail/testQueue 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_FULLCS401 has a capacity of 3 — enrol four students
ENROLLMENT_WINDOW_CLOSEDCS150's window closed last year
PREREQUISITES_NOT_METCS401 requires CS101 and CS301
STUDENT_NOT_ELIGIBLEStudent 100004 is suspended
DUPLICATE_RESOURCEEnrol the same student twice
INVALID_GRADEAward lode with a grade below 30