Technical Documentation: Learnille Server
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 likename,type(e.g.,GROUP,PRIVATE),entityType(e.g.,COURSE,CONSULTATION), andimageUrl.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.
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, aCOMMUNITYroom is created in InstantDB with the category’s name and thumbnailimageUrl.onCategoryUpdated: When a category is updated, the corresponding room’sname,status, andimageUrlare updated.
- Courses:
onCourseCreated: When a course is created, aGROUProom is created with the course’s title and thumbnailimageUrl. The instructor is automatically added as a participant.onCourseUpdated: When a course is updated, the corresponding room’snameandimageUrlare updated.
- Consultations:
onEnrollmentCreated: When a student enrolls in a consultation, aPRIVATEroom 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 theimageUrl. 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