A production-ready REST API for a Ticketing System built with Laravel 12, PostgreSQL, and modern authentication. This system provides comprehensive ticket management with role-based access control, real-time notifications, and export capabilities.
- Authentication: Token-based authentication using Laravel Sanctum
- Role-Based Access Control: Admin, Staff, and User roles with Spatie Laravel Permission
- Ticket Management: Full CRUD operations with status tracking
- Comment System: Add and view comments on tickets
- Admin Dashboard: Statistics and data export functionality
- API Documentation: Interactive Swagger UI documentation
- Email Notifications: Automated notifications for ticket events
- Export Capabilities: CSV and PDF export for reporting
- Queue System: Background job processing for emails
- Testing: Comprehensive feature tests with PHPUnit
- Security: Rate limiting, CORS protection, input sanitization, strong password requirements
- Framework: Laravel 12
- Database: PostgreSQL 15+
- Authentication: Laravel Sanctum
- Authorization: Spatie Laravel Permission
- API Documentation: L5-Swagger (OpenAPI 3.0)
- Export: Laravel Excel (CSV) and DomPDF (PDF)
- Mail: Laravel Mail with queue support
- Testing: PHPUnit with Laravel testing framework
- Rate Limiting: 60 requests/minute for API, 10/minute for login, 30/minute for registration
- CORS Protection: Configurable allowed origins
- Input Sanitization: XSS prevention for user-generated content
- Strong Passwords: Minimum 10 characters with uppercase, numbers, and symbols
- Authorization Checks: Role-based access control on all endpoints
- Token Expiration: 60-minute token validity
- Production-Safe Seeders: Default users only created in development
- PHP 8.3 or higher
- Composer
- PostgreSQL 15 or higher
- Node.js and npm (for API documentation assets)
git clone <repository-url>
cd ticketing-systemcomposer installcp .env.example .envEdit the .env file and configure your database settings:
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=ticketing_system
DB_USERNAME=your_username
DB_PASSWORD=your_password
MAIL_MAILER=log
MAIL_FROM_ADDRESS=your-email@example.com
MAIL_FROM_NAME="Ticketing System"php artisan key:generate# Create PostgreSQL database
createdb ticketing_system
# Run migrations and seeders
php artisan migrate --seedThis will create:
- Admin user:
admin@example.com/admin123 - Staff users:
staff1@example.com,staff2@example.com/staff123 - Regular users:
john@example.com,jane@example.com,bob@example.com/user123 - Sample tickets and comments
php artisan l5-swagger:generatephp artisan servephp artisan queue:workAccess the interactive API documentation at:
http://localhost:8000/api/docs
The API uses token-based authentication with Laravel Sanctum. Include the token in the Authorization header:
Authorization: Bearer YOUR_TOKEN_HERE
curl -X POST http://localhost:8000/api/register \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"email": "john@example.com",
"password": "password123",
"password_confirmation": "password123"
}'curl -X POST http://localhost:8000/api/login \
-H "Content-Type: application/json" \
-d '{
"email": "john@example.com",
"password": "password123"
}'POST /api/register- Register new userPOST /api/login- Login userPOST /api/logout- Logout user
GET /api/tickets- List tickets (filtered by user role)POST /api/tickets- Create new ticketGET /api/tickets/{id}- Get ticket detailsPUT /api/tickets/{id}- Update ticketDELETE /api/tickets/{id}- Delete ticket
POST /api/tickets/{id}/comments- Add comment to ticketGET /api/tickets/{id}/comments- Get ticket comments
GET /api/admin/tickets/stats- Get ticket statisticsGET /api/admin/tickets/export?format=csv&status=open- Export tickets
- Full access to all tickets
- Can assign tickets to staff
- Access to admin endpoints
- Can export data
- Can view all tickets
- Can update ticket status and assignments
- Can add comments to any ticket
- Can only view and manage their own tickets
- Can add comments to their tickets
- Cannot access admin endpoints
Run the test suite:
php artisan testRun tests with coverage:
php artisan test --coverageRun specific test file:
php artisan test tests/Feature/AuthTest.phpphp artisan queue:workphp artisan queue:failedphp artisan queue:retry all- Ensure PostgreSQL is running
- Verify database credentials in
.env - Check if the database exists:
psql -l - Run migrations:
php artisan migrate
- Ensure queue worker is running:
php artisan queue:work - Check queue configuration:
QUEUE_CONNECTION=database - Verify failed jobs table exists:
php artisan queue:failed-table
- Check mail configuration in
.env - For development, use:
MAIL_MAILER=log - For production, configure SMTP settings
- Ensure queue worker is running for email processing
- Install npm dependencies:
npm install - Generate documentation:
php artisan l5-swagger:generate - Check if assets are published:
php artisan vendor:publish --provider="L5Swagger\L5SwaggerServiceProvider"
- Clear application cache:
php artisan cache:clear - Clear config cache:
php artisan config:clear - Clear route cache:
php artisan route:clear - Re-run migrations if needed:
php artisan migrate:fresh --seed
- Create migration:
php artisan make:migration add_field_to_table - Create model:
php artisan make:model NewModel - Create controller:
php artisan make:controller Api/NewController - Add routes in
routes/api.php - Update API documentation annotations
- Write tests in
tests/Feature/
This project follows Laravel's coding standards. Run the following to check and fix code style:
php artisan pint-
Environment Configuration
APP_ENV=production APP_DEBUG=false APP_KEY=<generate-with-php-artisan-key-generate>
-
Database Configuration
- Use strong database credentials
- Enable SSL for database connections
- Run migrations:
php artisan migrate --force - Do NOT run seeders in production
-
Security Settings
BCRYPT_ROUNDS=14 SESSION_SECURE_COOKIE=true SESSION_HTTP_ONLY=true SESSION_SAME_SITE=strict SANCTUM_EXPIRES_AT=60
-
Cache Optimization
php artisan config:cache php artisan route:cache php artisan view:cache php artisan event:cache
-
Queue Configuration
- Set
QUEUE_CONNECTION=databaseorredis - Run queue worker:
php artisan queue:work --tries=3 --timeout=60 - Use supervisor to manage queue workers
- Set
-
Web Server Configuration
- Configure Nginx/Apache for Laravel
- Enable SSL/TLS certificates
- Set up proper headers (HSTS, CSP, etc.)
- Configure rate limiting at server level
-
Monitoring & Logging
- Set
LOG_CHANNEL=errorlogor configure external logging - Set up application monitoring (Sentry, Bugsnag, etc.)
- Monitor queue failed jobs
- Set
# 1. Install dependencies
composer install --optimize-autoloader --no-dev
# 2. Copy and configure environment
cp .env.example .env
# Edit .env with production values
# 3. Generate app key
php artisan key:generate
# 4. Run migrations
php artisan migrate --force
# 5. Optimize application
php artisan config:cache
php artisan route:cache
php artisan view:cache
# 6. Generate API documentation
php artisan l5-swagger:generate
# 7. Set proper file permissions
chown -R www-data:www-data storage bootstrap/cache
chmod -R 775 storage bootstrap/cacheCreate a docker-compose.yml file for containerized deployment:
version: '3.8'
services:
app:
image: php:8.3-fpm
volumes:
- ./:/var/www/html
environment:
- APP_ENV=production
- APP_DEBUG=false
depends_on:
- db
- redis
webserver:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www/html
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
db:
image: postgres:15
environment:
POSTGRES_DB=ticketing_system
POSTGRES_USER=postgres
POSTGRES_PASSWORD=<strong-password>
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:alpine
queue:
image: php:8.3-cli
command: php artisan queue:work --tries=3
volumes:
- ./:/var/www/html
depends_on:
- db
- redis
volumes:
postgres_data:- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
This project is licensed under the MIT License.
For support and questions:
- Create an issue in the repository
- Check the troubleshooting section above
- Review the API documentation at
/api/docs
Security Improvements:
- Added API rate limiting (60 req/min general, 10 req/min login, 30 req/min registration)
- Implemented CORS configuration for cross-origin requests
- Added input sanitization for comments (XSS prevention)
- Strengthened password requirements (min 10 chars, uppercase, numbers, symbols)
- Fixed authorization checks in TicketController and CommentController
- Reduced token expiration from 24 hours to 60 minutes
- Added production-safe seeders (default users only in development)
Code Quality:
- Added comprehensive error handling with try-catch blocks in all controllers
- Improved validation rules (description min/max length, category length)
- Optimized admin stats query (single query instead of 5 separate queries)
- Added null-safe access in CSV export
- Removed empty boot() methods from models
- Cleaned up duplicate casts in User model
- Hidden role field from API responses
Database:
- Added performance indexes on frequently queried columns
- Added composite indexes for common query patterns
- Improved migration for production safety
Documentation:
- Updated README with production deployment checklist
- Added Docker deployment configuration
- Updated .env.example with new configuration options
- Initial release with full ticketing system functionality
- Laravel 12 compatibility
- PostgreSQL support
- Role-based access control
- API documentation with Swagger
- Email notifications with queue processing
- Export functionality (CSV/PDF)
- Comprehensive test suite