web-based Helpdesk Ticketing Solution from scratch for a small/medium organization with simple hosting using PHP + Laravel,



web-based Helpdesk Ticketing Solution from scratch for a small/medium organization with simple hosting using PHP + Laravel


1. System Overview

Goal: Build a web-based system to manage support requests (tickets) with user login, ticket creation, assignment, tracking, and reporting.

Stack:

  • Backend: PHP with Laravel framework

  • Frontend: Blade templates (Laravel’s default) + optional JS for interactivity

  • Database: MySQL or MariaDB

  • Hosting: Shared hosting or VPS with PHP and MySQL support

Users / Roles:

  1. Admin: Manage users, categories, view reports, assign tickets

  2. Support Agent: View assigned tickets, update status, communicate with users

  3. End User: Create tickets, view their own tickets, receive updates


2. Core Features

Ticket Management:

  • Create, view, edit, and close tickets

  • Assign tickets to support agents

  • Categorize tickets (IT, HR, Facilities, etc.)

  • Priority levels (Low, Medium, High, Critical)

User Management:

  • Register / Login system for users

  • Admin can add/edit agents and users

Communication / Updates:

  • Add comments or replies to tickets

  • Notify users via email on ticket creation/updates (optional SMTP integration)

Dashboard / Reporting:

  • Admin/agent dashboard showing open, pending, and resolved tickets

  • Filter tickets by category, priority, or status

  • Simple charts or tables for ticket statistics

Optional / Advanced Features:

  • SLA management (track response/resolution time)

  • Knowledge base for FAQs

  • Attachments (e.g., screenshots of issues)


3. Database Design

Here’s a simple schema:

Tables:

  1. users
    | Column | Type | Description |
    |--------|------|-------------|
    | id | INT (PK) | User ID |
    | name | VARCHAR | Full name |
    | email | VARCHAR | Login email |
    | password | VARCHAR | Hashed password |
    | role | ENUM('admin','agent','user') | User role |
    | created_at, updated_at | TIMESTAMP | Laravel timestamps |

  2. tickets
    | Column | Type | Description |
    |--------|------|-------------|
    | id | INT (PK) | Ticket ID |
    | user_id | INT (FK) | Who created the ticket |
    | agent_id | INT (FK) | Assigned agent |
    | category | VARCHAR | Ticket category |
    | priority | ENUM('Low','Medium','High','Critical') | Priority |
    | status | ENUM('Open','In Progress','Resolved','Closed') | Ticket status |
    | subject | VARCHAR | Ticket subject |
    | description | TEXT | Detailed description |
    | created_at, updated_at | TIMESTAMP | Laravel timestamps |

  3. ticket_comments
    | Column | Type | Description |
    |--------|------|-------------|
    | id | INT (PK) | Comment ID |
    | ticket_id | INT (FK) | Associated ticket |
    | user_id | INT (FK) | Who commented |
    | comment | TEXT | Comment text |
    | created_at | TIMESTAMP | Timestamp |

  4. categories (optional for dynamic categories)
    | Column | Type | Description |
    |--------|------|-------------|
    | id | INT (PK) | Category ID |
    | name | VARCHAR | Category name |


4. Laravel Implementation Plan

  1. Setup Laravel

composer create-project laravel/laravel helpdesk
cd helpdesk
php artisan serve
  1. Database Configuration

  • Configure .env for MySQL:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=helpdesk
DB_USERNAME=root
DB_PASSWORD=
  1. Create Models & Migrations

php artisan make:model Ticket -m
php artisan make:model TicketComment -m
php artisan make:model Category -m
php artisan make:model User -m
  • Add relationships in models:

    • User → hasMany Tickets, hasMany TicketComments

    • Ticket → belongsTo User, belongsTo Agent, hasMany TicketComments

    • TicketComment → belongsTo Ticket, belongsTo User

  1. Authentication

  • Use Laravel Breeze or Jetstream for login/register functionality:

composer require laravel/breeze --dev
php artisan breeze:install
npm install && npm run dev
php artisan migrate
  1. Ticket CRUD

  • Create controllers: TicketController, TicketCommentController, CategoryController

  • Define routes in web.php:

Route::resource('tickets', TicketController::class);
Route::post('tickets/{ticket}/comments', [TicketCommentController::class, 'store']);
  1. Dashboard & Views

  • Blade templates for:

    • Ticket list (all tickets for admin/assigned tickets for agents)

    • Ticket creation form

    • Ticket detail view with comments

  1. Optional Features

  • Email notifications via Laravel’s Mail system

  • File uploads for attachments

  • Filters and reports using Laravel Eloquent queries


5. Deployment & Hosting

  • Shared hosting (cPanel) or VPS with PHP >= 8, MySQL, Apache/Nginx

  • Upload Laravel files, set up .env, run migrations:

