DDriving School CRM

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.

15features a school can switch on or off
3staff roles, plus custom roles
66pages across staff app and portal
93API routes
40database tables, 4 reporting views

Who uses it

The app has two sides that share one database: a staff dashboard for the school and a portal for its students.

/sys-ops

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.
/verify-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.

Settings → Workspace

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.

  1. 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
  2. Learner licence (LLR)

    Staff track the LLR application, test date, result and retest attempts.

    LLRSchedule
  3. 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
  4. 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
  5. 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
  6. 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.

Check 1 · workspace

Is the feature on?

Feature switches apply to everyone, super admins included. Pages show a "feature is off" screen; APIs return 403.

Check 2 · person

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.

Check 3 · data

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.

Result

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.

Videos 1–3→ Quiz→ Videos 4–6→ Quiz→ 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 ffmpeg into 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.

SetupWhat 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.
Before going live: the Razorpay integration is covered by unit tests for signature checks and webhook handling but hasn't been run against Razorpay's live servers. Test it with test-mode keys first.

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.

LayerChoice
FrameworkNext.js 16 (App Router), React 19, TypeScript
StylingTailwind CSS 4, CSS variables for theme and accent, DM Sans
DatabaseDemo: in-memory SQLite (node:sqlite) seeded from lib/data/config.ts. Production: MySQL via mysql2, same query interface.
AuthJWT in cookies, separate secrets for staff and students; passwords hashed with bcrypt
DocumentsPDFKit for invoices and certificates, pdf-parse for reading RTO forms, qrcode, xlsx for report export
Videoffmpeg to encrypted HLS, played with hls.js
ChartsRecharts
EmailNodemailer over SMTP (invoice and welcome emails)
PaymentsRazorpay, behind a gateway layer that can take other providers
TestsJest: 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

RoleEmailPassword
Super adminsuperadmin@demo.testAdmin@123
Adminadmin@demo.testAdmin@123
Staff (limited modules)staff@demo.testStaff@123
Customer portalananya.rao@example.comUser@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.