Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

24 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐ŸŽ“ DIEGO LMS โ€” Backend API

Multi-tenant Learning Management System backend built with Express.js 5, Prisma (PostgreSQL), Redis, Stripe, and JWT auth. Supports SCORM/AICC/xAPI courses, licensing, company (B2B) purchases, certificates, quizzes, and more.

Node Express Prisma License


๐Ÿ“š Table of Contents

  1. Overview
  2. Tech Stack
  3. Architecture Concepts
  4. Project Structure
  5. Quick Start
  6. Environment Variables
  7. Available Scripts
  8. API Conventions
  9. Modules / Feature Map
  10. Authentication & Authorization
  11. Postman Collection
  12. Further Documentation

๐Ÿงญ Overview

DIEGO is a multi-tenant LMS platform. A single backend instance serves multiple Tenants (white-labeled platforms), each of which can have their own courses, licensees, employees, and branding (subdomain / custom domain / logo / primary color).

Core domains modeled in the system:

  • Users & Auth โ€” multi-level RBAC (PRIVATE_USER, COMPANY_ADMIN, COMPANY_EMPLOYEE, LICENSEE, PLATFORM_ADMIN, TUTOR, TEACHER)
  • Courses & Lessons โ€” SCORM, AICC, xAPI, PDF, video, quizzes, checklists, LTI, slide decks
  • Enrollments & Progress โ€” lesson progress, SCORM session tracking, anti-cheat logging, auto-completion โ†’ certificate generation
  • Commerce โ€” single course purchase, packages, licenses, company bulk purchases, coupons, Stripe payments, invoices
  • Licensing โ€” licensees run their own branded course catalog under a tenant, earn a revenue share (LicenseeIncome)
  • Certificates โ€” auto-issued PDF certificates with QR code + timestamp proof
  • Support & Notifications โ€” support tickets, in-app notifications, severity alerts
  • i18n โ€” most user-facing content (titles, descriptions, messages) stored as Json to support it, en, fr, zh

๐Ÿ›  Tech Stack

Layer Technology
Runtime Node.js 18+
Framework Express 5
ORM Prisma 5 (@prisma/client, @prisma/adapter-pg)
Database PostgreSQL
Cache / Sessions Redis
Auth JWT (jsonwebtoken), bcrypt/bcryptjs
Validation Zod 4
Payments Stripe
File storage Cloudinary, Multer
PDF generation html-pdf-node (certificates)
Email Nodemailer
Scheduling node-cron
Logging Winston, Morgan
Monitoring swagger-stats
Testing Vitest, Supertest
Package manager pnpm 10

๐Ÿ— Architecture Concepts

Multi-tenancy

Almost every top-level entity (Course, License, Payment, Package, Quiz, Coupon, Notification, Alert, SupportTicket, ArchiveSubscription, Certificate, Review) carries an optional tenantId. Requests from LICENSEE and tenant-scoped users are automatically filtered by tenant via a tenantGuard middleware.

Role-based access (UserLevel)

Level Description
PRIVATE_USER Individual learner
COMPANY_ADMIN / COMPANY_EMPLOYEE B2B company accounts
LICENSEE Runs a branded catalog under a tenant, earns revenue share
PLATFORM_ADMIN Full cross-tenant access
TUTOR / TEACHER Assigned to specific courses

Enrollment lifecycle

NOT_STARTED โ†’ IN_PROGRESS โ†’ COMPLETED (or EXPIRED / SUSPENDED), driven by LessonProgress / ScormSession records. When all required lessons are completed, enrollmentService.checkAndUpdateEnrollmentStatus() auto-marks the enrollment COMPLETED and triggers async certificate generation.

Commerce model

A Payment is the central commerce record โ€” it can back a single-course Enrollment, a License, a PackagePurchase, a CompanyCoursePurchase, or an ArchiveSubscription, and produces an Invoice. Renewals are tracked separately (CourseRenewal, LicenseRenewal, CompanyCoursePurchaseRenewal) so pricing history isn't lost.

i18n content

Fields like courseTitle, description, name, message are stored as Prisma Json โ€” typically { "it": "...", "en": "...", "fr": "...", "zh": "..." }. Frontend clients should resolve these using the current SupportedLocale and the i18nMiddleware.


๐Ÿ“ Project Structure

diego-backend/
โ”œโ”€โ”€ prisma/
โ”‚   โ”œโ”€โ”€ migrations/
โ”‚   โ””โ”€โ”€ schema.prisma
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ config/                # db, logger, env config
โ”‚   โ”œโ”€โ”€ features/
โ”‚   โ”‚   โ”œโ”€โ”€ assignCourse/
โ”‚   โ”‚   โ”œโ”€โ”€ auth/
โ”‚   โ”‚   โ”œโ”€โ”€ certificate/
โ”‚   โ”‚   โ”œโ”€โ”€ course/
โ”‚   โ”‚   โ”œโ”€โ”€ coursePurchase/
โ”‚   โ”‚   โ”œโ”€โ”€ employee/
โ”‚   โ”‚   โ”œโ”€โ”€ enrollment/        # โœ… fully documented โ€” see API docs
โ”‚   โ”‚   โ”œโ”€โ”€ lesson/
โ”‚   โ”‚   โ”œโ”€โ”€ license/
โ”‚   โ”‚   โ”œโ”€โ”€ licenseIncome/
โ”‚   โ”‚   โ”œโ”€โ”€ licensePlan/
โ”‚   โ”‚   โ”œโ”€โ”€ notification/
โ”‚   โ”‚   โ”œโ”€โ”€ package/
โ”‚   โ”‚   โ”œโ”€โ”€ payment/
โ”‚   โ”‚   โ”œโ”€โ”€ quiz/
โ”‚   โ”‚   โ”œโ”€โ”€ reviews/
โ”‚   โ”‚   โ”œโ”€โ”€ supportTicket/
โ”‚   โ”‚   โ””โ”€โ”€ user/
โ”‚   โ”‚       โ””โ”€โ”€ each feature/  # {feature}.controller.js, {feature}.service.js,
โ”‚   โ”‚                          # {feature}.routes.js, {feature}.validation.js
โ”‚   โ”œโ”€โ”€ generated/prisma/      # Prisma client output
โ”‚   โ”œโ”€โ”€ routes/                # route aggregator
โ”‚   โ”œโ”€โ”€ seeds/                 # admin.seeder.js, package.seeder.js
โ”‚   โ”œโ”€โ”€ shared/
โ”‚   โ”‚   โ””โ”€โ”€ globals/
โ”‚   โ”‚       โ”œโ”€โ”€ decorators/    # catchAsync
โ”‚   โ”‚       โ””โ”€โ”€ helpers/       # auth-middleware, tenant.middleware, i18n.middleware, response.handler
โ”‚   โ”œโ”€โ”€ app.js
โ”‚   โ”œโ”€โ”€ app.test.js
โ”‚   โ”œโ”€โ”€ bootstrap.js
โ”‚   โ”œโ”€โ”€ routes.js
โ”‚   โ””โ”€โ”€ server.js
โ”œโ”€โ”€ uploads/
โ”œโ”€โ”€ .env.dev
โ””โ”€โ”€ package.json

Every feature module follows the same 4-file pattern: *.routes.js โ†’ *.controller.js โ†’ *.service.js, validated by *.validation.js (Zod). This means once a frontend dev understands the Enrollment module (fully documented below), every other module behaves the same way structurally.


๐Ÿš€ Quick Start

Prerequisites

  • Node.js 18+
  • PostgreSQL database
  • Redis
  • pnpm (npm install -g pnpm)

Installation

# 1. Clone the repository
git clone <repo-url>
cd diego-backend

# 2. Install dependencies
pnpm install

# 3. Set up environment variables
cp .env.dev .env
# Edit .env with your credentials

# 4. Generate Prisma Client
pnpm run prisma:generate

# 5. Run database migrations
pnpm run prisma:migrate

# 6. Seed the database
pnpm run seeds:admin      # Create admin account
pnpm run seeds:package    # Create subscription packages

# 7. Start development server
pnpm run dev

Server runs at http://localhost:5000/api/v1


๐Ÿ” Environment Variables

Create a .env file (copy from .env.dev) with at least:

# Server
NODE_ENV=development
PORT=5000
API_PREFIX=/api/v1

# Database
DATABASE_URL=postgresql://user:password@localhost:5432/diego_lms

# Redis
REDIS_URL=redis://localhost:6379

# Auth
JWT_SECRET=your_jwt_secret
JWT_EXPIRES_IN=7d
JWT_REFRESH_SECRET=your_refresh_secret

# Stripe
STRIPE_SECRET_KEY=sk_test_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx

# Cloudinary
CLOUDINARY_CLOUD_NAME=xxx
CLOUDINARY_API_KEY=xxx
CLOUDINARY_API_SECRET=xxx

# Email (Nodemailer)
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=xxx
SMTP_PASS=xxx

# Frontend URL (used in emails / access links)
FRONTEND_URL=http://localhost:3000

โš ๏ธ Ask your backend lead to confirm the exact variable names against .env.dev โ€” this list is inferred from the dependency list (Stripe, Cloudinary, Redis, Nodemailer, JWT) and should be verified.


๐Ÿ“œ Available Scripts

