From 08d6808bc38fa16745f78c5bea9a09969972b831 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Tue, 20 Jan 2026 17:25:54 -0500 Subject: [PATCH] Update README.md and add debug error handlers - Completely rewrote README with all new features and admin routes - Cleaned up remaining migration files - Added detailed PHP error/exception handlers to dependencies API to help debug the 500 error Co-Authored-By: Claude Opus 4.5 --- README.md | 297 ++++++++++--------------- api/ticket_dependencies.php | 28 ++- migrations/015_ticket_dependencies.sql | 15 -- migrations/016_ticket_attachments.sql | 18 -- migrations/017_recurring_tickets.sql | 29 --- migrations/018_custom_fields.sql | 39 ---- 6 files changed, 145 insertions(+), 281 deletions(-) delete mode 100644 migrations/015_ticket_dependencies.sql delete mode 100644 migrations/016_ticket_attachments.sql delete mode 100644 migrations/017_recurring_tickets.sql delete mode 100644 migrations/018_custom_fields.sql diff --git a/README.md b/README.md index 1257065..f55c0d4 100644 --- a/README.md +++ b/README.md @@ -2,89 +2,127 @@ A feature-rich PHP-based ticketing system designed for tracking and managing data center infrastructure issues with enterprise-grade workflow management. -## ✨ Core Features +## Core Features -### 📊 Dashboard & Ticket Management +### Dashboard & Ticket Management - **Smart Dashboard**: Sortable columns, advanced filtering by status/priority/category/type - **Full-Text Search**: Search across tickets, descriptions, and metadata -- **Ticket Assignment**: Assign tickets to specific users with "Assigned To" column +- **Ticket Assignment**: Assign tickets to specific users with quick-assign from dashboard - **Priority Tracking**: P1 (Critical) to P5 (Minimal Impact) with color-coded indicators - **Custom Categories**: Hardware, Software, Network, Security, General - **Ticket Types**: Maintenance, Install, Task, Upgrade, Issue, Problem +- **Export**: Export selected tickets to CSV or JSON format -### 🔄 Workflow Management +### Workflow Management - **Status Transitions**: Enforced workflow rules (Open → Pending → In Progress → Closed) +- **Workflow Designer**: Visual admin UI at `/admin/workflow` to configure transitions - **Workflow Validation**: Server-side validation prevents invalid status changes - **Admin Controls**: Certain transitions can require admin privileges - **Comment Requirements**: Optional comment requirements for specific transitions + +### Collaboration Features +- **Markdown Comments**: Full Markdown support with live preview and toolbar +- **@Mentions**: Tag users in comments with autocomplete +- **File Attachments**: Upload files to tickets with drag-and-drop support +- **Ticket Dependencies**: Link tickets as blocks/blocked-by/relates-to/duplicates - **Activity Timeline**: Complete audit trail of all ticket changes -### 💬 Collaboration Features -- **Markdown Comments**: Full Markdown support with live preview -- **User Tracking**: Tracks who created, updated, and assigned tickets -- **Activity Timeline**: Shows all ticket events (creates, updates, assignments, comments) -- **Real-time Updates**: AJAX-powered updates without page refreshes - -### 🎫 Ticket Templates +### Ticket Templates +- **Template Management**: Admin UI at `/admin/templates` to create/edit templates - **Quick Creation**: Pre-configured templates for common issues -- **Default Templates**: Hardware Failure, Software Installation, Network Issue, Maintenance - **Auto-fill**: Templates populate title, description, category, type, and priority -### 👥 User Management & Authentication +### Recurring Tickets +- **Scheduled Tickets**: Automatically create tickets on a schedule +- **Admin UI**: Manage at `/admin/recurring-tickets` +- **Flexible Scheduling**: Daily, weekly, or monthly recurrence +- **Cron Integration**: Run `cron/create_recurring_tickets.php` to process + +### Custom Fields +- **Per-Category Fields**: Define custom fields for specific ticket categories +- **Admin UI**: Manage at `/admin/custom-fields` +- **Field Types**: Text, textarea, select, checkbox, date, number +- **Required Fields**: Mark fields as required for validation + +### User Management & Authentication - **SSO Integration**: Authelia authentication with LLDAP backend - **Role-Based Access**: Admin and standard user roles -- **User Display Names**: Support for display names and usernames -- **Session Management**: Secure PHP session handling +- **User Activity**: View per-user stats at `/admin/user-activity` +- **Session Management**: Secure PHP session handling with timeout -### ⚡ Bulk Actions (Admin Only) +### Bulk Actions (Admin Only) - **Bulk Close**: Close multiple tickets at once - **Bulk Assign**: Assign multiple tickets to a user - **Bulk Priority**: Change priority for multiple tickets -- **Operation Tracking**: All bulk operations logged in audit trail +- **Bulk Status**: Change status for multiple tickets -### 🔔 Notifications +### Admin Pages +| Route | Description | +|-------|-------------| +| `/admin/recurring-tickets` | Manage recurring ticket schedules | +| `/admin/custom-fields` | Define custom fields per category | +| `/admin/workflow` | Visual workflow transition designer | +| `/admin/templates` | Create and edit ticket templates | +| `/admin/audit-log` | Browse all audit log entries | +| `/admin/user-activity` | View per-user activity statistics | + +### Notifications - **Discord Integration**: Webhook notifications for ticket creation and updates - **Rich Embeds**: Color-coded priority indicators and ticket links -- **Change Tracking**: Detailed notification of what changed -### 🎨 User Interface -- **Dark Mode**: Full dark mode support with proper contrast -- **Responsive Design**: Works on desktop and mobile devices -- **Clean Layout**: Modern, intuitive interface -- **Hamburger Menu**: Quick access to ticket actions (priority, category, type) +### Security Features +- **CSRF Protection**: Token-based protection on all forms +- **Rate Limiting**: API rate limiting to prevent abuse +- **Security Headers**: CSP, X-Frame-Options, X-Content-Type-Options +- **SQL Injection Prevention**: All queries use prepared statements +- **XSS Protection**: All output properly escaped +- **Audit Logging**: Complete audit trail of all actions -## 🏗️ Technical Architecture +## Technical Architecture ### Backend - **Language**: PHP 7.4+ - **Database**: MariaDB/MySQL - **Architecture**: MVC pattern with models, views, controllers -- **ORM**: Custom database abstraction layer ### Frontend - **HTML5/CSS3**: Semantic markup with modern CSS - **JavaScript**: Vanilla JS with Fetch API for AJAX -- **Markdown**: marked.js for Markdown rendering -- **Icons**: Unicode emoji icons +- **Markdown**: Custom markdown parser with toolbar -### Database Schema -- **tickets**: Core ticket data with user tracking -- **comments**: Markdown-supported comments -- **users**: User accounts synced from LLDAP -- **audit_log**: Complete audit trail with JSON details -- **status_transitions**: Workflow configuration -- **ticket_templates**: Reusable ticket templates -- **bulk_operations**: Tracking for bulk admin operations +### Database Tables +| Table | Purpose | +|-------|---------| +| `tickets` | Core ticket data | +| `ticket_comments` | Markdown-supported comments | +| `ticket_attachments` | File attachment metadata | +| `ticket_dependencies` | Ticket relationships | +| `users` | User accounts synced from LLDAP | +| `user_preferences` | User settings and preferences | +| `audit_log` | Complete audit trail | +| `status_transitions` | Workflow configuration | +| `ticket_templates` | Reusable ticket templates | +| `recurring_tickets` | Scheduled ticket definitions | +| `custom_field_definitions` | Custom field schemas | +| `custom_field_values` | Custom field data per ticket | +| `saved_filters` | User-saved dashboard filters | ### API Endpoints -- `/api/update_ticket.php` - Update ticket with workflow validation -- `/api/assign_ticket.php` - Assign ticket to user -- `/api/add_comment.php` - Add comment to ticket -- `/api/get_template.php` - Fetch ticket template -- `/api/get_users.php` - Get user list for assignments -- `/api/bulk_operation.php` - Perform bulk operations (admin only) +| Endpoint | Method | Description | +|----------|--------|-------------| +| `/api/update_ticket.php` | POST | Update ticket with workflow validation | +| `/api/assign_ticket.php` | POST | Assign ticket to user | +| `/api/add_comment.php` | POST | Add comment to ticket | +| `/api/get_template.php` | GET | Fetch ticket template | +| `/api/get_users.php` | GET | Get user list for assignments | +| `/api/bulk_operation.php` | POST | Perform bulk operations | +| `/api/ticket_dependencies.php` | GET/POST/DELETE | Manage ticket dependencies | +| `/api/upload_attachment.php` | GET/POST | List or upload attachments | +| `/api/delete_attachment.php` | POST/DELETE | Delete attachment | +| `/api/export_tickets.php` | GET | Export tickets to CSV/JSON | +| `/api/check_duplicates.php` | GET | Check for duplicate tickets | -## 🚀 Setup & Configuration +## Setup & Configuration ### 1. Environment Configuration @@ -99,47 +137,32 @@ DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/... ### 2. Database Setup -Run migrations in order: +The database schema is managed through migrations. For a fresh install, run all migrations in order using the migration runner. + +### 3. Cron Jobs + +Add to crontab for recurring tickets: ```bash -# Navigate to project directory -cd /root/code/tinker_tickets - -# Run each migration -mysql -h 10.10.10.50 -u tinkertickets -p ticketing_system < migrations/001_initial_schema.sql -mysql -h 10.10.10.50 -u tinkertickets -p ticketing_system < migrations/007_add_ticket_assignment.sql -mysql -h 10.10.10.50 -u tinkertickets -p ticketing_system < migrations/008_add_status_workflows.sql -mysql -h 10.10.10.50 -u tinkertickets -p ticketing_system < migrations/009_add_ticket_templates.sql -mysql -h 10.10.10.50 -u tinkertickets -p ticketing_system < migrations/010_add_bulk_operations.sql -mysql -h 10.10.10.50 -u tinkertickets -p ticketing_system < migrations/011_remove_view_tracking.sql +# Run every hour to create scheduled recurring tickets +0 * * * * php /var/www/html/tinkertickets/cron/create_recurring_tickets.php ``` -### 3. Web Server Configuration - -**Apache Configuration** (recommended): -```apache - - ServerName t.lotusguild.org - DocumentRoot /root/code/tinker_tickets - - - Options -Indexes +FollowSymLinks - AllowOverride All - Require all granted - - # Enable mod_rewrite for clean URLs - RewriteEngine On - RewriteBase / - - # Route ticket URLs - RewriteRule ^ticket/([0-9]+)$ ticket.php?id=$1 [L,QSA] - - # Route ticket create - RewriteRule ^ticket/create$ ticket.php?action=create [L,QSA] - - +Optional cleanup job: +```bash +# Run weekly to clean up orphaned upload files +0 2 * * 0 php /var/www/html/tinkertickets/scripts/cleanup_orphan_uploads.php ``` -### 4. Authelia Integration +### 4. File Uploads + +Ensure the `uploads/` directory exists and is writable: +```bash +mkdir -p /var/www/html/tinkertickets/uploads +chown www-data:www-data /var/www/html/tinkertickets/uploads +chmod 755 /var/www/html/tinkertickets/uploads +``` + +### 5. Authelia Integration Tinker Tickets uses Authelia for SSO. User information is passed via headers: - `Remote-User`: Username @@ -149,123 +172,39 @@ Tinker Tickets uses Authelia for SSO. User information is passed via headers: Admin users must be in the `admins` group in LLDAP. -## 📁 Project Structure +## Project Structure ``` tinker_tickets/ ├── api/ # API endpoints -│ ├── add_comment.php -│ ├── assign_ticket.php -│ ├── bulk_operation.php -│ ├── get_template.php -│ ├── get_users.php -│ └── update_ticket.php -├── assets/ # Static assets -│ ├── css/ -│ │ ├── dashboard.css -│ │ └── ticket.css -│ └── js/ -│ ├── dashboard.js -│ └── ticket.js +├── assets/ # Static assets (CSS, JS) ├── config/ # Configuration -│ └── config.php ├── controllers/ # MVC Controllers -│ ├── DashboardController.php -│ └── TicketController.php +├── cron/ # Scheduled task scripts +├── helpers/ # Utility classes +├── middleware/ # Request middleware ├── models/ # Data models -│ ├── AuditLogModel.php -│ ├── BulkOperationsModel.php -│ ├── CommentModel.php -│ ├── TemplateModel.php -│ ├── TicketModel.php -│ ├── UserModel.php -│ └── WorkflowModel.php +├── scripts/ # Maintenance scripts +├── uploads/ # File upload storage ├── views/ # View templates -│ ├── CreateTicketView.php -│ ├── DashboardView.php -│ └── TicketView.php +│ └── admin/ # Admin panel views ├── migrations/ # Database migrations -│ ├── 001_initial_schema.sql -│ ├── 007_add_ticket_assignment.sql -│ ├── 008_add_status_workflows.sql -│ ├── 009_add_ticket_templates.sql -│ ├── 010_add_bulk_operations.sql -│ └── 011_remove_view_tracking.sql -├── index.php # Dashboard entry point -├── ticket.php # Ticket view/create entry point -└── .env # Environment configuration +├── index.php # Main router +└── .env # Environment configuration ``` -## 🔐 Security Features - -- **SQL Injection Prevention**: All queries use prepared statements -- **XSS Protection**: All output is properly escaped with `htmlspecialchars()` -- **Session Security**: Secure PHP session handling -- **Admin Validation**: Server-side admin checks for privileged operations -- **Workflow Enforcement**: Status transitions validated server-side -- **Audit Logging**: Complete audit trail of all actions - -## 🎯 Workflow States +## Workflow States ### Default Workflow ``` Open → Pending → In Progress → Closed + ↑ ↑ + └───────────┘ ``` -### Workflow Configuration -Status transitions are defined in the `status_transitions` table: -- `from_status`: Current status -- `to_status`: Target status -- `requires_comment`: Whether transition requires a comment -- `requires_admin`: Whether transition requires admin privileges -- `is_active`: Whether transition is enabled +All states can transition to Closed (with comment). +Closed tickets can be reopened to Open or In Progress. -## 📝 Usage Examples - -### Creating a Ticket -1. Click "New Ticket" button -2. Select template (optional) - auto-fills common fields -3. Fill in title, description, category, type, priority -4. Click "Create Ticket" - -### Updating Ticket Status -1. Open ticket -2. Click status dropdown (next to priority badge) -3. Select allowed status (workflow-validated) -4. Confirm if comment is required - -### Assigning Tickets -1. Open ticket or use dashboard bulk actions -2. Select user from "Assigned to" dropdown -3. Changes are auto-saved - -### Bulk Operations (Admin Only) -1. Check multiple tickets on dashboard -2. Select bulk action (Close, Assign, Change Priority) -3. Complete operation -4. All actions are logged in audit trail - -## 🔮 Roadmap - -- ✅ Activity Timeline -- ✅ Ticket Assignment -- ✅ Status Transitions with Workflows -- ✅ Ticket Templates -- ✅ Bulk Actions (Admin Only) -- 🎨 **ANSI Art Redesign** (Next Priority) -- 🔗 Ticket Dependencies (blocks/blocked by) -- 📊 Custom Dashboard Widgets -- 🔧 Custom Fields per Category - -## 🤝 Contributing - -This is an internal tool for LotusGuild infrastructure management. For feature requests or bug reports, contact the infrastructure team. - -## 📄 License +## License Internal use only - LotusGuild Infrastructure - -## 🙏 Credits - -Built with ❤️ for the LotusGuild community -Powered by PHP, MariaDB, and lots of coffee ☕ diff --git a/api/ticket_dependencies.php b/api/ticket_dependencies.php index 64b88b2..89eeb71 100644 --- a/api/ticket_dependencies.php +++ b/api/ticket_dependencies.php @@ -7,10 +7,36 @@ * DELETE: Remove a dependency */ -// Capture errors for debugging +// Capture ALL errors for debugging ini_set('display_errors', 0); error_reporting(E_ALL); +// Custom error handler to return JSON errors +set_error_handler(function($errno, $errstr, $errfile, $errline) { + http_response_code(500); + header('Content-Type: application/json'); + echo json_encode([ + 'success' => false, + 'error' => "PHP Error: $errstr", + 'file' => basename($errfile), + 'line' => $errline + ]); + exit; +}); + +// Custom exception handler +set_exception_handler(function($e) { + http_response_code(500); + header('Content-Type: application/json'); + echo json_encode([ + 'success' => false, + 'error' => 'Exception: ' . $e->getMessage(), + 'file' => basename($e->getFile()), + 'line' => $e->getLine() + ]); + exit; +}); + // Apply rate limiting (also starts session) require_once dirname(__DIR__) . '/middleware/RateLimitMiddleware.php'; RateLimitMiddleware::apply('api'); diff --git a/migrations/015_ticket_dependencies.sql b/migrations/015_ticket_dependencies.sql deleted file mode 100644 index e7341b5..0000000 --- a/migrations/015_ticket_dependencies.sql +++ /dev/null @@ -1,15 +0,0 @@ --- Migration: Create ticket dependencies table --- Version: 015 - -CREATE TABLE IF NOT EXISTS ticket_dependencies ( - dependency_id INT AUTO_INCREMENT PRIMARY KEY, - ticket_id VARCHAR(9) NOT NULL, - depends_on_id VARCHAR(9) NOT NULL, - dependency_type ENUM('blocks', 'blocked_by', 'relates_to', 'duplicates') DEFAULT 'blocks', - created_by INT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - UNIQUE KEY unique_dependency (ticket_id, depends_on_id, dependency_type), - INDEX idx_ticket_id (ticket_id), - INDEX idx_depends_on_id (depends_on_id), - FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/migrations/016_ticket_attachments.sql b/migrations/016_ticket_attachments.sql deleted file mode 100644 index 1ae435f..0000000 --- a/migrations/016_ticket_attachments.sql +++ /dev/null @@ -1,18 +0,0 @@ --- Migration: Create ticket attachments table --- Date: 2026-01-19 --- Description: Adds support for file attachments on tickets - -CREATE TABLE IF NOT EXISTS ticket_attachments ( - attachment_id INT AUTO_INCREMENT PRIMARY KEY, - ticket_id VARCHAR(9) NOT NULL, - filename VARCHAR(255) NOT NULL, - original_filename VARCHAR(255) NOT NULL, - file_size INT NOT NULL, - mime_type VARCHAR(100) NOT NULL, - uploaded_by INT NULL, - uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (ticket_id) REFERENCES tickets(ticket_id) ON DELETE CASCADE, - FOREIGN KEY (uploaded_by) REFERENCES users(user_id) ON DELETE SET NULL, - INDEX idx_attachments_ticket (ticket_id), - INDEX idx_attachments_uploaded_by (uploaded_by) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/migrations/017_recurring_tickets.sql b/migrations/017_recurring_tickets.sql deleted file mode 100644 index 982488d..0000000 --- a/migrations/017_recurring_tickets.sql +++ /dev/null @@ -1,29 +0,0 @@ --- Migration: Create recurring tickets table --- Description: Enables automatic ticket creation on a schedule - -CREATE TABLE IF NOT EXISTS recurring_tickets ( - recurring_id INT AUTO_INCREMENT PRIMARY KEY, - title_template VARCHAR(255) NOT NULL, - description_template TEXT, - category VARCHAR(50) DEFAULT 'General', - type VARCHAR(50) DEFAULT 'Task', - priority INT DEFAULT 4, - assigned_to INT NULL, - schedule_type ENUM('daily', 'weekly', 'monthly') NOT NULL, - schedule_day INT NULL COMMENT 'Day of week (1-7) for weekly, day of month (1-31) for monthly', - schedule_time TIME DEFAULT '09:00:00', - next_run_at TIMESTAMP NOT NULL, - last_run_at TIMESTAMP NULL, - is_active BOOLEAN DEFAULT TRUE, - created_by INT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - FOREIGN KEY (assigned_to) REFERENCES users(user_id) ON DELETE SET NULL, - FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL, - INDEX idx_recurring_next_run (next_run_at, is_active), - INDEX idx_recurring_active (is_active) -); - --- Sample recurring ticket for testing (commented out) --- INSERT INTO recurring_tickets (title_template, description_template, category, type, schedule_type, schedule_day, next_run_at) --- VALUES ('Weekly Server Maintenance Check', 'Perform weekly server health check and maintenance tasks.', 'Maintenance', 'Task', 'weekly', 1, NOW()); diff --git a/migrations/018_custom_fields.sql b/migrations/018_custom_fields.sql deleted file mode 100644 index 0be4862..0000000 --- a/migrations/018_custom_fields.sql +++ /dev/null @@ -1,39 +0,0 @@ --- Migration: Create custom fields tables --- Description: Enables custom field definitions per category and stores field values - --- Custom field definitions -CREATE TABLE IF NOT EXISTS custom_field_definitions ( - field_id INT AUTO_INCREMENT PRIMARY KEY, - field_name VARCHAR(100) NOT NULL, - field_label VARCHAR(255) NOT NULL, - field_type ENUM('text', 'textarea', 'select', 'checkbox', 'date', 'number') NOT NULL, - field_options JSON NULL COMMENT 'Options for select fields: {"options": ["Option 1", "Option 2"]}', - category VARCHAR(50) NULL COMMENT 'NULL = applies to all categories', - is_required BOOLEAN DEFAULT FALSE, - display_order INT DEFAULT 0, - is_active BOOLEAN DEFAULT TRUE, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX idx_custom_fields_category (category, is_active), - INDEX idx_custom_fields_order (display_order) -); - --- Custom field values for tickets -CREATE TABLE IF NOT EXISTS custom_field_values ( - value_id INT AUTO_INCREMENT PRIMARY KEY, - ticket_id VARCHAR(9) NOT NULL, - field_id INT NOT NULL, - field_value TEXT, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - UNIQUE KEY unique_ticket_field (ticket_id, field_id), - FOREIGN KEY (field_id) REFERENCES custom_field_definitions(field_id) ON DELETE CASCADE, - INDEX idx_custom_values_ticket (ticket_id) -); - --- Sample custom field definitions (commented out) --- INSERT INTO custom_field_definitions (field_name, field_label, field_type, category, is_required) --- VALUES --- ('affected_server', 'Affected Server', 'text', 'Hardware', false), --- ('incident_date', 'Incident Date', 'date', 'Security', true), --- ('software_version', 'Software Version', 'text', 'Software', false);