Skip to content

feat: Student course catalog#97

Merged
ebouchut merged 4 commits into
devfrom
feat/student-course-catalog
Jul 13, 2026
Merged

feat: Student course catalog#97
ebouchut merged 4 commits into
devfrom
feat/student-course-catalog

Conversation

@ebouchut

@ebouchut ebouchut commented Jul 13, 2026

Copy link
Copy Markdown
Owner

ebouchut added 4 commits July 13, 2026 10:15
Students can browse the published courses at /courses and open a
course page listing its published lessons. CourseService owns the
student visibility rule: PUBLISHED is visible, an enrolled student
keeps read access to an ARCHIVED course, DRAFT is never visible, and
invisible content answers 404 so drafts do not leak. New derived
queries: lessons by course and status in reading order, enrollment by
(user, course). The navigation gains a Courses entry for logged-in
users, and the security matrix tightens /courses from gate-pass 404 to
200 now that the controller exists.
EnrollmentService owns the student-side lifecycle: enrolling is
idempotent, only published courses accept new enrollments (404
otherwise, drafts do not leak), a DROPPED row is re-activated instead
of inserted twice (the (user, course) pair is the primary key), and
dropping stamps dropped_at while leaving COMPLETED untouched.

The course page gains Register and Quit actions (POST + CSRF, PRG
redirects with ?enrolled / ?dropped confirmation alerts, matching the
?registered idiom), hides Register on non-published courses, and the
catalogue marks the courses the student is enrolled in.
An actively enrolled student reads a published lesson at
/courses/{courseId}/lessons/{lessonId}: the Markdown is rendered to
sanitized HTML by MarkdownRenderer (cached, ADR-0013) and emitted with
th:utext, with previous/next links in reading order. A student who is
not enrolled is redirected to the course page with an enroll-required
hint instead of a 403 (the Register button is right there). Lessons
that are draft, archived, or belong to another course answer 404. The
course page lesson list now links each lesson.
The dashboard placeholder becomes the real "My courses" view: the
active enrollments of the logged-in user (dropped ones excluded), each
with its status and enrollment date, linking back to the course page.
GET /dashboard moves from AuthController to a DashboardController in
the course package, since the page renders enrollment data.

StudentCourseFlowTest drives the whole student journey end to end:
browse (draft courses hidden), bounce off a lesson before enrolling,
enroll, read a lesson (Markdown rendered to HTML), reject an unknown
lesson, see the dashboard list the course, drop, and see it gone.
Base automatically changed from feat/course-security-foundation to dev July 13, 2026 09:38
@ebouchut ebouchut self-assigned this Jul 13, 2026
@ebouchut ebouchut moved this to In Review in learn-dev-project Jul 13, 2026
@ebouchut ebouchut added this to the v0.9 - Code Freeze milestone Jul 13, 2026
@ebouchut ebouchut added test auth Authentication & authorization (login, sessions, password reset, tokens) labels Jul 13, 2026
@ebouchut ebouchut merged commit d4245e5 into dev Jul 13, 2026
1 check passed
@ebouchut ebouchut deleted the feat/student-course-catalog branch July 13, 2026 09:46
@github-project-automation github-project-automation Bot moved this from In Review to Done in learn-dev-project Jul 13, 2026
@ebouchut ebouchut changed the title feat/student-course-catalog feat: Student course catalog Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auth Authentication & authorization (login, sessions, password reset, tokens) backend frontend test

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant