Skip to content
All work
Full-Stack ProductLive · 2026

Support & Issue Tracking System

A role-based internal ticketing system — reporters, agents and administrators working the same queue through different permissions — deployed as serverless functions.

  • React
  • Express
  • MongoDB
  • JWT
  • Cloudinary
  • Vercel

Overview

An internal support desk where three roles interact with one queue. Reporters raise and track tickets, agents work and comment on them, administrators manage users and oversee the whole queue. Authentication is JWT-based and authorisation is enforced in middleware, so a role's boundaries are defined in one place rather than re-derived in each route handler.

Problem

Support requests arriving through email and chat have no state, no owner and no history. Nobody can answer who is handling a request, how long it has been open, or what was already tried.

Adding a database alone does not fix it. The moment three roles share one queue, the real problem becomes authorisation: who may reassign, who may close, who may see another person's ticket.

Business context

A support desk is a workflow tool before it is a data store. Its value is in making ownership and state explicit so that work stops being dropped.

It is also the point where an internal tool most often leaks: a missing authorisation check on one endpoint exposes every ticket in the system.

Solution

Three models — user, ticket and comment — with the comment thread attached to the ticket, so the conversation and the state live together rather than in someone's inbox.

Authentication middleware verifies a signed token and attaches the caller; role middleware then gates the route. Adding an endpoint means declaring which roles may reach it, not reimplementing the check.

Attachments are uploaded through Multer and stored on Cloudinary rather than on the application filesystem, which is what makes the service safe to run on ephemeral serverless instances.

An admin seed script creates the first administrator deterministically, so a fresh deployment has a defined starting state instead of requiring a manual database insert.

Architecture

  1. Clients

    Reporter

    Raise and track

    Support agent

    Work and comment

    Administrator

    Users and oversight

  2. Application

    React frontend

    Role-aware views

    Serverless entrypoint

    Vercel function

  3. Access

    JWT auth middleware

    Verify · attach caller

    Role middleware

    Central RBAC

  4. Domain

    Tickets

    Lifecycle and assignment

    Comments

    Threaded per ticket

    Users

    Profiles and roles

  5. Persistence

    MongoDB

    Tickets · comments · users

    Cloudinary

    Attachments

One queue, three roles. Authorisation is centralised in middleware and file storage is external so the compute layer stays stateless.

Implementation

Routes are grouped by resource — auth, tickets, comments, users — with controllers kept thin and shared concerns in middleware.

Tokens are generated through a single utility so signing options and expiry are defined once instead of drifting between endpoints.

The Express application is exported through a dedicated serverless entrypoint so the same codebase runs locally as a server and on Vercel as a function.

No local disk writes: uploads stream to Cloudinary, which is a requirement rather than an optimisation on a platform where the filesystem does not persist between invocations.

Engineering challenges

  • Authorisation that does not drift

    Per-route permission checks are the standard way these systems leak, because one handler eventually forgets. Expressing roles as middleware means an endpoint without an explicit policy is visibly missing one.

  • Stateless compute and file uploads

    Serverless instances do not keep a filesystem. Uploading straight to external object storage is what allows attachments to work at all in that environment.

  • Running one Express app in two environments

    Local development wants a long-lived server; the platform wants a handler. Separating the application from its entrypoint lets both consume the same code without a parallel implementation.

Key decisions

Roles in middleware, not in handlers
It makes authorisation auditable in one file and makes a missing policy conspicuous.
External object storage for attachments
It is the only correct choice on ephemeral compute, and it removes file serving from the application entirely.
A deterministic admin seed
A new environment should reach a known good state through a script, not through manual database edits nobody records.

Results

No production metrics are published for this project yet. I would rather show nothing here than a number I cannot stand behind — the architecture and the decisions above are the part worth reviewing.

Technology

Frontend

  • React
  • Vite
  • Client routing

Backend

  • Node.js
  • Express
  • REST API

Data

  • MongoDB
  • Mongoose
  • Ticket / Comment / User models

Access

  • JWT
  • Auth middleware
  • Role middleware

Media

  • Multer
  • Cloudinary

Deployment

  • Vercel serverless entrypoint

Contact

Have an AI product or workflow worth building?

Send me the problem — not the spec. If it’s a fit I’ll tell you how I’d approach it; if it isn’t, I’ll say so.

Faisalabad, Pakistan · PKT (UTC+5) · Working remotely