php artisan migrate --force
  • Set folder permissions for storage and bootstrap/cache

  • Use Laravel scheduler for automated tasks (like email reminders)


6. Scaling / Future Enhancements

  • Add roles & permissions using spatie/laravel-permission package

  • API endpoints for mobile app integration

  • Integrate real-time notifications with Laravel Echo & Pusher

  • Analytics dashboard with charts (Chart.js or ApexCharts)



                       +---------------------+
                       |      End Users      |
                       |  (Employees/Clients)|
                       +----------+----------+
                                  |
                                  | Create Ticket
                                  v
                       +---------------------+
                       |   Web Frontend      |
                       |  (Blade Templates / |
                       |   JS Interactivity) |
                       +----------+----------+
                                  |
                                  | Submit / View Tickets
                                  v
                       +---------------------+
                       |   Laravel Backend   |
                       |  (Controllers,      |
                       |   Models, Services) |
                       +----------+----------+
                                  |
        +-------------------------+--------------------------+
        |                         |                          |
        v                         v                          v
+----------------+       +----------------+         +----------------+
| Ticket System  |       | User System    |         | Notification/  |
| (Tickets,      |       | (Users &       |         | Email System   |
| Categories,    |       | Roles/Agents)  |         | (Optional)     |
| Priority,      |       +----------------+         +----------------+
| Status,        |
| Comments)      |
+--------+-------+
         |
         | Read/Write
         v
+---------------------------+
|       Database            |
|  MySQL / MariaDB          |
|---------------------------|
| Tables:                   |
|  - users                  |
|  - tickets                |
|  - ticket_comments        |
|  - categories             |
+---------------------------+
         ^
         |
         | Query/Update
         v
+---------------------------+
| Admin / Support Agents    |
| - View Tickets            |
| - Assign Tickets          |
| - Update Status / Reply   |
| - Generate Reports        |
+---------------------------+

-----------------------------------------------------------------------

          +-------------------+
          |   Ticket Created  |
          | (by End User)     |
          +---------+---------+
                    |
                    v
          +-------------------+
          |   Ticket Assigned |
          | (to Support Agent)|
          +---------+---------+
                    |
                    v
          +-------------------+
          |  Ticket In Progress|
          |  (Investigation / |
          |   Updates / Replies)|
          +---------+---------+
                    |
          +---------+---------+
          |                   |
          v                   v
 +-------------------+   +-------------------+
 |  Resolved         |   | Escalated / Pending|
 |  (Issue Fixed)    |   | (Further Action)   |
 +---------+---------+   +---------+---------+
           |                       |
           v                       |
     +-------------------+         |
     |   Ticket Closed   | <-------+
     |  (User Informed)  |
     +-------------------+



1. Ticket Lifecycle Flowchart with Statuses

          +-------------------+
          |   Ticket Created  |
          | status = 'open'   |
          | (by End User)     |
          +---------+---------+
                    |
                    v
          +-------------------+
          |   Ticket Assigned |
          | status = 'assigned'|
          | (to Support Agent)|
          +---------+---------+
                    |
                    v
          +-------------------+
          |  In Progress      |
          | status = 'in_progress' |
          | (Agent working /  |
          |  adding comments) |
          +---------+---------+
                    |
          +---------+---------+
          |                   |
          v                   v
 +-------------------+   +-------------------+
 |  Resolved         |   | Escalated / Pending|
 | status='resolved' |   | status='pending'   |
 | (Issue fixed)     |   | (Need more action)|
 +---------+---------+   +---------+---------+
           |                       |
           v                       |
     +-------------------+         |
     |   Ticket Closed   | <-------+
     | status='closed'   |
     | (User Informed)   |
     +-------------------+

2. Ticket Status Table

Status Code Description Laravel Enum / DB Value
open Ticket created, not yet assigned 'open'
assigned Assigned to an agent 'assigned'
in_progress Agent is working on ticket 'in_progress'
resolved Issue resolved by agent 'resolved'
pending Needs more info / escalated 'pending'
closed Ticket confirmed resolved and closed 'closed'

3. Suggested Database Table Design (tickets)

Table: tickets
+-------------------+---------------------+--------------------------+
| Column Name       | Type                | Description              |
+-------------------+---------------------+--------------------------+
| id                | INT (PK, auto_inc)  | Ticket ID                |
| user_id           | INT (FK)            | Who created the ticket   |
| agent_id          | INT (FK, nullable)  | Assigned agent           |
| category          | VARCHAR(50)         | Ticket category (IT/HR) |
| priority          | ENUM('Low','Med','High','Critical') | Priority level |
| status            | ENUM('open','assigned','in_progress','resolved','pending','closed') | Current status |
| subject           | VARCHAR(255)        | Ticket subject           |
| description       | TEXT                | Detailed issue           |
| created_at        | TIMESTAMP           | Auto timestamp           |
| updated_at        | TIMESTAMP           | Auto timestamp           |
+-------------------+---------------------+--------------------------+

