In production
Mentrex
The learning platform Mentrex Academy runs on: courses, enrolments, fees, assessments and student progress in one system.
- Role
- Lead engineer: design, data model, backend and front end
- When
- Apr 2025 – present
- Status
- In production at Mentrex Academy
- Stack
- Next.js · TypeScript · PostgreSQL · Prisma · TanStack Query · Zod · Tailwind CSS · Resend
Overview
Mentrex is the learning management system behind Mentrex Academy, a tech-course institute in Kerala. One Next.js app serves two portals:
- Admins and instructors manage courses, modules, students, fees, assessments and feedback.
- Students work through their courses, take assessments, practise weak topics and log daily check-ins.
I've built and maintained it since April 2025. It grew with the academy, from course content to assessments, payments, stand-ups, leave requests and events. Each step meant schema migrations on a live database with real student data in it.
The problem
A small institute runs on a lot of moving parts. Course material lives in one place, fee tracking in another, and who's stuck on which module mostly lives in instructors' heads.
Three groups need different answers from the same data:
- Instructors need to know who's falling behind.
- Admins need to know who owes what.
- Students need a clear next step.
The goal was one system where all three come from the same records.
My role
- The data model and its migrations: Prisma on PostgreSQL (Neon), now 39 models.
- Authentication, sessions, password reset and role-based access for admins, instructors and students.
- The module-progression and assessment engines.
- The admin, instructor and student interfaces.
- Deployment, plus ongoing changes as the academy's needs change.
Architecture
A single Next.js App Router application with separate route groups and layouts for each portal. Route handlers validate input with Zod and call domain modules. The domain modules own the rules for progress, assessments and activity logging.
- Portals
- Admin & instructor(admin) route group
- Student(student) route group
HttpOnly session cookie - Middleware
- Session · RBAC · CSRF origin check · rate limit
- Server
- Route handlersZod validation, ownership checks
- Domain modulesprogression, assessments, activity log
Prisma - Services
- PostgreSQL (Neon)39 models
- Resendtransactional email
- ImageKitprofile images
What it does
- Reusable curriculum. A module can belong to several courses through an ordered join table, so content isn't duplicated when a new course reuses it.
- Mixed content. Video, PDF, quiz, assignment, link, image and note items, with drag-and-drop ordering.
- Assessments and practice. Question banks are tagged by topic and difficulty. Graded attempts can be resumed. Practice mode doesn't touch grades. After each attempt, a report breaks results down by topic and difficulty.
- Fees. Enrolments carry fee schedules, payments are recorded across methods, and invoices are generated as PDFs.
- Day-to-day accountability. Learning sessions close automatically. There's an activity log, daily check-ins and stand-ups, a personal Kanban board, leave requests, and events with teams.
- Instructor tools. Typed, prioritised feedback to students, plus analytics on enrolments, revenue and performance.
Engineering decisions
Progression as an explicit state machine
- Why
- Each enrolment has one progress row per course module. Its status moves from
LOCKEDthroughIN_PROGRESS,CONTENT_COMPLETEDandASSESSMENT_READYtoPASSEDorCOMPLETED. Finishing a module's content unlocks the next one. Passing its assessment isn't required to move on, which matches how the academy teaches. Admins can unlock a module by hand. Recalculation functions rebuild progress when a course's modules change, and a module is re-locked only if the student hasn't started it. - Instead of:
- computing progress on the fly from content completions, which makes manual overrides and history hard to express.
Grade on the server, sanitise what the client sees
- Why
- Questions are stripped down before they're sent: text, type, difficulty, points, tags and (optionally shuffled) options. Correct answers and explanations stay on the server. Answers are saved one at a time and scored on submit.
Revocable sessions behind signed cookies
- Why
- Tokens are signed with
joseand set as HttpOnly cookies. Each token also maps to a session row, so it can be revoked before it expires. Password reset uses a separate one-hour token and returns the same response whether or not the account exists.
Known gaps
- It's single-tenant by design. Serving a second institute means scoping the schema by tenant, and I've written up what that would take.
- Rate limiting is in memory. That's fine on one instance and wrong on several; it would move to the database or Redis.
- Automated tests are thin. The progression engine is the first thing I'd cover, since it holds the most rules.