Admissions Counselling Platform
A six-role platform that runs a university-admissions counselling operation end to end.

Admissions counselling is coordination-heavy. A single student's journey involves a counsellor building a task plan, teachers running tutoring sessions and marking attendance, parents wanting visibility, personal statement drafts going back and forth, transcripts and reference letters being collected, a university shortlist being negotiated, and a monthly report going to the family, usually scattered across spreadsheets, email threads, and word processors.
The platform puts every stakeholder in one system with a view scoped to their role. A counsellor sees their caseload; a guardian sees their child's progress; a teacher sees their sessions and attendance sheets; an admin sees the whole organization, including which monthly reports are still outstanding.
We delivered the full stack: a Next.js frontend with five dashboard trees, an Express and TypeORM backend of roughly 30 API modules over 34 database entities and 71 schema migrations, a real-time Socket.io layer, a server-side document pipeline, and CI/CD across three backend environments plus Vercel hosting.
Six stakeholders, one student, no shared system
The organization's work lived in spreadsheets, email threads, and word processors. Counsellors, students, parents, teachers, and administrators each needed a different view of the same underlying activity, and nobody had a reliable answer to operational questions like which monthly reports were still outstanding or which statements were waiting on feedback.
The harder engineering problems were the parts that replace manual work outright: generating branded PDF reports from templates automatically, scoring university fit through external region-specific services for two national admissions systems, and keeping six kinds of users notified through the channels they actually check.

One user model, six roles, permissions as data
Rather than separate apps, a single Next.js application serves five dashboard trees, admin, counsellor, student, teacher, guardian, with a super-admin tier on the API. Users can hold multiple roles: login issues an independent server-side session token per role, and route middleware confines each role to its own area.
We modeled access as role, resource, and action records in the database with per-user overrides, so an organization can tune what a counsellor or teacher may create, view, update, or delete without a code change. The backend is layered, routers, controllers, services, TypeORM entities, with shared middleware for validation, pagination, response formatting, and rate limiting, and every schema change ships as a migration applied automatically on deploy.
Follow-up doesn't depend on anyone remembering to follow up: due-task and session reminders fire every minute, completed items archive nightly, report reminders go out monthly, and a weekly digest reaches users over WhatsApp/SMS. Chat and live feedback run in real time over Socket.io gateways attached to the same server.

A system of record for the whole counselling operation
Counsellors manage students through typed tasks, academic, non-academic, forms, transcripts, references, with priorities, due dates, checklists, and per-organization custom statuses, plus a reusable task library. Counselling and tutoring sessions carry notes, statuses, linked homework, and per-session attendance. Students draft personal statements in a rich-text editor tied to a target university, and counsellors respond with threaded feedback the student sees alongside the draft.
For university shortlisting, the platform assembles each student's academic profile, GPA, SAT/ACT sub-scores, IB points and subjects, school type, intended major, and submits it to external region-specific scoring services for US and UK admissions, the UK one built around UCAS course codes. Returned matches are reconciled against the platform's own university catalog, reviewed with counsellors, and approved selections persist as the student's shortlist.
Monthly progress reports are written in the app and rendered through a real document pipeline: content converts to HTML, merges into an admin-managed DOCX template, converts to PDF, and uploads to S3, with a monthly job that identifies students still lacking a report and nudges their counsellor. Communication spans built-in chat, in-app notifications, browser push via Firebase Cloud Messaging, and a weekly WhatsApp/SMS digest delivered through Vonage. Admins get bulk CSV user import with row-level failure reporting, departments, calendars, resource libraries, report templates, and activity logs.
Six-role access model
Super-admin, admin, counsellor, student, teacher, and guardian each get a role-scoped workspace, with database-driven permissions and per-user overrides that change behavior without a redeploy.
University matching (Unimatch)
Structured academic profiles are scored by external US and UK admissions services, reconciled against the platform's university catalog, and turned into counsellor-approved shortlists with Target, Reach, and Safety tiers.
Task and session management
Typed tasks with checklists, priorities, due dates, and custom statuses on drag-and-drop boards; sessions with notes, linked homework, and per-session attendance tracking.
Statement feedback workflow
Students draft personal statements per target university in a rich-text editor; counsellors respond with threaded, timestamped feedback, and a review queue shows which students are still waiting.
Automated monthly reporting
Reports merge into organization-managed DOCX templates, convert to branded PDFs server-side, upload to S3, and a monthly job chases counsellors for any student still missing one.
Chat and multi-channel notifications
Built-in real-time chat with presence and unread counts, plus notifications in-app, over browser push, and as an opt-in weekly WhatsApp/SMS digest.






- 01
Per-role session tokens
A user who is both counsellor and admin gets separate server-side sessions per role, so role switching is explicit and each token's authority is narrow. Sessions live in PostgreSQL, making revocation and expiry straightforward.
- 02
Migration-first schema over 34 entities
PostgreSQL through TypeORM covers users and their relationship graph, organizations, tasks, sessions, attendance, statements, universities, matches, reports, permissions, and conversations, with 71 versioned migrations applied automatically on deploy.
- 03
Server-side document pipeline
Docxtemplater merges report content into admin-managed DOCX templates, with DOCX-to-PDF conversion via Puppeteer and an optional LibreOffice path for higher fidelity, families receive a consistently branded document, and admins change the template without developers.
- 04
Real-time layer on Socket.io
Chat and live feedback run over Socket.io gateways sharing the HTTP server, with per-user token association, online-presence tracking, and unread counts.
- 05
Three-environment CI/CD
GitHub Actions deploys the frontend to Vercel and the backend over SSH to PM2-managed processes across dev, staging, and production, running migrations automatically on deploy.
- A single system of record replaces spreadsheet-and-email coordination across six user roles.
- Monthly reporting runs from template to branded PDF automatically, with automatic follow-up on missing reports.
- University shortlisting follows a structured workflow backed by external scoring services for both US and UK admissions.
- Students and families stay engaged through built-in chat and three notification channels: in-app, web push, and a WhatsApp/SMS digest.
- Operational tooling, bulk user import, configurable permissions and task statuses, activity logs, multi-environment CI/CD, supports running the platform as a business.