4. Laravel Model Example (Ticket.php)

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Ticket extends Model
{
    use HasFactory;

    protected $fillable = [
        'user_id',
        'agent_id',
        'category',
        'priority',
        'status',
        'subject',
        'description',
    ];

    // Relationships
    public function user() {
        return $this->belongsTo(User::class, 'user_id');
    }

    public function agent() {
        return $this->belongsTo(User::class, 'agent_id');
    }

    public function comments() {
        return $this->hasMany(TicketComment::class);
    }

    // Status check helper functions
    public function isOpen() {
        return $this->status === 'open';
    }

    public function isAssigned() {
        return $this->status === 'assigned';
    }

    public function isInProgress() {
        return $this->status === 'in_progress';
    }

    public function isResolved() {
        return $this->status === 'resolved';
    }

    public function isPending() {
        return $this->status === 'pending';
    }

    public function isClosed() {
        return $this->status === 'closed';
    }
}

5. Laravel Migration Example (tickets table)

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateTicketsTable extends Migration
{
    public function up()
    {
        Schema::create('tickets', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained('users');
            $table->foreignId('agent_id')->nullable()->constrained('users');
            $table->string('category', 50);
            $table->enum('priority', ['Low','Medium','High','Critical'])->default('Low');
            $table->enum('status', ['open','assigned','in_progress','resolved','pending','closed'])->default('open');
            $table->string('subject');
            $table->text('description');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('tickets');
    }
}

Ticket → TicketComment relationship, including Users, Agents, database tables, ticket lifecycle, and Laravel model interactions. This will give you a full picture of the system architecture for coding.


                     +---------------------+
                     |       Users         |
                     |---------------------|
                     | id (PK)             |
                     | name                |
                     | email               |
                     | password            |
                     | role ('user','agent','admin') |
                     +---------+-----------+
                               |
                               | Creates / Comments
                               v
                     +---------------------+
                     |       Tickets       |
                     |---------------------|
                     | id (PK)             |
                     | user_id (FK -> users.id) |
                     | agent_id (FK -> users.id, nullable) |
                     | category            |
                     | priority            |
                     | status              |
                     | subject             |
                     | description         |
                     | created_at          |
                     | updated_at          |
                     +---------+-----------+
                               |
                               | Has Many
                               v
                     +---------------------+
                     |   TicketComments    |
                     |---------------------|
                     | id (PK)             |
                     | ticket_id (FK -> tickets.id) |
                     | user_id (FK -> users.id)    |
                     | comment             |
                     | created_at          |
                     +---------------------+


Explanation of the Diagram

  1. Users Table

    • Stores all users (end users, agents, admin).

    • The role field determines what permissions each user has.

  2. Tickets Table

    • Each ticket is created by a user (user_id).

    • Each ticket can be assigned to an agent (agent_id) or remain unassigned.

    • Tracks status through the ticket lifecycle (open, assigned, in_progress, resolved, pending, closed).

    • Ticket belongs to a user (creator) and optionally to an agent (assignee).

  3. TicketComments Table

    • Each comment belongs to a ticket (ticket_id) and is made by a user (user_id).

    • Allows conversation/history between the user and the agent on a ticket.


How Laravel Models Interact

  • User.php

public function ticketsCreated() { return $this->hasMany(Ticket::class, 'user_id'); }
public function ticketsAssigned() { return $this->hasMany(Ticket::class, 'agent_id'); }
public function comments() { return $this->hasMany(TicketComment::class); }
  • Ticket.php

public function user() { return $this->belongsTo(User::class, 'user_id'); }
public function agent() { return $this->belongsTo(User::class, 'agent_id'); }
public function comments() { return $this->hasMany(TicketComment::class); }
  • TicketComment.php

public function ticket() { return $this->belongsTo(Ticket::class); }
public function user() { return $this->belongsTo(User::class); }

Ticket Lifecycle Integration

Ticket Status Field → Lifecycle
--------------------------------
open        → Ticket just created
assigned    → Ticket assigned to an agent
in_progress → Agent is working / adding comments
resolved    → Issue resolved by agent
pending     → Waiting for more info or escalation
closed      → Ticket confirmed closed by user/admin

Flow:

  • Users create TicketsTickets assigned to AgentsTicketComments allow conversation → Status updates change lifecycle → Final closure.


This diagram, combined with the Laravel relationships, gives a complete blueprint for implementation:

  • Database tables and foreign keys

  • Relationships in Laravel models

  • Ticket lifecycle management

  • Commenting system



Comments

Popular posts from this blog

Differences Between Ubuntu 24.04.2 LTS and Ubuntu 25.04

Kapardak Bhasma: A Comprehensive Review and use

Vanga Bhasma: A Traditional Ayurvedic Metallic Formulation and use