Product overview
A CRM and learning platform for driving schools
One app that runs a driving school's front desk and back office: admissions, licence paperwork with the RTO, lessons, fees and invoices. It also gives every student a portal with online video courses, quizzes and a verifiable certificate. It is white-label, so each school sets its own name, logo and accent colour.
Who uses it
The app has two sides that share one database: a staff dashboard for the school and a portal for its students.
Staff dashboard
Where the school's team works every day.
- Super admin: everything, including branches, roles, feature switches and locking the brand colour.
- Admin: runs the school; manages users and settings.
- Staff: sees only the modules they've been given (front desk, accountant and so on).
Customer portal
Where students sign in with credentials the school sends them.
- Licence progress and upcoming lessons or test days.
- Payments, receipts, invoices, and paying the balance online.
- Video courses, quizzes and a downloadable certificate.
Public certificate check
Anyone holding a certificate can scan its QR code or type its number to confirm it's genuine. No sign-in needed.
White-label branding
Business name, logo, contact details, invoice prefix and accent colour all come from settings. The interface is black and white with light and dark themes; the accent is the only colour.
A student's path through the app
Most students follow this route from first visit to licence in hand. Each step maps to a module in the staff dashboard.
-
Admission
Front desk creates the customer, picks one or more services (training and licensing, renewal, badge, address change…) and sets the fee. Uploading the RTO's LLR certificate, Form 2 or acknowledgement PDF fills in name, date of birth, address and application numbers automatically.
CustomersReferrals -
Learner licence (LLR)
Staff track the LLR application, test date, result and retest attempts.
LLRSchedule -
Training
Lessons are booked on a week/day calendar with an instructor and a vehicle. The calendar refuses to double-book an instructor, a vehicle or a student. The student sees their sessions in the portal and can study the theory course online.
TrainingScheduleLMS -
Driving licence (DL)
Slot booking, test result, licence issue and dispatch. The pipeline view shows every student between LLR and DL on one screen, with what they've paid and what they owe.
DLPipeline -
Fees, all the way through
Instalments are recorded as payments, which update invoices and the outstanding balance. Invoices can be emailed or downloaded as PDF; students can pay online from the portal.
PaymentsInvoicesOnline payments -
Later services
Renewals, duplicate licences, address changes and commercial badges are tracked the same way for returning customers.
RenewalsBadge
Features
Four core areas are always on. The other fifteen are switches a super admin controls in Settings → Features. Turning one off hides it from navigation, dashboards and the portal and blocks its pages and APIs for everyone; its data is kept.
Always on
Dashboard
Admissions, applications in progress and recent activity.
Customers
Student records, services, documents and portal access.
Payments
Fees, instalments, receipts and outstanding balances.
Users & settings
Team accounts, module permissions, audit log and workspace settings.
Operations
Learner licence (LLR)
Applications, test dates, results and retests.
Driving licence (DL)
Slots, results, issue and dispatch.
Training sessions
Track driving training and time slots.
Scheduling
Calendar of lessons and test days with instructors, vehicles and clash checks.
Badge applications
Commercial badge applications and dispatch.
Renewals
Renewals, duplicates and address changes.
Pipeline tracker needs LLR + DL
Every student from LLR to DL in one view.
Referrals
Where students come from and who sent them.
Finance
Invoices
Generate, email and download PDF invoices.
Online payments needs portal
Students pay balances and invoices from the portal.
Expenses
Log and categorise business costs.
Insights
Reports
Revenue, admissions and expense charts with Excel export.
Notifications
In-app alerts and the header bell.
Learning and portal
Learning module (LMS)
Courses, video lessons, quizzes, enrolments and certificates.
Customer portal
Student sign-in for progress, payments, invoices and courses.
Who can see what
Every staff request passes three independent checks. They're enforced on the server in
proxy.ts and the route handlers, so hiding a menu item is never the only protection.
Is the feature on?
Feature switches apply to everyone, super admins included. Pages show a "feature is off" screen; APIs return 403.
Does this user have the module?
Roles are named sets of modules. Editing a role updates everyone who holds it. Role and status are re-read on every request, so deactivating someone takes effect immediately.
Is the record in their branch?
Each branch has its own customers, payments and schedule. Staff pinned to a branch never see another branch's records, even by typing an id into the URL.
Allowed
Staff without a branch, and super admins, can switch branches from the header.
The learning module
Schools build theory courses from video lessons and checkpoint quizzes, enrol students individually or by service, and issue certificates automatically.
Courses unlock in segments
A course is split into segments. Segment 1 opens on enrolment; each later one opens when the student passes the checkpoint quiz before it. Finishing everything issues the certificate.
If a student uses up every quiz attempt without passing, the portal tells them to contact the school rather than leaving them stuck.
Protected video delivery
- Uploads are transcoded with
ffmpeginto AES-128 encrypted HLS. - Each playback gets a fresh token valid for 90 seconds, tied to that student and video.
- The playlist is rewritten so segments and the key are served only through token-checked routes.
- Token and playlist requests from other sites are refused.
Admin tools
- Drag-to-reorder course builder and quiz builder.
- Bulk enrolment by service type.
- Analytics: where students stop watching each video, and quiz pass rates.
- Preview any video as staff without enrolling.
Certificates
A certificate gets a stable number when the course is completed. The PDF, with the school's branding and a QR code, is generated on demand when downloaded. The QR code links to the public verification page.
Online payments
Students can pay their balance or a specific invoice from the portal. A successful online payment is recorded as a normal payment with mode Online, updates the invoice and notifies staff.
| Setup | What happens |
|---|---|
| Razorpay keys set | Real checkout. With the webhook at /api/webhooks/payments configured, payments are recorded even if the student closes the browser before returning. |
| No keys, development | A simulated checkout with a fake card form. Nobody is charged. |
| No keys, production | Online payment is unavailable, unless ALLOW_DEMO_PAYMENTS=1 is set for a demo site. A live site can't accidentally let students "pay" for free. |
How it's built
A single Next.js app that serves both the staff dashboard and the portal, with server-rendered pages and route-handler APIs.
| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router), React 19, TypeScript |
| Styling | Tailwind CSS 4, CSS variables for theme and accent, DM Sans |
| Database | Demo: in-memory SQLite (node:sqlite) seeded from lib/data/config.ts. Production: MySQL via mysql2, same query interface. |
| Auth | JWT in cookies, separate secrets for staff and students; passwords hashed with bcrypt |
| Documents | PDFKit for invoices and certificates, pdf-parse for reading RTO forms, qrcode, xlsx for report export |
| Video | ffmpeg to encrypted HLS, played with hls.js |
| Charts | Recharts |
| Nodemailer over SMTP (invoice and welcome emails) | |
| Payments | Razorpay, behind a gateway layer that can take other providers |
| Tests | Jest: unit tests for auth, branches, features, scheduling, payments, quiz grading and the unlock engine, plus API tests |
Where things live
app/ sys-ops/ # staff dashboard: login, modules, admin screens (portal-root)/ # customer portal: login, dashboard, courses, pay, schedule api/ # 93 route handlers, staff + customer-portal + webhooks components/ # shared UI: app shell, tables, search, HLS player, checkout lib/ auth.ts, customerAuth.ts # staff and student sessions features.ts, featureFlags.ts # feature catalogue and stored switches branch.ts, branchAccess.ts # branch scoping for lists and single records roles.ts, modules.ts # roles and module permissions lms/ # unlock engine, grading, video tokens, HLS, certificates payments/ # gateway abstraction and order fulfilment pdf/ # invoice and certificate PDFs extractRTODocument.ts # reads RTO PDFs to pre-fill forms data/ # demo data (delete when moving to MySQL) db.ts # database access db/ # MySQL schema and migrations proxy.ts # request gate: features, sessions, module access, body size __tests__/ # unit and API tests
Running it
Needs Node 22.13 or newer (24 recommended). Out of the box it runs on fictional demo data held in memory, which resets on every restart.
npm install
npm run dev # http://localhost:3000
Demo accounts
| Role | Password | |
|---|---|---|
| Super admin | superadmin@demo.test | Admin@123 |
| Admin | admin@demo.test | Admin@123 |
| Staff (limited modules) | staff@demo.test | Staff@123 |
| Customer portal | ananya.rao@example.com | User@123 |
The sign-in pages have one-tap buttons for each.
Going to production
Database
Apply db/schema.mysql.sql and the migrations, swap lib/db.ts for a mysql2 pool, delete lib/data/. See db/README.md.
Secrets
Set long random JWT_SECRET and CUSTOMER_JWT_SECRET, and NEXT_PUBLIC_APP_URL for emails and QR codes.
Services
SMTP settings for email, ffmpeg and LMS_MEDIA_PATH for video uploads, Razorpay keys and webhook secret for payments.