Course Module Feature Guide
Functional breakdown of admin and learner capabilities, lifecycle states, and production behavior.
Course - Feature Guide
1. Feature Overview
Course module delivers a full LMS capability on top of the commerce stack:
- sellable course publishing tied to catalog products,
- structured learning runtime (topic/lesson/resource + progress),
- assessment runtime (quiz attempts/scoring),
- completion credentialing (certificate template + issuance + verification).
It is intentionally split by actor:
- Admin controls structure, quality, and publishability.
- Customer/mobile consumes and progresses.
- Public only verifies issued certificates.
2. Route Ownership and Surfaces
| Surface | Prefix | Owner module |
|---|---|---|
| Admin courses | /api/admin/courses | CourseAdminModule, TopicAdminModule, LessonAdminModule, QuizAdminModule, ResourceAdminModule, ReviewAdminModule |
| Admin certificates | /api/admin/certificates | CertificateAdminModule |
| Customer runtime | /api/courses | DiscoveryCustomerModule, PurchaseCustomerModule, LearningCustomerModule, QuizCustomerModule, CertificateCustomerModule, CourseReviewCustomerModule |
| Mobile runtime | /api/mobile/courses | mobile.module.ts composition with customer leaf modules |
| Public verify | /api/certificates | CourseModule (PublicCertificateController) |
2.1 Swagger grouping (current)
Admin groups in Swagger:
Course Management (Admin)Course Topics (Admin)Course Lessons (Admin)Course Quiz (Admin)Course Resources (Admin)Course Reviews (Admin)Course Certificates (Admin)
Mobile/customer groups in Swagger:
Course Discovery (Mobile)Course Purchases (Mobile)Course Learning (Mobile)Course Quiz (Mobile)Course Certificates (Mobile)Course Reviews (Mobile)
3. Admin Feature Matrix
| Domain | Features |
|---|---|
| Course | Create/update/delete, status lifecycle, sellable toggle, product link/unlink, auto-create product, accessValidityDays |
| Topic | List/create/update/delete/reorder per course |
| Lesson | List/create/update/delete/reorder per topic, lesson-type payload validation |
| Resource | List/create/delete, attach by course/topic/lesson with targeting constraints |
| Review | List/create/update/delete, fake reviewer profile fields (reviewerName, reviewerEmail), image attach, hidden toggle |
| Quiz | Create/update/delete quiz config, list/create/update/delete/reorder questions |
| Certificate | Template CRUD + active filter + issued certificate listing |
Admin protections:
JwtAuthGuard + RoleGuardon all admin controllers- typed permission codes (
Courses_READ/CREATE/UPDATE/DELETE) - Redis sliding-window rate limiting per action
4. Customer/Mobile Feature Matrix
| Stage | Features |
|---|---|
| Discovery | List published sellable courses, slug detail with historical slug fallback, list visible reviews + review summary by slug |
| Purchase view | List purchased courses and purchase detail, including access window visibility (validityDays, accessStartAt) |
| Learning | Curriculum tree, lesson content retrieval, lesson completion update, progress summary |
| Quiz | Quiz eligibility/detail, start attempt, attempts list, attempt detail, submit for score |
| Certificate | Eligibility check, generation request, certificate detail/list |
| Public trust | No-auth certificate verification by certificate number |
Learner protections:
- JWT required for purchase/learning/quiz/certificate runtime
- entitlement + expiry checks before protected learning actions
- Redis sliding-window rate limiting per action
5. Key Business Rules
5.1 Course Publication and Sellability
A course is customer-discoverable only when:
status = "published"isSellable = true
5.2 Entitlement Rule
Protected runtime (curriculum, lessons, progress, quiz, certificate) requires valid product_access.
Access is granted after successful payment and expires based on courses.accessValidityDays (null = lifetime). Learners can view their remaining access window via the purchase detail endpoint.
5.3 Quiz Rule
- user must complete course lessons before starting quiz
- max attempts enforced by quiz config
- submit path rejects expired attempts and duplicate submit
5.4 Certificate Rule
Generation is allowed only when:
- certificate feature enabled
- entitlement active
- course complete
- quiz passed when quiz is enabled
Generation is idempotent at queue + DB layers.
5.5 Schema Integrity Rules
- certificate template names are unique across the system (
certificate_template_name_unique) - course access validity is
null(lifetime) or a strictly positive day count (course_access_validity_days_positive_check) - duplicate template-name creates with different payload are rejected to prevent ambiguous template state
6. State Models
6.1 Course Status Lifecycle
6.2 Learner Journey
7. Caching Strategy
- Discovery list/detail and quiz detail use Redis cache keyspaces with deterministic key construction.
- Admin read surfaces (course list/detail, topic/lesson/resource/review lists, quiz reads, certificate template reads) are cached and invalidated by write paths.
8. Rate Limiting
Action-scoped Redis keys (rl:courses:*, rl:certificates:public:*) are used across admin/customer/public controllers.
Configuration:
- common:
CONTENT_ADMIN_RATE_LIMIT,CONTENT_ADMIN_RATE_WINDOW_SECONDS - public certificate override:
COURSE_CERTIFICATE_VERIFY_RATE_LIMIT,COURSE_CERTIFICATE_VERIFY_RATE_WINDOW_SECONDS
9. Queue/Worker Feature Behavior
Certificate generation feature uses BullMQ:
- queue:
courses - job:
course.generate_certificate - dedupe key:
jobId = cert:<userId>:<courseId> - retries/backoff from environment
- worker logs start/skip/success/failure with correlation context
- duplicate certificate creation avoided by DB unique + conflict-safe insert
10. Error UX Mapping
| Scenario | API behavior | Recommended UI |
|---|---|---|
| Course not found/unpublished | 404 | not-found screen |
| Not purchased | 403 on protected runtime | redirect to purchase CTA |
| Access expired | 403 | renewal/repurchase message |
| Quiz cap reached | 400 | disable start CTA + show attempt summary |
| Quiz timer expired | 400 | prompt restart if attempts remain |
| Certificate not yet generated | eligibility false or 404 detail | show generate/poll state |
| Public invalid certificate number | 200 with isValid=false | invalid badge + retry input |
| Rate-limited | 429 | transient backoff toast/dialog |
11. Release/QA Checklist (Feature-Focused)
- Course lifecycle and sellable visibility verified end-to-end.
- Product linkage correctness validated (
productType=course, uniqueness). - Curriculum ordering and reordering behavior validated for topics/lessons.
- Lesson-type specific required payload checks validated.
- Quiz attempt edge cases validated (in-progress reuse, cap, timeout, double submit).
- Certificate generation validated for:
- queued path,
- already-generated path,
- ineligible reason paths.
- Public certificate verification verified for both valid and invalid numbers.
- Mobile-composed
/api/mobile/courses/*routes confirmed equivalent to customer contracts.
Time fields in this module are stored as timezone-aware values and should be handled as ISO-8601 instants by API consumers.
See Also
- API Reference: See Course - API & Integration Guide Section 11 (Endpoint Reference + Payload Cheatsheet) for complete request/response DTOs.
- Backend Reference: See Course - Backend Documentation Section 3 (Data Model) for schema details.