Script Description
pnpm run dev Start development server with nodemon auto-reload
pnpm start Start production server (node src/bootstrap.js)
pnpm run build Generate Prisma Client
pnpm run postinstall Auto-runs prisma generate after install
pnpm run prisma:generate Generate Prisma Client
pnpm run prisma:migrate Run database migrations (dev)
pnpm run prisma:deploy Deploy migrations (production)
pnpm run prisma:studio Open Prisma Studio GUI
pnpm run seeds:admin Seed admin user
pnpm run seeds:package Seed subscription packages
pnpm run lint Run ESLint
pnpm run lint:fix Auto-fix ESLint issues
pnpm run format Format code with Prettier
pnpm run test Run tests with Vitest
pnpm run test:watch Run tests in watch mode
pnpm run test:coverage Run tests with coverage report

๐Ÿ”Œ API Conventions

  • Base URL: http://localhost:5000/api/v1 (dev)
  • Auth: Authorization: Bearer <accessToken> header on all protected routes
  • Content-Type: application/json
  • Response envelope (via ResponseHandler):
{
  "success": true,
  "message": "Human readable message",
  "data": { }
}

Error responses follow the same envelope with "success": false and an "error" or "message" field describing what went wrong (validation errors surface Zod's issue array).

  • Pagination (list endpoints): query params page (default 1), limit (default 20, max 100), returns:
{
  "meta": { "page": 1, "limit": 20, "total": 42, "totalPages": 3 },
  "items": [ ]
}
  • Multi-tenant scoping: PLATFORM_ADMIN sees everything (optionally filter with ?tenantId=); LICENSEE and tenant-bound users are auto-scoped to their own tenantId โ€” no need to pass it manually.
  • i18n fields: any field typed Json in the schema (titles, descriptions, messages) may come back as an object keyed by locale ({ "en": "...", "it": "..." }) rather than a plain string.

๐Ÿ—บ Modules / Feature Map

Module Status Notes
enrollment โœ… Fully documented See API_DOCUMENTATION.md + Postman
course ๐ŸŸก Partial (sample response only) List endpoint shape known from sample; CRUD endpoints to confirm
auth โฌœ Pending source Login/register/refresh/OTP endpoints โ€” send auth.routes.js
certificate โฌœ Pending source certificateService.autoGenerateOnCompletion confirmed to exist
coursePurchase โฌœ Pending source
employee โฌœ Pending source
lesson โฌœ Pending source
license โฌœ Pending source
licenseIncome โฌœ Pending source
licensePlan โฌœ Pending source
notification โฌœ Pending source
package โฌœ Pending source
payment โฌœ Pending source Stripe-backed
quiz โฌœ Pending source
reviews โฌœ Pending source
supportTicket โฌœ Pending source
user โฌœ Pending source
assignCourse โฌœ Pending source

Send the .controller.js / .routes.js / .validation.js for any โฌœ module and it'll be added to API_DOCUMENTATION.md and the Postman collection in the exact same format as Enrollment.


๐Ÿ”‘ Authentication & Authorization

All routes in enrollment.routes.js (and, by convention, every other feature) run through two global middlewares:

router.use(authMiddleware.protect);   // validates JWT, attaches req.user
router.use(i18nMiddleware);           // resolves locale for Json fields

Elevated routes add:

const adminGuard = authMiddleware.authorize('PLATFORM_ADMIN', 'LICENSEE');
router.use(adminGuard, tenantGuard);

For the frontend:

  1. Obtain accessToken from the (pending) auth module's login endpoint.
  2. Send it as Authorization: Bearer <accessToken> on every request.
  3. A 403/401 on a licensee/* or admin route usually means the logged-in user's level isn't PLATFORM_ADMIN or LICENSEE, or their tenantId doesn't resolve.

๐Ÿ“ฎ Postman Collection

Import DIEGO_LMS.postman_collection.json into Postman. It includes:

  • Collection-level {{baseUrl}} and {{accessToken}} variables
  • A Enrollment folder with all 14 endpoints, pre-filled example bodies matching the Zod schemas, and inline descriptions
  • A Courses folder with the confirmed GET /courses list endpoint (from the sample response you shared)
  • Placeholder folders for every other module, ready to fill in once source files are shared

Set {{baseUrl}} to http://localhost:5000/api/v1 and {{accessToken}} after logging in.


๐Ÿ“– Further Documentation

  • API_DOCUMENTATION.md โ€” full endpoint-by-endpoint reference (request/response/auth/errors)
  • prisma/schema.prisma โ€” source of truth for all data shapes
  • Prisma Studio (pnpm run prisma:studio) โ€” browse live data during integration testing

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages