Software Architecture Document: Learnille Server
1. Introduction
1.1. Purpose 1.2. Scope 1.3. Definitions, Acronyms, and Abbreviations 1.4. References 1.5. Overview of the Remainder of the Document
2. Architectural Representation
2.1. Architectural Goals
- Modularity: Achieved through NestJS modules for distinct features.
- Scalability: Leveraging technologies like Node.js, PostgreSQL, Redis, and BullMQ.
- Maintainability: TypeScript for type safety, consistent structure via NestJS.
- Security: JWT-based authentication, role-based access control (CASL observed), Helmet for security headers.
- Testability: Structure supports unit, integration, and e2e testing (Jest setup observed). 2.2. Constraints
- Technology Stack: Primarily NestJS (Node.js/TypeScript), PostgreSQL, Redis.
- Reliance on specific third-party services (e.g., Paystack, Novu, Sentry, New Relic, Cloudflare R2 / S3, InstantDB/Triplit, ClickHouse, Shlink). 2.3. Key Architectural Decisions & Rationale
- Choice of NestJS: Provides a robust, modular framework for building scalable server-side applications with TypeScript.
- Modular Design: Enhances separation of concerns, maintainability, and team collaboration.
- Use of TypeORM: Offers a powerful ORM for database interaction with PostgreSQL.
- JWT for Authentication: Standard and stateless approach for API security.
- Asynchronous Processing with BullMQ: For handling background tasks and improving responsiveness.
- Centralized Configuration: Using
@nestjs/configwith environment-specific files and Joi validation. - Event-Driven Elements: Use of
@nestjs/event-emitterfor decoupling components.
3. System Overview and Context
3.1. System Context Diagram (Conceptual - to be described textually for now) The Learnille Server acts as the central backend API for various clients (web application, mobile applications). It interacts with:
- Databases: Self-Hosted PostgreSQL (primary), Redis (caching/session/rate-limiting), OpenSearch (search), InstantDB/Triplit.
- Payment Gateways: Paystack, Flutterwave.
- Notification Service: Novu.
- Error Tracking & Monitoring: Sentry, New Relic.
- File Storage: Cloudflare R2 (S3 API compatible) / MinIO.
- Authentication: Google & Apple (for social login).
- URL Shortening: Shlink. 3.2. Major Components
- API Layer: Exposes RESTful endpoints (NestJS Controllers).
- Application Core: Business logic encapsulated in NestJS Services and Modules.
- Data Access Layer: TypeORM repositories interacting with databases.
- Infrastructure Services: Wrappers or integrations for Redis, BullMQ, OpenSearch, Novu, New Relic, Sentry, etc.
- External Service Integrations: Clients/SDKs for Paystack, Flutterwave, Google, Cloudflare R2, etc.
4. Architectural Views
4.1. Logical View / Module View
4.1.1. Overview
The application is structured as a set of NestJS modules. A root AppModule imports core infrastructure modules and feature-specific modules.
graph LR
subgraph User Interaction
UI(Frontend)
end
subgraph Backend API (NestJS)
subgraph Core Modules
AppMod(AppModule) --> Cfg(ConfigModule)
AppMod --> DB(DatabaseModule)
AppMod --> Auth(AuthModule)
AppMod --> Redis(RedisModule)
AppMod --> Bull(BullMQModule)
AppMod --> Elastic(ElasticModule)
AppMod --> Notify(NotificationModule)
AppMod --> Common(Common Utils)
end
subgraph Feature Modules
Market(MarketplaceModule) -- uses --> Elastic
Consult(ConsultationModule) -- uses --> User(UsersModule)
Consult -- uses --> Timeslot(TimeslotService)
Consult -- triggers --> Pay(PaymentModule)
Cart(CartModule) -- holds --> ConsultEntity(Consultation Entity)
Cart -- holds --> CourseEntity(Course Entity)
Pay -- uses --> User
Pay -- uses --> PayGW(PaystackModule)
Pay -- updates --> Wallet(WalletService)
Pay -- triggers --> Enroll(EnrollmentModule)
Pay -- triggers --> Notify
end
end
UI --> Market
UI --> Consult
UI --> Cart
Market --> Consult
Consult --> Pay
Cart --> Pay # Assumed Checkout Flow
4.1.2. Core Infrastructure Modules
ConfigModule: Manages environment variables and application configuration with Joi validation.DatabaseModule(custom, likely wrapsTypeOrmModule): Manages PostgreSQL database connections and entity registration.AuthModule: Handles authentication (JWT, local, Google), authorization strategies, and user session management.CryptoModule: Provides cryptographic functions (password hashing, JWT signing/verification).RedisModule: Manages Redis connections for caching and potentially other uses (e.g., Throttler storage).BullmqCustomModule: Manages BullMQ for background job processing.ElasticModule: Integrates with Elasticsearch for search capabilities.NotificationModule&NovuModule: Manages notifications via Novu (workflows, subscribers).SentryModule: Integrates Sentry for error tracking and performance monitoring.MailerModule: Handles email sending via SMTP with Handlebars templating.ClickHouseModule: Integrates ClickHouse for analytics.StorageModule(withSimpleStorageService): Manages file storage (e.g., S3).LoggerModule(nestjs-pino) / Winston: Provides structured logging capabilities.TerminusModule: For health checks.ThrottlerModule: For API rate limiting.EventEmitterModule: For in-application event handling. 4.1.3. Key Feature Modules (Initial list based on analysis)UsersModule: Manages user profiles, roles, and basic user data.CourseModule: Manages course creation, content (sections, subsections, items), instructors, categories, levels, pricing, and related metadata.ConsultationModule: Manages consultation offerings, consultant availability (timeslots), user bookings, and individual consultation sessions. It supports different consultation types (e.g., one-off, recurring) and integrates withElasticModulefor search,PaymentModulefor billing,NotificationModulefor reminders, andReviewsModulefor feedback. It has its own set of entities for consultations, bookings, timeslots, and type-specific metadata.PaymentModule: Orchestrates financial transactions. It integrates with payment gateways (e.g.,PaystackModule) to process incoming payments for orders. It managesPaymententities and includes aWalletServiceandWalletControllerfor user fund management and withdrawals. It interacts closely withOrderModule,UsersModule,CourseModule,ConsultationModule, andEnrollmentModule.PaystackModule: (If not already listed separately) Provides a dedicated interface for interacting with the Paystack payment gateway API, including payment initiation and webhook handling.InstructorsModule: Manages instructor-specific profiles, linking them to baseUseraccounts. It handles details like professional experience, achievements, expertise, and resume. It's tightly coupled withUsersModuleandCourseModule(as instructors create courses) and interacts withFilesModulefor resume/profile picture storage and potentiallyEnrollmentModulefor viewing course enrollments. It may use a sharedProviderServicefor managing common profile sections like experiences and achievements.ConsultantModule: Manages consultant-specific profiles, linking them to baseUseraccounts. It handles details like professional experience, achievements, expertise, resume, and availability. It's tightly coupled withUsersModuleandConsultationModule(as consultants offer consultations) and interacts withFilesModulefor resume/profile picture storage,ReviewsModulefor feedback, and uses a sharedProviderServicefor managing common profile sections and availability.CartModule: Provides shopping cart functionality, allowing users to add and manage items (courses, consultations) before purchase. It interacts with product modules for item details andOrderModulefor checkout.OrderModule: Manages the order creation process. It takes items (often from a cart), applies coupons, calculates totals, and createsOrderrecords. It's a crucial intermediary toPaymentModulefor initiating transactions andEnrollmentModulefor post-payment fulfillment.ReviewsModule: Handles user-submitted reviews and ratings for products (courses, consultations). Interacts with product modules to update aggregate ratings andEnrollmentModulefor review eligibility. May integrate withElasticModule.MarketplaceModule: Powers the public-facing discovery of products. Relies heavily onElasticModulefor search/filtering and integratesRecommendationModule.StudentsModule: Manages student-specific profiles (linked toUser) and their interactions, particularly closely tied toEnrollmentModule.ImpressionModule: Tracks user views/interactions with content like courses and consultations, likely feeding data to analytics or recommendation systems.EnrollmentModule: Manages user enrollment in products, often triggered by successful payments. Includes anEnrollmentListenerfor event-driven enrollment creation and tracks granular progress.CommsModule: Integrates with third-party communication platforms (e.g., Stream, CometChat) for features like chat/calls, managing user tokens for these services.CategoryModule: Manages the hierarchical categorization of content (courses, consultations).- (Others to be detailed as analysis progresses: Product, etc.)
4.2. Development View
4.2.1. Source Code Organization: Primarily within
src/, with modules in dedicated subdirectories (e.g.,src/users,src/course). Common utilities might reside insrc/commonorsrc/shared. Configuration insrc/config.tsandenv/directory. 4.2.2. Key Frameworks and Libraries: NestJS, TypeORM, Express.js (underlying NestJS), Passport.js, Joi, BullMQ, Elasticsearch client, Novu SDK, Sentry SDK, Paystack SDK. 4.2.3. Build Process:npm run build(usesnest build). 4.3. Deployment View 4.3.1. Target Environment(s): Local, Development, Staging, Production (as indicated by.envfile structure andNODE_ENVusage). 4.3.2. Physical Infrastructure (Conceptual): - Application Server(s) running Node.js (v22 specified).
- PostgreSQL Database Server.
- Redis Server.
- Elasticsearch Cluster.
- ClickHouse Server.
- InstantDB/Triplit Server (can be run via
docker-compose.ymllocally). - Dependencies on external services (Paystack, Novu, Sentry, Google, S3, Shlink).
4.3.3. Containerization Strategy:
docker-compose.ymlprovided is fortriplit-server. The main application's containerization strategy for deployment is not yet fully detailed from current files but likely involves Docker. 4.3.4. Technology Stack Summary: Node.js (v22), TypeScript, NestJS, PostgreSQL, Redis, Elasticsearch, BullMQ, Novu, Sentry, Paystack, S3, ClickHouse, InstantDB.
5. Data Architecture
5.1. Data Persistence Strategy
- Primary Relational Database: PostgreSQL (managed via TypeORM).
- Caching/Session/Rate-Limiting: Redis.
- Search Indexing: Elasticsearch.
- Analytics: ClickHouse.
- Real-time/Collaborative Data: InstantDB/Triplit. 5.2. High-Level Data Model (Key entities identified so far)
User: Core user information, roles, credentials.Login: Tracks login sessions/attempts.ForgotPassword,VerifyEmail: Tokens for account recovery/verification.Course: Main course details, pricing, instructor, category, level.CourseSection,CourseSubSection,CourseItem: Hierarchical course content.Instructor: Profile specific to instructors, linked to aUser, contains professional details, resume, and courses they manage.Consultant: Profile specific to consultants, linked to aUser, contains professional details, resume, availability, and consultations they offer.Student: Role-specific profiles linked to Users.Consultation: Main consultation offering details, type, consultant, pricing.Booking: User bookings for consultations.ConsultationTimeSlot: Consultant availability.ConsultationSession: Individual consultation sessions.OneOffConsultationMeta,RecurringConsultation: Metadata for specific consultation types.Payment: Records of financial transactions, linked to orders, users, and gateways.Withdrawal: Records of user withdrawal requests from their wallets.Order: Represents a user's intention to purchase items (courses, consultations).OrderItem: Represents individual items within an order.Cart: Represents a user's shopping cart.CartItem: Represents individual items within a cart.Coupon,CouponUsage: For managing discount codes.Category: For course categorization.Student: Profile for student users.Enrollment,SectionEnrollment: Tracks user enrollment and progress in products.Review: Stores user reviews and ratings.UserAuthTokens(Comms): Stores tokens for external communication services.File: For storing references to uploaded files (profile photos, course materials).- (Others to be added: PaymentTransaction, EnrollmentRecord, Product, etc.) 5.3. Data Flow for Key Use Cases
- User Registration: Client -> API (
/auth/register) ->AuthService->UsersService(creates User) -> Role-specific service (creates Instructor/Student/Consultant profile) -> DB. Event emitted, Novu notification triggered. - Course Creation: Client -> API (
/course) ->CourseController->CourseService-> DB (creates Course, links to Instructor, Category, Files, etc.). Event emitted. - Consultation Booking: User (Client) browses consultations (via API, potentially using Elasticsearch) -> Selects a consultation and an available timeslot -> Submits booking request (API:
POST /consultation/booking) ->ConsultationController->ConsultationService(validates timeslot, createsBookingentity, potentially links toConsultationSession) -> Triggers payment flow (viaPaymentModule) -> On success, confirms booking, sends notifications (viaNovuModule). - Checkout Flow: User adds items to Cart (via
CartModule) -> User proceeds to checkout ->OrderServicecreates anOrderfrom Cart items, applies coupons, calculates total, sets status to PENDING -> (Rest of payment flow as previously described, starting withPaymentsService._initiatePaymentForOrder). - Product Discovery: User searches/filters on Marketplace UI -> API (
/marketplace/*) ->MarketplaceController->MarketplaceService->ElasticModule(queries Elasticsearch) -> Returns product list. - Leaving a Review: User (Student) submits review for a Course -> API (
/review) ->ReviewsController->ReviewsService(validates eligibility, e.g., viaEnrollmentService) -> SavesReviewentity -> Updates aggregate rating onCourseentity.
6. Cross-Cutting Concerns
6.1. Security Architecture
- Authentication: JWT-based.
LocalStrategyfor email/password,GoogleStrategyfor Google OAuth. Managed byAuthModuleand Passport.js. - Authorization: Role-based access control (RBAC) implied by
UserRoleand potentially fine-grained withCaslGuard(seen inCourseController). - Input Validation:
class-validatorDTOs withValidationPipe. - HTTP Security Headers:
helmetmiddleware. - CORS: Enabled via
app.enableCors(). - Secret Management: Primarily through environment variables (
.envfiles,ConfigModule).KEYS_DIRin config suggests potential for local key storage. 6.2. Error Handling and Fault Tolerance - Global Exception Filter:
AllExceptionsFilterinmain.tsfor standardized error responses. - Custom exceptions defined per module (e.g.,
PhotoNotFoundExceptioninUsersModule). - Sentry: Integrated for error tracking and reporting (
SentryModule, process-level handlers inmain.ts). 6.3. Logging and Monitoring - Structured Logging:
nestjs-pinoor Winston (conditional inmain.ts).AppRequestLoggerMiddlewarefor HTTP request logging. - Performance Monitoring: Sentry APM (implied by
instrument.tsand Sentry setup). - Health Checks:
TerminusModuleimported, likely for/healthendpoints. 6.4. Configuration Management @nestjs/configloading environment-specific.envfiles fromenv/.- Joi schema validation (
src/config.ts) for environment variables. - Type-safe access via
ConfigServiceandConfiginterface. 6.5. API Design - RESTful principles generally followed.
- Standardized response format via
ResponseInterceptor(seen inmain.ts). - API documentation via Swagger (setup in
main.ts, available at/docs). 6.6. Asynchronous Processing BullmqCustomModulefor background jobs (e.g., email sending, long computations).
7. Design Rationale
7.1. Why NestJS?
- Opinionated framework providing structure for large applications.
- Excellent TypeScript support.
- Modular architecture promotes separation of concerns.
- Built-in support for microservices, testing, and common patterns. 7.2. Why a Modular Architecture?
- Improved maintainability and testability.
- Allows for parallel development by teams.
- Clear boundaries between different functional areas of the application. 7.3. Rationale for Database Choices
- PostgreSQL: Robust, feature-rich relational database suitable for complex data models.
- Redis: High-performance key-value store ideal for caching, session management, and rate limiting.
- Elasticsearch: Powerful search engine for providing fast and relevant search results (e.g., for courses).
- ClickHouse: Columnar database optimized for OLAP queries and analytics.
- InstantDB/Triplit: Real-time database capabilities.
Appendix
- (Diagrams can be added here later if text-based representations are feasible)