Module Breakdown
Each module lives under
src/modules/<module>, with its own Controllers, Services, and Repositories.
4.1 Authentication
- Controllers:
AuthController(/auth/signup,/auth/login,/auth/token) exposes sign-up, login, and token endpoints. - Service:
FirebaseAuthServicewraps Firebase Admin SDK for user creation, JWT issuance, and token verification. - Repository: Minimal, since Firebase is the source of truth; local DB used for profile data only.
Why? Offloads heavy lifting to Firebase—leveraging its scalability, secure token management, and built-in user lifecycle.
4.2 Courses
- Controllers:
CourseControllerendpoints (/courses,/courses/:id/versions, etc.) - Service:
CourseServiceimplements versioning logic, content locking, and draft/publish workflows. - Repository:
CourseRepositorydefines schemas forCourse,Version,Module,Section, andItemsubdocuments.
Why? Versioning courses independently supports safe iteration and rollbacks; keeping content hierarchies in subdocuments optimizes read performance.
4.3 Quizzes
- Controllers:
QuizControllerfor managing quizzes and attempts. - Service:
QuizServiceuses a factory pattern to handle different question types (SOL, SML, OTL, NAT, DES). - Repository:
QuizRepository,QuestionBankRepository, andAttemptRepositoryseparate concerns for question storage vs. attempt tracking.
Why? Quiz logic is inherently complex—isolating types and attempts into dedicated repos and services maintains clarity and testability.
4.4 Users
- Controllers:
UserController(/users/:id/enroll,/users/:id/progress) - Service:
EnrollmentServiceandProgressServicetrack course enrollments and watch-time. - Repository:
UserRepositorywith methods for progress snapshots, watch-time aggregates, and profile updates.
Why? Separating enrollment from progress allows flexible business rules (e.g., free vs. paid courses, quiz retakes).
4.5 Notifications
- Controllers:
NotificationController(/notifications/invite,/notifications/status) - Service:
MailService(SMTP) andInviteServicemanage email invites and status tracking. - Repository:
InviteRepositorystores invite tokens, expiration, and status.
Why? Decoupling email transport from invite logic simplifies swapping providers or adding in-app notification channels later.
4.6 Settings
- Controllers:
SettingsController(/settings/proctoring,/settings/custom) - Service:
SettingsServicereads/writes course- and user-level settings. - Repository:
SettingsRepositorywith JSON-schema–validated storage.
Why? Proctoring and custom flags vary by course; having a dedicated module keeps these concerns isolated.
4.7 Anomalies
- Controllers:
AnomalyController(/anomalies,/anomalies/:id) - Service:
AnomalyServicesubscribes to watch-time events and applies threshold rules. - Repository:
AnomalyRepositorystores anomaly records with metadata (userId, courseId, timestamp).
Why? Early detection of suspicious behavior protects academic integrity and platform health.
4.8 GenAI
- Controllers:
GenAIController(/genai/questions,/genai/summaries) - Service:
GenAIServicewraps OpenAI (or Ollama) clients, handles prompt templates and rate limits. - Repository: Optionally caches generated content in
GenAIRepositoryto avoid redundant API calls.
Why? Centralizing prompt engineering and caching improves consistency, costs control, and performance.