GHL-ITSM is a free, open-source multi-tenant IT service management portal built with Laravel. This guide will help you get up and running quickly.
# Clone the repository
git clone https://github.com/your-org/ghl-itsm.git
cd ghl-itsm
# Install dependencies
composer install
npm install
# Setup environment
cp .env.example .env
php artisan key:generate
# Run migrations and seed data
php artisan migrate --seed
php artisan db:seed --class=MultiTenantTestDataSeeder
# Start development server
php artisan serve
Visit http://localhost:8000
to see your application.
git clone https://github.com/your-org/ghl-itsm.git
cd ghl-itsm
# Install PHP dependencies
composer install
# Install Node.js dependencies
npm install
# Build assets
npm run build
# Copy environment file
cp .env.example .env
# Generate application key
php artisan key:generate
Edit the .env
file with your database credentials:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=ghl_itsm
DB_USERNAME=your_username
DB_PASSWORD=your_password
# Run migrations
php artisan migrate
# Seed with test data
php artisan db:seed --class=MultiTenantTestDataSeeder
# Create super admin user
php artisan make:super-admin [email protected]
Variable | Description | Default |
---|---|---|
APP_NAME |
Application name | GHL-ITSM |
APP_ENV |
Environment (local, production) | local |
DB_DATABASE |
Database name | ghl_itsm |
MAIL_MAILER |
Email driver | smtp |
# Set proper permissions
chmod -R 755 storage bootstrap/cache
chown -R www-data:www-data storage bootstrap/cache
GHL-ITSM uses a multi-tenant architecture where each client has isolated data. This section explains how to set up and manage client accounts.
Client accounts can be created through the super admin interface or programmatically:
// Create a client account programmatically
use App\Models\ClientAccount;
$clientAccount = ClientAccount::create([
'name' => 'John Smith',
'company_name' => 'TechStartup Inc',
'email' => '[email protected]',
'monthly_hours' => 10,
'contract_value' => 700.00,
'contract_start_date' => '2024-01-01',
'status' => 'active',
]);
Service windows track monthly hours for each client:
// Create a service window
use App\Models\ServiceWindow;
$serviceWindow = ServiceWindow::create([
'client_account_id' => $clientAccount->id,
'month_year' => now()->format('Y-m'),
'allocated_hours' => 10,
'used_hours' => 0,
'remaining_hours' => 10,
'status' => 'active',
]);
All data is automatically isolated by client_account_id. The system ensures:
// Create a super admin
use App\Models\User;
use App\Models\UserRole;
$superAdmin = User::create([
'name' => 'Admin User',
'email' => '[email protected]',
'password' => bcrypt('password'),
'role' => UserRole::SUPER_ADMIN,
'client_account_id' => null,
]);
// Create a tech user
$tech = User::create([
'name' => 'Tech User',
'email' => '[email protected]',
'password' => bcrypt('password'),
'role' => UserRole::PROVIDER,
'client_account_id' => null,
]);
// Create a client user
$client = User::create([
'name' => 'Client User',
'email' => '[email protected]',
'password' => bcrypt('password'),
'role' => UserRole::CLIENT,
'client_account_id' => $clientAccount->id,
]);
All API endpoints require authentication. Include the Bearer token in the Authorization header:
Authorization: Bearer {your-token}
Get all tickets (filtered by user role)
curl -X GET "http://your-domain.com/api/tickets" \
-H "Authorization: Bearer {token}"
Response: JSON array of tickets
Create a new ticket
curl -X POST "http://your-domain.com/api/tickets" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"title": "New Support Request",
"description": "I need help with my website",
"priority": "medium"
}'
Update ticket status
curl -X PATCH "http://your-domain.com/api/tickets/1/status" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"status": "in-progress",
"hours_spent": 2
}'
# Clone repository
git clone https://github.com/your-org/ghl-itsm.git
cd ghl-itsm
# Install dependencies
composer install --optimize-autoloader --no-dev
npm install
npm run build
# Environment setup
cp .env.example .env
# Edit .env with production values
# Generate key and run migrations
php artisan key:generate
php artisan migrate --force
# Set permissions
chmod -R 755 storage bootstrap/cache
chown -R www-data:www-data storage bootstrap/cache
# Configure web server
# Point document root to public/ directory
server {
listen 80;
server_name your-domain.com;
root /path/to/ghl-itsm/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
If you encounter permission errors:
chmod -R 755 storage bootstrap/cache
chown -R www-data:www-data storage bootstrap/cache
Check your database configuration:
# Test database connection
php artisan tinker
DB::connection()->getPdo();
Clear application cache:
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
We welcome contributions to GHL-ITSM! Please read this section before submitting pull requests.
# Fork and clone the repository
git clone https://github.com/your-username/ghl-itsm.git
cd ghl-itsm
# Install dependencies
composer install
npm install
# Setup environment
cp .env.example .env
php artisan key:generate
# Run migrations and seed data
php artisan migrate --seed
php artisan db:seed --class=MultiTenantTestDataSeeder
# Run tests
php artisan test
Run the test suite before submitting:
# Run all tests
php artisan test
# Run specific test file
php artisan test tests/Feature/YourTest.php
# Run with coverage
php artisan test --coverage