Skip to main content

Technical Documentation: Learnille Server

1. Introduction

1.1. Purpose This document provides detailed technical information for developers working on or integrating with the Learnille Server. It covers project setup, architecture, core technologies, module deep dives, API reference, development practices, and troubleshooting. 1.2. Getting Started 1.2.1. Prerequisites

  • Node.js (Version 22, as specified in package.json)
  • npm (comes with Node.js)
  • PostgreSQL (Version 14+ recommended by README.md in documentation folder, though not explicitly in server's package.json)
  • Redis (Version 7.0 recommended)
  • Access to other services as per src/config.ts for full functionality (Elasticsearch, ClickHouse, Novu, Paystack, S3, InstantDB, Shlink, Google).
  • Docker (optional, for running dependencies like Triplit server via docker-compose.yml). 1.2.2. Repository Setup
  • Clone the repository from the provided Git source.
  • Follow standard Git branching strategies if applicable. 1.2.3. Installation
  • Navigate to the server directory.
  • Run npm install to install dependencies listed in package.json. 1.2.4. Environment Configuration
  • Create environment-specific .env files within an env/ directory inside server/ (e.g., server/env/.env.local, server/env/.env.development).
  • Refer to server/src/config.ts (the validationSchema object) for the full list of required and optional environment variables. Key variables include database credentials, API keys for third-party services, JWT secrets, etc.
  • An example .env.example file should ideally be created and maintained at server/env/.env.example. 1.2.5. Running the Application
  • Local Development (with hot-reloading): npm run watch:local (sets NODE_ENV=local)
  • Development (without hot-reloading): npm run start:dev (sets NODE_ENV=development)
  • Staging: npm run start:staging (sets NODE_ENV=staging)
  • Production: npm run start:prod (sets NODE_ENV=prod) or using PM2: npm run start:pm2:prod
  • The application typically runs on port 3000 (or process.env.PORT). 1.2.6. Running Tests
  • Run all tests: npm test
  • Run tests with coverage: npm run test:cov
  • Run E2E tests: npm run test:e2e (requires separate Jest config test/jest-e2e.json)

2. Project Structure

2.1. Overview of Key Directories (within server/)

  • src/: Contains all TypeScript source code.
  • env/: (Convention) Should contain environment-specific .env files.
  • dist/: Output directory for compiled JavaScript code (generated by npm run build).
  • test/: Contains end-to-end test configurations and possibly tests.
  • node_modules/: Contains installed npm packages. 2.2. Structure of src/
  • main.ts: Application entry point.
  • app.module.ts: Root NestJS module.
  • config.ts: Defines environment variable validation schema (validationSchema) and Config interface.
  • data-source.ts: Defines a TypeORM AppDataSource (likely for CLI use or defaults).
  • instrument.ts: Early instrumentation setup (e.g., Sentry).
  • Module-specific directories (e.g., users/, auth/, course/, payments/): Each contains controllers, services, modules, entities, DTOs for a specific feature.
  • common/: Likely contains shared utilities, decorators, pipes, guards, interceptors, filters.
  • assets/: Static assets, like MJML email templates, copied to dist/ during build.
  • database/: (Convention, if DatabaseModule is custom) Might contain database module setup.
  • winston/: Contains Winston logger service.
  • (Other directories for specific integrations like redis/, elastic/, bullmq/, novu/, etc.) 2.3. Key Configuration Files (at server/ root)
  • package.json: Project metadata, dependencies, scripts.
  • nest-cli.json: NestJS CLI configuration (source root, assets, plugins like Swagger).
  • tsconfig.json: TypeScript compiler options.
  • docker-compose.yml: Defines services for local development (currently only triplit-server).
  • .eslintrc.js, .prettierrc: ESLint and Prettier configurations for code linting and formatting.

3. Core Technologies & Concepts

3.1. NestJS:

  • Modules (@Module): Organize code into reusable units. AppModule is the root.
  • Controllers (@Controller): Handle incoming HTTP requests and send responses.
  • Services (@Injectable): Encapsulate business logic, injected into controllers or other services.
  • Providers: Services, repositories, factories, helpers, etc., managed by NestJS DI.
  • Pipes (@PipeTransform): Transform or validate input data (e.g., ValidationPipe).
  • Guards (@CanActivate): Determine if a request can be handled by a route (e.g., JwtAuthGuard, CaslGuard).
  • Interceptors (@NestInterceptor): Bind extra logic before/after route handler execution (e.g., ResponseInterceptor).
  • Filters (@ExceptionFilter): Handle unhandled exceptions across the application (e.g., AllExceptionsFilter).
  • Decorators: Extensively used for metadata (e.g., @Get(), @Post(), @Body(), @CurrentUser()). 3.2. TypeORM:
  • Entities (@Entity): Define database table structures.
  • Repositories (@Repository or custom): Provide methods for database operations.
  • DataSource: Configuration object for database connections (seen in data-source.ts).
  • Migrations: Managed via scripts in package.json (e.g., npm run migrations:run).
  • Seeding: Scripts in package.json for populating initial data. 3.3. Configuration Management:
  • @nestjs/config with ConfigService.
  • .env files in env/ directory, selected by NODE_ENV.
  • Joi validation schema in src/config.ts.
  • Type-safe access using Config interface. 3.4. Logging:
  • nestjs-pino or Winston (conditional in main.ts).
  • AppRequestLoggerMiddleware for logging HTTP requests.
  • Sentry for error and performance monitoring. 3.5. Error Handling:
  • AllExceptionsFilter for global, standardized error responses.
  • Custom exceptions per module (e.g., PhotoNotFoundException).
  • Sentry integration in main.ts and for unhandled process exceptions. 3.6. Authentication & Authorization:
  • JWT (JSON Web Tokens) for stateless authentication.
  • Passport.js strategies (LocalStrategy, JwtStrategy, GoogleStrategy).
  • Guards (JwtAuthGuard, LocalAuthGuard, GoogleAuthGuard, LoginAuthGuard).
  • @CurrentUser() decorator to access authenticated user data.
  • CASL for fine-grained, ability-based authorization (seen in CourseController). 3.7. Background Jobs with BullMQ:
  • BullmqCustomModule for setup.
  • Used for tasks that can be processed asynchronously.
  • BullBoard for monitoring queues (setup in AppModule). 3.8. Caching with Redis:
  • RedisModule for integration.
  • Used by ThrottlerModule for rate limiting.
  • Potentially for application-level caching via CacheModule (if used). 3.9. API Documentation with Swagger:
  • @nestjs/swagger plugin enabled in nest-cli.json.
  • Setup in main.ts, available at /docs endpoint.
  • Controllers and DTOs use decorators like @ApiTags, @ApiOperation, @ApiBody, @ApiResponse, @ApiProperty for documentation. 3.10. Email Sending:
  • @nestjs-modules/mailer with Handlebars templates (src/assets/templates/*.mjml). 3.11. Notifications with Novu:
  • NovuModule integration.
  • WorkflowsService defines notification workflows.
  • Used for events like email verification, password reset.

4. Module Deep Dive

4.1. Module: Users (src/users/) 4.1.1. Purpose and Responsibilities: Manages user profiles, core user data, roles, and profile picture handling. Provides services for user creation, retrieval, and updates. 4.1.2. Key Files:

  • users.module.ts: Imports TypeORM for User & Login entities, CryptoModule, GoogleModule, FilesModule, AuthModule. Exports UsersService.
  • users.controller.ts: Handles /user route. Endpoints for fetching (GET /) and updating (PUT /) the authenticated user's profile. Uses JwtAuthGuard and @CurrentUser().
  • users.service.ts: Contains logic for createUser (hashes password), getUserProfile (formats response, gets photo URL), updateUser (processes photo), findLoginWithUser, addUserTag, removeUserTag. Interacts with UsersRepository, CryptoService, FilesService.
  • entities/user.entity.ts: Defines the User schema with fields like id, name, email, password (hashed), roles, photo (OneToOne with File), verified status, timestamps, tags, etc.
  • dto/: Contains DTOs like UserCreate, UserUpdate, UserResponseDto. 4.1.3. API Endpoints (from UsersController):
  • GET /user: Get current authenticated user's profile. (Protected by JWT)
    • Response: UserResponseDto
  • PUT /user: Update current authenticated user's profile. (Protected by JWT)
    • Request Body: UserUpdate
    • Response: UserResponseDto 4.1.4. Data Models:
  • User entity (see user.entity.ts for details). 4.1.5. Core Workflows & Business Logic:
  • Profile Fetching: Retrieve user, get public URL for photo if exists.
  • Profile Update: Validate input, process photo (check existence, MIME type, usage by others), update user record.
  • User Creation (in service): Hash password, save user. 4.1.6. Events Emitted/Handled: (Not explicitly seen in these files, but AuthService emits USER_REGISTRATION_SUCCESSFUL which involves UsersService).

4.2. Module: Auth (src/auth/) 4.2.1. Purpose and Responsibilities: Handles all aspects of user authentication, including registration, login (local, Google), password management (change, forgot, reset), email verification, and JWT generation/validation. 4.2.2. Key Files:

  • auth.module.ts: Imports PassportModule, UsersModule, GoogleModule, CryptoModule, TypeORM for Login, User, ForgotPassword, VerifyEmail entities. Provides strategies, guards, AuthService, LoginsService. Exports AuthService.
  • auth.controller.ts: Handles /auth routes. Endpoints for check-email, register, login, change-password, code (request verification/reset code), forgot-password, reset-password, verify-email.
  • auth.service.ts: Core logic for all auth operations. Interacts with UsersService, CryptoService, notification services (WorkflowsService), and repositories for ForgotPassword, VerifyEmail. Generates codes, signs JWTs, validates credentials.
  • entities/: Contains Login, ForgotPassword, VerifyEmail entities.
  • guards/: Contains JwtAuthGuard, LocalAuthGuard, GoogleAuthGuard, LoginAuthGuard.
  • strategies/: Contains LocalStrategy, JwtStrategy, GoogleStrategy.
  • dto/: Contains DTOs like UserRegisterDto, LoginDto, ChangePasswordDto, ResetPasswordDto, VerifyEmailDto. 4.2.3. API Endpoints (from AuthController):
  • GET /auth/check-email?email=<email>: Check if email is available.
  • POST /auth/register: Register a new user. Body: UserRegisterDto. Response: RegisterResponse (includes JWT).
  • POST /auth/login: Login with email/password. Body: LoginDto. Response: LoginResponse (includes JWT). (Protected by LoginAuthGuard)
  • POST /auth/change-password: Change password for authenticated user. Body: ChangePasswordDto. (Protected by JwtAuthGuard)
  • POST /auth/code: Request a verification/reset code. Body: RequestCodeDto.
  • GET /auth/forgot-password?email=<email>: Initiate forgot password flow.
  • POST /auth/reset-password: Reset password using code. Body: ResetPasswordDto.
  • POST /auth/verify-email: Verify email using code. Body: VerifyEmailDto. 4.2.4. Data Models:
  • Login entity: Tracks login attempts/sessions.
  • ForgotPassword entity: Stores tokens for password reset.
  • VerifyEmail entity: Stores tokens for email verification. 4.2.5. Core Workflows & Business Logic:
  • Registration: Validate email, create user (via UsersService), create role-specific profile, trigger Novu verification email, return JWT.
  • Login: Validate credentials (via LocalStrategy), generate JWT.
  • Password Reset: Generate code, store it, send via Novu, verify code, update password, trigger Novu notification.
  • Email Verification: Generate code, store it, send via Novu, verify code, update user's verified status. 4.2.6. Events Emitted/Handled: Emits AppEvents.USER_REGISTRATION_SUCCESSFUL after successful registration. UserRegisteredListener likely handles this.

4.3. Module: Course (src/course/) 4.3.1. Purpose and Responsibilities: Manages all aspects of e-learning courses, including creation, content organization (sections, subsections, items), instructor associations, pricing, publishing, and retrieval. 4.3.2. Key Files:

  • course.module.ts: Imports TypeORM for numerous course-related entities (Course, CourseSection, Instructor, Category, etc.). Integrates StorageModule, ElasticModule, EnrollmentModule. Provides CourseService, CourseSectionService, etc. Exports CourseService.
  • course.controller.ts: Handles /course routes. Extensive endpoints for CRUD on courses, sections, subsections, items. Also handles course levels, properties (requirements, audience), summaries, and statistics. Uses JwtAuthGuard, CaslGuard, @AllowPublicView. Implements pagination.
  • course.service.ts: Core logic for course creation (validation, slug generation, file handling, manager assignment), retrieval (single, paginated list with processed output including file URLs), updates (ownership checks), deletion. Interacts with many repositories and services (FilesService, SlugService, CourseElasticService, TextWithIconService).
  • entities/course.entity.ts: Defines the main Course schema with fields for title, content structure, pricing, instructor, category, files, status, etc.
  • entities/sections.entity.ts, subsections.entity.ts, course_item.entity.ts, level.entity.ts, requirement.entity.ts: Define related data models.
  • dto/: Contains DTOs like CreateCourseDto, UpdateCourseDto, CourseResponseDto, DTOs for sections, subsections, items. 4.3.3. API Endpoints (Selected from CourseController):
  • POST /course: Create a new course. Body: CreateCourseDto. (Protected by JWT, CASL)
  • GET /course: Get all courses (paginated). (Protected by JWT, filters by instructor)
  • GET /course/slug/:slug: Get course by slug. (Publicly viewable with view options)
  • GET /course/:id: Get course by ID. (Publicly viewable with view options)
  • PUT /course/:id: Update a course. Body: UpdateCourseDto. (Protected by JWT, CASL)
  • DELETE /course/:id: Delete a course. (Protected by JWT, CASL)
  • CRUD endpoints for /course/section, /course/subsection, /course/item.
  • Endpoints for /course/levels, /course/summaries/:id, /course/:id/statistics.
  • Endpoints for managing course properties (requirements, etc.) like /course/:courseId/:type/replace. 4.3.4. Data Models:
  • Course entity (see course.entity.ts for details).
  • CourseSection, CourseSubSection, CourseItem, Level, Requirement, Inclusion, Audience entities. 4.3.5. Core Workflows & Business Logic:
  • Course Creation: Extensive validation, file handling for thumbnail/video, slug generation, linking to instructor/category, creating manager associations, emitting COURSE_CREATED event.
  • Course Retrieval: Fetching course with relations, processing file URLs, serializing output based on view groups. Paginated listing with filtering.
  • Course Update: Ownership validation, updating fields and relations.
  • Content Management: CRUD operations for hierarchical course content (sections, subsections, items). 4.3.6. Events Emitted/Handled: Emits AppEvents.COURSE_CREATED.

4.4. Module: Consultation (src/consultation/) 4.4.1. Purpose and Responsibilities: Manages the creation, scheduling, booking, delivery, and review of consultation services. Supports one-off and recurring consultation types, consultant availability management, and payment integration. 4.4.2. Key Files:

  • consultation.module.ts: Imports TypeORM for Consultation, Booking, ConsultationTimeSlot, ConsultationSession, OneOffConsultationMeta, RecurringConsultation, etc. Integrates ElasticModule, FilesModule, SharedModule, ReviewsModule, CategoryModule. Provides ConsultationService, SessionsService, TimeslotService.
  • consultation.controller.ts: Handles /consultation routes. Endpoints for CRUD on consultation offerings, managing availability (timeslots), booking, handling one-off/recurring specifics, and managing descriptive properties (benefits, questions). Uses JwtAuthGuard, @AllowPublicView.
  • consultation.service.ts: Core logic for creating/updating consultation offerings (validating consultant, category, files, sale dates, type-specific meta), finding consultations (single, paginated with processed output including file URLs), managing bookings, and interacting with timeslot/session logic. Integrates with ProductAccessService, FilesService, SlugService, ElasticService, NotificationService.
  • sessions.service.ts: Logic for managing consultation sessions and checking timeslot availability.
  • timeslot.service.ts: Logic for consultants to define and manage their availability.
  • entities/consultation.entity.ts: Main schema for consultation offerings (title, description, consultant, type, pricing, scheduling rules, links to properties, sessions).
  • entities/booking.entity.ts: Schema for user bookings.
  • entities/timeslot.entity.ts: Schema for consultant availability slots.
  • entities/sessions.entity.ts: Schema for individual consultation sessions.
  • entities/oneoff.entity.ts, recurring-consultation.entity.ts: Schemas for type-specific metadata.
  • dto/: Contains DTOs like CreateConsultationDto, UpdateConsultationDto, CreateBookingDto, ConsultationAvailabilityDto, OneoffInfoDto, RecurringInfoDto, ConsultationResponseDto. 4.4.3. API Endpoints (Key Examples from ConsultationController):
  • POST /consultation: Create a new consultation offering. (Protected)
  • GET /consultation: Get all consultations (paginated). (Protected)
  • GET /consultation/:id or GET /consultation/slug/:slug: Get specific consultation. (Publicly viewable)
  • PUT /consultation/:id: Update consultation. (Protected)
  • POST /consultation/booking: Create a new booking. (Protected)
  • PUT /consultation/:consultationId/availability: Update consultant's availability for a consultation. (Protected)
  • GET /consultation/:consultationId/availability: Get availability for a consultation. (Protected)
  • POST /consultation/:consultationId/oneoff or /recurring: Add type-specific details. (Protected)
  • CRUD endpoints for properties like benefits, questions under /consultation/:consultationId/:type. (Protected) 4.4.4. Data Models:
  • Consultation entity (details key fields like consultant, type, pricing, scheduling rules, links to sessions, bookings, properties).
  • Booking entity (links user to consultation/session, status).
  • ConsultationTimeSlot entity (defines consultant's available slots).
  • ConsultationSession entity (represents an actual scheduled session). 4.4.5. Core Workflows & Business Logic:
  • Consultation Creation: Validation of consultant, category, files; generation of slug; setting default availability; emitting CONSULTATION_CREATED event.
  • Consultation Retrieval: Fetching with relations, processing file URLs, serializing based on view groups, fetching type-specific metadata.
  • Availability Management: Consultants define timeslots; service checks for conflicts.
  • Booking: User selects consultation & timeslot; system validates availability, creates booking, potentially links to a session, initiates payment. 4.4.6. Events Emitted/Handled: AppEvents.CONSULTATION_CREATED, AppEvents.CONSULTATION_UPDATED.

4.5. Module: Payments (src/payments/) 4.5.1. Purpose and Responsibilities: Handles all financial transactions, including processing payments for orders via gateways like Paystack, managing payment records, and providing user wallet functionalities (balance, withdrawals). 4.5.2. Key Files:

  • payments.module.ts: Imports TypeORM for Payment, CoursePayment, ConsultationPayment, Withdrawal, Order, Coupon entities. Integrates PaystackModule, UsersModule, EnrollmentModule, CourseModule, ConsultationModule, CouponModule, CartModule. Provides PaymentsService, WalletService.
  • payments.controller.ts: Handles /payment routes. Endpoints for creating payments (POST /), finding user's payments (GET /), finding a specific payment (GET /:id), regenerating payment links (POST /regenerate-link), and a Paystack webhook (POST /paystack-webhook).
  • wallet.controller.ts: Handles /wallet routes. Endpoints for provider payment overview (GET /overview/:providerId) and revenue charts (GET /revenue-chart/:providerId).
  • payments.service.ts: Core logic for initiating payments (via _initiatePaymentForOrder which interacts with PaystackService), creating Payment records, retrieving payment history.
  • wallet.service.ts: Logic for calculating provider earnings, balances, processing withdrawal requests (creation part), and generating revenue reports.
  • entities/payment.entity.ts: Main schema for payment transactions (amount, fees, currency, status, gateway info, links to Order, Payer (User), Student (beneficiary)).
  • entities/withdrawal.entity.ts: Schema for user withdrawal requests, including amount and status (PENDING, COMPLETED, etc.).
  • dto/: Contains DTOs like CreatePaymentDto, RegeneratePaymentLinkDto, PaymentResponseDto, GetOverviewResponseDto. 4.5.3. API Endpoints (Key Examples):
  • From PaymentsController:
    • POST /payment: Initiate a payment for an order. Body: CreatePaymentDto. (Protected)
    • GET /payment: Get authenticated user's payment history (paginated). (Protected)
    • GET /payment/:id: Get details of a specific payment. (Protected)
    • POST /payment/regenerate-link: Regenerate payment link for an order. Body: RegeneratePaymentLinkDto. (Protected)
    • POST /payment/paystack-webhook: Handles Paystack webhook events (Unauthenticated, internal).
  • From WalletController:
    • GET /wallet/overview/:providerId: Get payment overview for a provider. (Protected)
    • GET /wallet/revenue-chart/:providerId?period=<period>: Get revenue chart data for a provider. (Protected, admin can specify providerId) 4.5.4. Data Models:
  • Payment entity (details key fields: amount, fees, currency, status, gateway, ref, links to Order, Payer, Student).
  • Withdrawal entity (links to User, amount, status). 4.5.5. Core Workflows & Business Logic:
  • Payment Initiation: Triggered by OrderService (likely). PaymentsService validates order, prepares data, calls gateway service (PaystackService) to get auth URL. A Payment record is created in PENDING state.
  • Payment Confirmation: Paystack webhook hits controller, PaystackService processes it, PaymentsService (or OrderService via events) updates Payment and Order status. Post-payment actions (enrollment, notifications) are triggered.
  • Wallet Operations:
    • Balance Calculation: WalletService calculates a provider's balance by subtracting total completed withdrawals from their total earnings (final amount from payments where they are the provider).
    • Revenue Reporting: Provides data for revenue charts over specified periods for providers.
    • Withdrawal Requests: WalletService allows for the creation of Withdrawal records in a PENDING state. (Actual processing/payout mechanism is not detailed in this service).
    • Overview: Provides a consolidated view of a provider's total sales, withdrawals, and current balance. 4.5.6. Events Emitted/Handled: (Events are likely emitted upon successful payment confirmation to trigger other module actions like enrollment, rather than during initiation).

4.6. Module: Instructors (src/instructors/) 4.6.1. Purpose and Responsibilities: Manages instructor-specific profiles, their professional details (experience, achievements, expertise), resume, and their association with courses and the base user system. 4.6.2. Key Files:

  • instructors.module.ts: Imports TypeORM for Instructor, User, CourseManager. Integrates CourseModule, SharedModule, FilesModule, EnrollmentModule. Provides InstructorsService.
  • instructors.controller.ts: Handles /instructor routes. Endpoints for creating (POST /), fetching (GET /:id?, with public/private views), updating (PUT /:id), and deleting (DELETE /:userId, admin-only) instructor profiles. Also includes endpoints for managing instructor availability via a shared ProviderService.
  • instructors.service.ts: Core logic for CRUD operations on instructor profiles. Handles linking to User, managing achievements and experiences (via ProviderService), resume uploads (via FilesService), and cascading deletion of courses upon instructor removal. Performs access checks for updates/deletions. Provides an overview endpoint integrating with EnrollmentService.
  • entities/instructor.entity.ts: Defines the Instructor schema with fields for overview, description, expertise, languages, position, institution, social links, and relations to User (OneToOne), Course (OneToMany), File (for resume), Experience, and Achievement.
  • entities/manager.entity.ts: Defines a course manager, linking an instructor to a course in a managerial capacity.
  • dto/: Contains DTOs like CreateInstructorDto, UpdateInstructorDto, InstructorResponseDto. 4.6.3. API Endpoints (Key Examples from InstructorsController):
  • POST /instructor: Create an instructor profile for the authenticated user. Body: CreateInstructorDto. (Protected)
  • GET /instructor/:id? (or by email/slug): Get instructor profile. (Publicly viewable with view options)
  • PUT /instructor/:id: Update instructor profile (user ID as :id). Body: UpdateInstructorDto. (Protected, owner/admin)
  • DELETE /instructor/:userId: Delete instructor profile. (Admin-only)
  • GET /instructor/overview/:id?: Get instructor overview/statistics. (Protected)
  • GET /instructor/availability, PUT /instructor/availability: Manage instructor availability (via ProviderService). (Protected) 4.6.4. Data Models:
  • Instructor entity (details key fields: link to User, overview, expertise, experiences, achievements, resume, courses).
  • CourseManager entity (links Instructor to Course as a manager). 4.6.5. Core Workflows & Business Logic:
  • Profile Creation: Link to existing User, add Instructor role to User, save professional details (experiences, achievements via ProviderService), handle resume upload. Emit INSTRUCTOR_CREATED event.
  • Profile Retrieval: Fetch instructor and associated user data, format resume URL, serialize based on view groups.
  • Profile Update: Access control, update fields, handle resume/experience/achievement updates. Emit INSTRUCTOR_UPDATED event.
  • Profile Deletion (Admin): Cascade delete associated courses, then delete instructor profile. Emit INSTRUCTOR_REMOVED event. 4.6.6. Events Emitted/Handled: AppEvents.INSTRUCTOR_CREATED, AppEvents.INSTRUCTOR_UPDATED, AppEvents.INSTRUCTOR_REMOVED.

4.7. Module: Consultant (src/consultant/) 4.7.1. Purpose and Responsibilities: Manages consultant-specific profiles, their professional details (experience, achievements, expertise), resume, availability, and their association with consultation services and the base user system. 4.7.2. Key Files:

  • consultant.module.ts: Imports TypeORM for Consultant, User, Achievement, Experience, File, Availability, TimeSlot, and various consultation-related entities. Integrates SharedModule, ReviewsModule, FilesModule. Provides ConsultantService and re-provides SessionsService (from consultation module).
  • consultant.controller.ts: Handles /consultant routes. Endpoints for creating (POST /), fetching (GET /:id?, with public/private views), updating (PUT /:userId), and deleting (DELETE /:userId) consultant profiles. Also includes endpoints for managing consultant availability (via ProviderService) and viewing calendar events/upcoming sessions (via SessionsService).
  • consultant.service.ts: Core logic for CRUD operations on consultant profiles. Handles linking to User, managing achievements and experiences (via ProviderService), resume uploads (via FilesService). Performs access checks for updates/deletions. Provides methods for getCalendarEvents and a stubbed getOverview.
  • entities/consultant.entity.ts: Defines the Consultant schema with fields for about, description, expertise, languages, professional background, social links, and relations to User (OneToOne), Consultation (OneToMany), File (for resume), Experience, and Achievement.
  • entities/consultant-meta.entity.ts: (Purpose to be clarified if distinct from Consultant entity fields).
  • entities/timeslot.entity.ts: (If specific to consultant, or if it's the shared one for availability).
  • dto/: Contains DTOs like CreateConsultantDto, UpdateConsultantDto, ConsultantResponseDto. 4.7.3. API Endpoints (Key Examples from ConsultantController):
  • POST /consultant: Create a consultant profile for the authenticated user. Body: CreateConsultantDto. (Protected)
  • GET /consultant/:id? (or by email/slug): Get consultant profile. (Publicly viewable with view options)
  • PUT /consultant/:userId: Update consultant profile. Body: UpdateConsultantDto. (Protected, owner/admin)
  • DELETE /consultant/:userId: Delete consultant profile. (Protected, owner/admin - service enforces)
  • GET /consultant/overview: Get consultant overview. (Protected)
  • GET /consultant/availability, PUT /consultant/availability: Manage consultant availability (via ProviderService). (Protected)
  • GET /consultant/calendar: Get consultant's calendar events. (Protected)
  • GET /consultant/sessions/upcoming: Get consultant's upcoming sessions. (Protected) 4.7.4. Data Models:
  • Consultant entity (details key fields: link to User, professional background, expertise, resume, consultations offered). 4.7.5. Core Workflows & Business Logic:
  • Profile Creation: Link to existing User, add Consultant role to User, save professional details, handle resume. Emit CONSULTANT_CREATED event.
  • Profile Retrieval: Fetch consultant and associated user data, format resume URL, serialize based on view groups, fetch experiences/achievements via ProviderService.
  • Profile Update: Access control, update fields, handle resume/experience/achievement updates. Emit CONSULTANT_UPDATED event.
  • Profile Deletion: Access control, delete associated provider-specific data (achievements, experiences, availability), then delete consultant profile. Emit CONSULTANT_REMOVED event. 4.7.6. Events Emitted/Handled: AppEvents.CONSULTANT_CREATED, AppEvents.CONSULTANT_UPDATED, AppEvents.CONSULTANT_REMOVED.

4.8. Module: Cart (src/cart/) 4.8.1. Purpose and Responsibilities (High-Level): Manages user shopping carts, allowing items (courses, consultations) to be added, viewed, and removed before checkout. 4.8.2. Key Interactions: UsersModule (user association), CourseModule/ConsultationModule (product details), CouponModule (potential pre-order discount application), OrderModule (for converting cart to order). 4.8.3. Core Entities: Cart, CartItem.

4.9. Module: Order (src/order/) 4.9.1. Purpose and Responsibilities (High-Level): Handles the creation and management of orders from cart items or direct product selections. Calculates totals, applies coupons, and interfaces with PaymentModule to initiate payment and EnrollmentModule for fulfillment. 4.9.2. Key Interactions: CartModule (source of items), CouponModule (discounts), PaymentModule (payment processing), EnrollmentModule (fulfillment), UsersModule (user association), CourseModule/ConsultationModule (item details). 4.9.3. Core Entities: Order, OrderItem.

4.10. Module: Reviews (src/reviews/) 4.10.1. Purpose and Responsibilities (High-Level): Manages user-submitted reviews and ratings for products like courses and consultations. Handles review creation, retrieval, and aggregation of rating statistics. 4.10.2. Key Interactions: UsersModule (reviewer identity), CourseModule/ConsultationModule (reviewed entity context), EnrollmentModule (review eligibility). 4.10.3. Core Entities: Review.

4.11. Module: Marketplace (src/marketplace/) 4.11.1. Purpose and Responsibilities (High-Level): Provides public-facing API endpoints for searching, filtering, and discovering products (courses, consultations). Integrates recommendation logic. 4.11.2. Key Interactions: ElasticModule (primary data source for search), RecommendationModule, CourseModule/ConsultationModule (for product data structure). 4.11.3. Core Entities: (Primarily acts on data indexed in Elasticsearch, but references Course, Consultation entities).

4.12. Module: Students (src/students/) 4.12.1. Purpose and Responsibilities (High-Level): Manages student-specific profiles (linked to User accounts) and provides access to their enrollment data. 4.12.2. Key Interactions: UsersModule (base user data), EnrollmentModule (fetches student's enrollments). 4.12.3. Core Entities: Student.

4.13. Module: Impression (src/impression/) 4.13.1. Purpose and Responsibilities (High-Level): Tracks user impressions (views/interactions) for content like courses and consultations. Data is likely used for analytics. 4.13.2. Key Interactions: CourseModule/ConsultationModule (to identify entities being viewed). May log to an external system or update counters. 4.13.3. Core Entities: (May not have its own persistent entity in primary DB if data is offloaded).

4.14. Module: Enrollment (src/enrollment/) 4.14.1. Purpose and Responsibilities (High-Level): Manages user enrollments in products (courses, consultations), often triggered by successful payments. Tracks enrollment status and potentially granular progress (e.g., section completion). 4.14.2. Key Interactions: UsersModule/StudentsModule (enrolled user), CourseModule/ConsultationModule (enrolled product), PaymentModule (trigger for enrollment), OrderModule. Contains EnrollmentListener for event-driven actions. 4.14.3. Core Entities: Enrollment, SectionEnrollment.

4.15. Module: Comms (src/comms/) 4.15.1. Purpose and Responsibilities (High-Level): Integrates with third-party communication platforms (e.g., Stream, CometChat) for features like chat/calls. Manages user authentication tokens for these services and handles user provisioning on these platforms, often via event listeners (e.g., NewUserListener). 4.15.2. Key Interactions: UsersModule (user context), ConfigModule (API keys), HttpModule (external API calls), StreamModule. 4.15.3. Core Entities: UserAuthTokens.

4.16. Module: Category (src/category/) 4.16.1. Purpose and Responsibilities (High-Level): Manages a hierarchical system of categories and subcategories used to classify products like courses and consultations. Provides admin CRUD operations and public retrieval. 4.16.2. Key Interactions: CourseModule/ConsultationModule (products are assigned to categories), FilesModule (for category images). 4.16.3. Core Entities: Category.

5. API Reference

5.1. General Principles: RESTful, JSON-based. Standardized response format is implemented via ResponseInterceptor. 5.2. Authentication: Bearer Token (JWT) required for most endpoints. Sent in Authorization header. 5.3. Rate Limiting: Applied globally via ThrottlerModule and ThrottlerGuard, using Redis for storage. Limits configured via environment variables (THROTTLE_TTL, THROTTLE_LIMIT). 5.4. Common Status Codes and Error Formats: Standard HTTP status codes. Errors handled by AllExceptionsFilter, providing a consistent JSON error response structure. 5.5. API Documentation: Available at /docs (Swagger UI).

6. Database Schema & Migrations

6.1. Overview of Key Tables/Entities: users, logins, forgot_passwords, verify_emails, courses, course_sections, course_subsections, course_items, instructors, categories, files, etc. (Detailed in entity files). 6.2. Running Migrations: npm run migrations:run -- -d ./src/migrations-data-source.ts (or similar, path might vary slightly based on package.json). 6.3. Creating New Migrations: npm run migrations:generate -- -d ./src/migrations-data-source.ts ./src/migrations/$npm_config_name 6.4. Seeding Data: npm run seed:local (or other environment-specific seed scripts).

7. Development Practices

7.1. Coding Standards: Enforced by ESLint and Prettier (configs: .eslintrc.js, .prettierrc). 7.2. Testing Strategies: Jest framework. package.json includes scripts for unit tests (npm test), coverage (npm run test:cov), and E2E tests (npm run test:e2e). 7.3. Debugging Techniques: Use Node.js debugger, NestJS verbose logging (for local/dev), Sentry for error tracking in deployed environments. Source maps are generated.

8. Deployment

8.1. Build Process: npm run build (uses nest build which invokes TypeScript compiler). 8.2. Required Environment Variables: See src/config.ts validationSchema for a comprehensive list. Key categories include server ports, database credentials, JWT secrets, API keys for Paystack, Novu, S3, Google, ClickHouse, InstantDB, Shlink, Redis, SMTP. 8.3. Production Startup: npm run start:prod or npm run start:pm2:prod (uses PM2 for process management).

9. Troubleshooting Guide

9.1. Common Startup Issues:

  • Port conflicts (use kill-port as seen in main.ts, or check lsof -i :<port>).
  • Database connection errors (check .env credentials, DB server status, network).
  • Missing environment variables (application will likely fail validation at startup).
  • Redis connection errors. 9.2. Interpreting Logs: Check console output for NestJS logs, Winston/Pino logs (for staging/prod), and Sentry for detailed error reports with stack traces. 9.3. API Error Debugging: Use Swagger UI (/docs) or tools like Postman/Insomnia to test endpoints. Check API response structure and error messages.

10. Chat Flow Architecture

This section provides a comprehensive overview of the chat flow architecture, which is built around InstantDB and a robust event-driven system. This design ensures that chat rooms for categories, courses, and consultations are created, updated, and synchronized in a scalable and decoupled manner.

10.1. High-Level Overview

The architecture leverages an event-driven approach to manage the lifecycle of chat rooms. When a significant action occurs in the system—such as creating a course, updating a category, or enrolling in a consultation—an event is emitted. A dedicated listener, the InstantListener, subscribes to these events and executes the corresponding logic to create or update rooms and participants in InstantDB.

This approach decouples the core business logic of each module (e.g., CourseService, CategoryService) from the chat functionality, leading to a more maintainable and scalable system.

10.2. InstantDB Schema (server/src/instantdb/schema/instant.schema.ts)

The InstantDB schema is central to the chat functionality. It defines the entities and their relationships, enabling real-time communication and data synchronization.

10.2.1. Key Entities

  • users: Stores user profile information, such as name, email, and photo URL.
  • rooms: Represents a chat room. It includes properties like name, type (e.g., GROUP, PRIVATE), entityType (e.g., COURSE, CONSULTATION), and imageUrl.
  • participants: Links a user to a room, defining their role (e.g., INSTRUCTOR, STUDENT).
  • messages: Represents a single message within a room.

10.2.2. participantUser Relationship

A key enhancement to the schema is the participantUser link. This creates a direct relationship between a participant and a user, allowing the frontend to efficiently retrieve detailed user information for each participant in a room without additional queries.

// server/src/instantdb/schema/instant.schema.ts
links: {
// ...
participantUser: {
forward: { on: "participants", has: "one", label: "user" },
reverse: { on: "users", has: "many", label: "participations" },
},
// ...
}

10.3. Event-Driven Synchronization (server/src/instantdb/listeners/instant.listener.ts)

The InstantListener is the core of the synchronization process. It subscribes to application-wide events and triggers the appropriate actions in the InstantdbService.

10.3.1. Room Creation and Updates

  • Categories:
    • onCategoryCreated: When a parent category is created, a COMMUNITY room is created in InstantDB with the category's name and thumbnail imageUrl.
    • onCategoryUpdated: When a category is updated, the corresponding room's name, status, and imageUrl are updated.
  • Courses:
    • onCourseCreated: When a course is created, a GROUP room is created with the course's title and thumbnail imageUrl. The instructor is automatically added as a participant.
    • onCourseUpdated: When a course is updated, the corresponding room's name and imageUrl are updated.
  • Consultations:
    • onEnrollmentCreated: When a student enrolls in a consultation, a PRIVATE room is created. The room name is dynamically generated from the consultant's and student's first names, and the consultation's thumbnail is used as the imageUrl. Both the consultant and the student are added as participants.

10.4. Sequence Diagrams

10.4.1. Consultation Enrollment and Room Creation

This diagram illustrates the flow when a user enrolls in a consultation, resulting in the creation of a private chat room.

sequenceDiagram
participant User
participant EnrollmentService
participant EventEmitter
participant InstantListener
participant InstantdbService

User->>EnrollmentService: enrollInConsultation(data)
EnrollmentService->>EnrollmentService: save(enrollment)
EnrollmentService->>EventEmitter: emit('enrollment.consultation.successful', enrollment)

EventEmitter->>InstantListener: handleConsultationEnrollment(enrollment)
InstantListener->>InstantdbService: createRoom(roomData)
InstantdbService-->>InstantListener: room
InstantListener->>InstantdbService: createRoomParticipant(consultant)
InstantListener->>InstantdbService: createRoomParticipant(student)

Appendix

  • List of Key Environment Variables and their purpose (can be derived from src/config.ts).
  • Glossary