Skip to main content

Development Setup

This guide covers setting up a local development environment for the Rhino Group Ticket System.


Prerequisites

ToolVersionPurpose
PHP8.4+Application runtime
Laravel HerdLatestLocal PHP server (recommended)
MySQL8.0+Database
Node.js20+Frontend build system
Composer2.xPHP dependency management
GitLatestVersion control

Initial Setup

1. Clone the Repository

git clone <repository-url> Z:\Repos\ticket-manager
cd Z:\Repos\ticket-manager

2. Install PHP Dependencies

composer install

3. Configure PHP (php.ini)

Add these settings to your php.ini — required for PHP 8.4 compatibility:

zend.max_allowed_stack_size=512K
zend.reserved_stack_size=64K

Without these, PHP 8.4's stack overflow detection causes crashes on deeply nested osTicket ORM calls.

4. Database Setup

Create the database and import the base schema:

CREATE DATABASE managerhinogroup CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Import the osTicket base schema, then apply all custom migrations:

# Apply each migration in deploy/ directory
mysql -u root -p managerhinogroup < deploy/deploy-production-migration.sql
mysql -u root -p managerhinogroup < deploy/deploy-ai-history-table.sql
mysql -u root -p managerhinogroup < deploy/deploy-over-budget-lock.sql
mysql -u root -p managerhinogroup < deploy/deploy-escalation-tracking.sql
mysql -u root -p managerhinogroup < deploy/deploy-sms-tracking.sql
mysql -u root -p managerhinogroup < deploy/deploy-documentation-required.sql
mysql -u root -p managerhinogroup < deploy/deploy-client-closed-docs-tracking.sql
mysql -u root -p managerhinogroup < deploy/deploy-browser-notifications.sql
mysql -u root -p managerhinogroup < deploy/deploy-notification-subscriptions.sql
mysql -u root -p managerhinogroup < deploy/deploy-ai-assistant.sql
mysql -u root -p managerhinogroup < deploy/deploy-harvest-time-entries.sql

5. Configure osTicket

Copy and edit the configuration file:

cp include/ost-sampleconfig.php include/ost-config.php

Edit include/ost-config.php with your local settings:

define('DBTYPE', 'mysql');
define('DBHOST', 'localhost');
define('DBNAME', 'managerhinogroup');
define('DBUSER', 'root');
define('DBPASS', 'your_password');
define('TABLE_PREFIX', 'ost_');

// Algolia (search)
define('ALGOLIA_APP_ID', 'your_app_id');
define('ALGOLIA_ADMIN_KEY', 'your_admin_key');
define('ALGOLIA_SEARCH_KEY', 'your_search_key');
define('ALGOLIA_INDEX', 'rhinotickets_index_dev');

// Project Manager staff IDs
define('PMS_LIST', serialize([19, 22, 1, 4]));
define('PMS_REAL_LIST', serialize([19, 22, 4]));

6. Install Frontend Dependencies

cd custom
npm install

7. Build Frontend Assets

# Development build with watch mode
npm run dev

# Production build
npm run build

# SCSS compilation (Gulp)
npx gulp sass
npx gulp watch

8. Configure Web Server

Laravel Herd (recommended): Link the project directory:

herd link ticket-manager

Access at http://ticket-manager.test

Apache: Point a vhost to the project root with .htaccess support enabled.


Running Cron Jobs Locally

Gemini AI Queue

# PowerShell helper script
.\run-cron-dev.ps1

# Or directly
php cron-gemini.php

Embeddings Generation

php cron-embeddings.php

All Crons (via API)

php api/cron.php

Code Quality Tools

PHPCompatibility Check

Verify PHP 8.4 compatibility:

php vendor\bin\phpcs --report=summary --warning-severity=0 .

Rector (Code Modernization)

# Dry run — shows what would change
php vendor\bin\rector --dry-run --no-progress-bar

# Apply changes
php vendor\bin\rector --no-progress-bar

# Run directory-by-directory if full scan fails (Windows Fiber stack issue)
php vendor\bin\rector --dry-run include/
php vendor\bin\rector --dry-run scp/

PHPStan (Static Analysis)

php vendor\bin\phpstan analyse

Debugging

API Logging

All Gemini API calls are logged to var/logs/api/gemini/:

# View today's log
Get-Content var\logs\api\gemini\gemini-2026-05-04.log -Tail 50

# Search for a specific ticket
Select-String -Path var\logs\api\gemini\*.log -Pattern "ticket_id.*8826"

Plugin Debug Output

Set $debug_ip in a motherload plugin to your local IP:

protected $debug_ip = ['127.0.0.1', '::1'];

osTicket System Log

Check Admin → Manage → Logs in the staff panel, or query directly:

SELECT * FROM ost_syslog ORDER BY created DESC LIMIT 20;

Environment Variables

The system reads configuration from include/ost-config.php (not .env files). Key values:

ConfigPurpose
DBHOST / DBNAME / DBUSER / DBPASSDatabase connection
ALGOLIA_APP_ID / ALGOLIA_ADMIN_KEY / ALGOLIA_SEARCH_KEYAlgolia search
ALGOLIA_INDEXSearch index name
PMS_LISTSerialized array of PM staff IDs
PMS_REAL_LISTSerialized array of actual PM staff IDs
GLOBAL_PM_MAPPINGStaff ID → PM mapping array

External Service Credentials

These are configured via the osTicket admin panel (stored in ost_config table):

  • Gemini API Key — Admin → Settings → AI Assistant
  • Pinecone API Key — Admin → Settings → AI Assistant
  • Twilio SID/Token — Admin → Settings → Twilio SMS
  • Harvest API Token — Configured in custom class
  • Asana API Keyinclude/ost-config.php
  • Microsoft 365 OAuth — Admin → Emails → (account) → OAuth tab

Testing

Test/Diagnostic Scripts

Test files live in the tests/ directory:

# Run a specific test
php tests/test-gemini-queue.php
php tests/test-notifications.php

Bulk Ticket Generator

For testing with sample data, use the admin tool:

  1. Navigate to Admin → Tools in the staff panel
  2. Use the Bulk Ticket Generator to create test tickets
  3. Configure count, departments, priorities, and sample content

Common Issues

IssueSolution
Stack overflow crash on ticket loadAdd zend.max_allowed_stack_size=512K to php.ini
Gemini cron processes 0 ticketsCheck ost_gemini_queue has rows with processed=0
Algolia search returns no resultsRun php cron-algolia.php to rebuild index
Frontend changes not visibleRun npm run build in custom/ directory
OAuth token expiredRe-authorize via Admin → Emails → (account) → OAuth
safeQuery() returns emptyCheck MySQL connection and query syntax in logs

Git Workflow

# Feature branch
git checkout -b feature/your-feature

# Make changes, commit
git add .
git commit -m "feat: description of change"

# Push and create PR
git push origin feature/your-feature

File Organization Rules

TypeLocation
Test/debug scriptstests/
Database migrationsdeploy/
One-off fixesfixes/
Feature documentationdocs/
Core application filesRoot or include/
Cron scriptsRoot (for easy cron access)