Skip to content
IndependentWeb2026

Live demo · portfolio project

Helpdesk Ticketing System

IT support ticketing with roles, an audit trail and a responsive UI

An IT support app where staff raise requests and technicians resolve them, with role-based access, a full audit trail and a responsive interface.

The problem

IT requests arrive through chat, email and hallway conversations, so nobody knows what is open, who owns it or what changed. Staff can't see progress, and managers can't see the backlog.

What I built

Built the system in PHP and MySQL on CodeIgniter 3, with one record for every ticket. Access rules are enforced on the server, every status, priority and assignee change is written to an audit trail, and search and pagination keep large queues fast. The interface works on desktop and on tablets, with an off-canvas menu for smaller screens.

Outcome

A complete app with seeded data: sign-in, the ticket lifecycle, comments, role-based access, user administration and the audit trail. Access rules, CSRF protection, session handling and account lockout were checked in the browser and with HTTP-level tests.

Key features

  • Role-based access for staff, technicians and admins
  • Ticket lifecycle with status, priority, category and assignee
  • Audit trail for every status, priority and assignee change
  • Threaded comments on each ticket
  • Search, filters, an open queue and an assigned-to-me view
  • Admin user management with lockout safeguards
  • Responsive layout with an off-canvas menu on smaller screens

Engineering highlights

  • Access control on the server: every ticket and user screen checks the role and ownership. A staff member asking for someone else's ticket gets a 404, so ticket numbers can't be probed.
  • Every status, priority and assignee change is saved together with its audit row, in one transaction, so the history can't drift from the data.
  • A disabled account is locked out on its next request, not when its session expires.
  • Safeguards for admins: they can't disable their own account or remove the last active admin.
  • Search and pagination run in SQL, so large queues stay fast without loading every row.
  • Strict Content Security Policy with no inline scripts, and database credentials read from environment variables.

Architecture

A CodeIgniter 3 front controller routes each request to an MVC controller. Every request re-checks the signed-in user against the database, and all data access goes through models to MySQL.

  1. Client

    • Browser (Bootstrap 5 UI)
  2. Web

    • Apache or PHP built-in server
    • CodeIgniter 3 front controller
  3. App

    • Auth, ticket and user controllers
    • Role guard and login check (MY_Controller)
    • Models and audit trail
  4. Data

    • MySQL / MariaDB
    • Database-backed sessions
  • Sessions are stored in the database, and the session ID is regenerated on sign-in.
  • Every form carries a CSRF token, and the Content Security Policy blocks inline scripts.
  • Database credentials come from environment variables, not from the code.

Tech stack

Back end
  • PHP 8 on CodeIgniter 3 (MVC)
  • Query Builder with parameterised queries
  • Server-side form validation and CSRF protection
  • Database-backed sessions with ID regeneration on sign-in
  • bcrypt password hashing
Data
  • MySQL / MariaDB with foreign keys and indexes
  • Audit trail table written in the same transaction as each change
  • Idempotent schema and seed scripts
Front end
  • Bootstrap 5 with a custom design system
  • Responsive layout with an off-canvas menu
  • Vanilla JavaScript, no framework
Security
  • Content Security Policy and baseline security headers
  • Role checks on the server, not only in the UI
  • Generic sign-in errors, so accounts can't be enumerated