Skip to content

team-tango790/talentflow-backend

Repository files navigation

TalentFlow LMS — Backend

REST API backend for the TalentFlow Learning Management System. Built for Trueminds Innovations' internship programme to manage intern learning, progress tracking, assignments, certificates, and cohort collaboration.

Live URL: https://talentflow-backend-7pp4.onrender.com


Tech Stack

Layer Technology
Runtime Node.js
Framework Express 5
Language TypeScript 5
ORM Prisma 6
Database PostgreSQL (Neon)
Authentication JWT (HS256, 7-day expiry)
Password hashing bcrypt
File uploads Cloudinary + multer
Email Nodemailer
Validation express-validator + Zod
Rate limiting express-rate-limit

Getting Started

Prerequisites

  • Node.js 18+
  • A PostgreSQL database (Neon recommended)
  • A .env file — see Environment Variables below

Install & Run

# Install dependencies
npm install

# Generate Prisma client
npx prisma generate

# Run database migrations
npx prisma migrate deploy

# Development (hot reload)
npm run dev

# Production build
npm run build
npm start

The server runs on port 5000 by default (http://localhost:5000).

Note: If connecting to a Neon database, disconnect from any VPN before running prisma migrate or prisma db push.


Environment Variables

Create a .env file in the project root:

DATABASE_URL=postgresql://user:password@host/talentflow
JWT_SECRET=your_strong_secret_here
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
EMAIL_USER=your_smtp_email
EMAIL_PASS=your_smtp_password
GOOGLE_CLIENT_ID=your_google_oauth_client_id
PORT=5000

Project Structure

src/
├── app.ts                  Express app setup — middleware, routes, CORS
├── server.ts               Server entry point — listens on PORT
├── config/
│   ├── db.ts               Prisma client instance
│   └── cloudinary.ts       Cloudinary configuration
├── controllers/            Request handlers — one file per domain
├── services/               Business logic — one file per domain
├── routes/                 Express routers — one file per domain
├── middleware/
│   ├── authMiddleware.ts   JWT verification + req.user injection
│   ├── errorMiddleware.ts  Global error handler
│   ├── rateLimitMiddleware.ts  Rate limiters for auth routes
│   ├── uploadMiddleware.ts Multer + Cloudinary upload
│   └── validateRequest.ts  express-validator error collector
├── validators/             Input validation rules per domain
├── utils/
│   ├── AppError.ts         Custom error class with status code
│   ├── asyncHandler.ts     Wraps async controllers — no try/catch needed
│   ├── generateToken.ts    JWT signing
│   └── sendEmail.ts        Nodemailer helper
└── types/
    └── express.d.ts        Extends Express Request with req.user

Architecture

Each domain follows the same 3-layer pattern:

Route → Controller → Service → Prisma → Database
  • Routes — define HTTP method and path, apply auth/validation middleware
  • Controllers — extract request data, call the service, send the response
  • Services — all business logic and Prisma queries live here

Errors are thrown as AppError instances from the service layer and caught by the global error middleware.


API Reference

All protected endpoints require Authorization: Bearer <token> in the request headers.

Authentication

Method Route Auth Description
POST /api/auth/register None Register new user — returns { data: { ...user, token } }
POST /api/auth/login None Login — returns { data: { ...user, token } }
POST /api/auth/google-auth None Google OAuth — verifies Google ID token
POST /api/auth/forgot-password None Sends 6-digit OTP to email
POST /api/auth/verify-otp None Validates OTP
POST /api/auth/reset-password/:token None Sets new password

Token shape: { id, role, iat, exp } — the token is nested inside data in the login/register response, not at the root.

Users

Method Route Auth Description
GET /api/users/me Any Get current user's full profile
PUT /api/users/me Any Update name, bio, track — sets onboardingCompleted: true
GET /api/users Admin/Mentor List all users with pagination and role filter
GET /api/users/:id Admin Get user by ID
PUT /api/users/:id/role Admin Update a user's role

Cohorts

Method Route Auth Description
POST /api/cohorts Admin Create a cohort
GET /api/cohorts Admin/Mentor List all cohorts
GET /api/cohorts/:id Admin/Mentor Get cohort details
POST /api/cohorts/assign-user Admin Assign an intern to a cohort

Enrollments

Method Route Auth Description
GET /api/enrollments Intern All enrollments with full course + module data
POST /api/enrollments Intern Enroll in a course — one active course at a time

Courses

Method Route Auth Description
GET /api/courses Any All active courses
POST /api/courses Admin Create a course
GET /api/courses/:id/overview Any Course detail — modules, resources, mentor, session IDs
GET /api/courses/:id/progress Intern Progress across all modules
GET /api/courses/:id/modules Any Ordered list of modules
POST /api/courses/:id/assign-mentor Admin Assign a mentor to a course

Modules

Method Route Auth Description
POST /api/courses/:courseId/modules Mentor/Admin Create a module
GET /api/modules/:id/progress Intern Per-lesson completion status
GET /api/modules/:id/lessons Any All lessons in a module
PUT /api/modules/:id Mentor/Admin Update a module
DELETE /api/modules/:id Admin Delete a module

Lessons

Method Route Auth Description
POST /api/modules/:moduleId/lessons Mentor/Admin Create a lesson
PUT /api/lessons/:id Mentor/Admin Update a lesson
DELETE /api/lessons/:id Admin Delete a lesson
POST /api/lessons/:id/complete Intern Mark lesson complete — idempotent, triggers progress recompute
GET /api/lessons/:id/progress Intern Completion status of a single lesson
POST /api/lessons/:id/study-log Intern Log study time { duration: number } (minutes)
GET /api/lessons/:id/study-log Intern All study log entries for a lesson

Assignments

Method Route Auth Description
POST /api/assignments Mentor/Admin Create an assignment
GET /api/assignments/course/:courseId Any All assignments for a course
GET /api/assignments/:id Any Single assignment detail
PUT /api/assignments/:id Mentor/Admin Update an assignment
DELETE /api/assignments/:id Admin Delete an assignment

Submissions

Method Route Auth Description
GET /api/submissions Intern All of the intern's submissions
GET /api/submissions/:id Any Submission detail with grade and feedback
POST /api/submissions/:assignmentId Intern Submit — { submissionType, fileUrl, figmaUrl, portfolioUrl, noteToMentor }
PUT /api/submissions/:assignmentId/resubmit Intern Update an existing submission

Resources

Method Route Auth Description
POST /api/resources Mentor/Admin Create a resource — attach to course, module, or lesson
GET /api/resources/course/:courseId Any Course-level resources
GET /api/resources/module/:moduleId Any Module-level resources
GET /api/resources/lesson/:lessonId Any Lesson-level resources
PUT /api/resources/:id Mentor/Admin Update a resource
DELETE /api/resources/:id Mentor/Admin Delete a resource

Study Logs

Method Route Auth Description
GET /api/study-logs/me Intern Total study time summary
GET /api/study-logs/me/overtime Intern Grouped hours — ?period=daily|weekly|monthly

Analytics

Method Route Auth Description
GET /api/analytics/me Intern Full snapshot — GPA, streaks, certificates, enrollments
GET /api/analytics/me/modules Intern Per-module performance — ?courseId= to filter
GET /api/analytics/me/study-overtime Intern Study hours over time — ?period=daily|weekly|monthly

Certificates

Method Route Auth Description
GET /api/certificates/me Intern All earned certificates
GET /api/certificates/:id Any Single certificate with full detail
POST /api/certificates Admin Manually issue a certificate

Discussions

Method Route Auth Description
POST /api/discussions Any Create a thread — type: COURSE | TEAM | DIRECT
GET /api/discussions/:id Any Full thread with all replies
POST /api/discussions/:id/replies Any Post a reply
DELETE /api/discussions/:id/replies/:replyId Any Delete a reply (own, or Admin)

Live Sessions

Method Route Auth Description
POST /api/live-sessions Mentor/Admin Create a session — { title, courseId, scheduledAt, duration, platform, platformUrl }
GET /api/live-sessions/:id Any Session details
PUT /api/live-sessions/:id Mentor/Admin Update a session
DELETE /api/live-sessions/:id Admin Delete a session
POST /api/live-sessions/:id/rsvp Intern RSVP to a session
DELETE /api/live-sessions/:id/rsvp Intern Cancel RSVP

Teams

Method Route Auth Description
POST /api/teams Admin Create a team
GET /api/teams Any List all teams
GET /api/teams/:id Any Team details with members
POST /api/teams/:id/members Admin Add a member to a team

Dashboard

Method Route Auth Description
GET /api/dashboard Intern Aggregated dashboard data — stats, active enrollment, module progress

Data Models (Summary)

Model Key Purpose
User All users — role: INTERN | MENTOR | ADMIN
Cohort Group of interns on the same track
Course Learning content container
Module Ordered section within a course — can be locked
Lesson Individual unit — type: VIDEO | ARTICLE
Enrollment Links User to Course — tracks progress, status, averageGrade
LessonProgress Records lesson completion — triggers progress recompute
StudyLog Time spent on a lesson in minutes
Assignment Task issued per course/module with due date
Submission Intern's response — tracks grade and mentor feedback
Resource Reference material — attached to course, module, or lesson
Certificate Auto-issued when enrollment reaches 100%
Discussion Message thread — type: COURSE | TEAM | DIRECT
LiveSession Scheduled session — platform: ZOOM | GOOGLE_MEET | YOUTUBE | OTHER
LiveSessionRSVP Intern's registration for a live session
Team Cross-functional intern group

Automated Side Effects

  • Lesson marked completeEnrollment.progress recomputed automatically
  • Module fully complete → next module's isLocked set to false
  • Enrollment reaches 100% → status set to COMPLETED, certificate auto-issued
  • RSVP createdLIVE_SESSION_REMINDER notification created for the intern

Error Response Format

All errors return a consistent JSON shape:

{
  "success": false,
  "message": "Descriptive error message"
}

Common status codes: 400 Bad Request · 401 Unauthorized · 403 Forbidden · 404 Not Found · 429 Rate Limit Exceeded · 500 Server Error


Deployment

The backend is deployed on Render as a web service using a Dockerfile for reproducible builds.

Live URL: https://talentflow-backend-7pp4.onrender.com
Database: Neon PostgreSQL

On first deploy or after schema changes, Prisma migrations run automatically via the start script:

npx prisma migrate deploy && node dist/server.js

Contributing

  1. Branch off main — use feature/, fix/, or chore/ prefixes
  2. Never commit .env — it is gitignored
  3. Run npx prisma generate after any schema change
  4. Keep prisma.config.ts committed — it is required for Railway/Render build to resolve routes correctly

TalentFlow LMS — Trueminds Innovations · 2026

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors