A RESTful API for managing catering facilities, locations, tags, and employees with JWT authentication and automated email notifications.
- Docker & Docker Compose OR
- PHP 8.3+, MySQL 8.0+, Composer
- Resend API key (free tier: 3,000 emails/month)
Using Docker (Recommended):
# Clone and navigate to project
cd Catering-API
# Copy environment file
cp .env.example .env
# Start containers
docker-compose up -d
# Setup database with sample data
docker exec catering_api_app php sql/database_manager.php setup
# Verify installation
curl http://localhost:8080/healthUsing Local Development (XAMPP/MAMP):
# Install dependencies
composer install
# Copy and configure .env
cp .env.example .env
# Setup database
php sql/database_manager.php setup
# Verify installation
curl http://localhost/Catering-API/public/healthπ Detailed Installation Guide: docs/PROJECT-INSTALLATION.md
| Document | Description |
|---|---|
| API Documentation | Complete API endpoint reference |
| Installation Guide | Detailed setup instructions |
| Testing Guide | How to run tests |
| Unit Test Strategy | Testing best practices |
| Refactoring Log | Code improvements history |
| Project Structure | Codebase organization |
| Database Management | Database operations |
The API uses JWT (JSON Web Token) authentication.
# Generate JWT secret: php -r "echo base64_encode(random_bytes(32));"
JWT_SECRET_KEY=your_secure_jwt_secret
# Hash password: php -r "echo password_hash('yourpass', PASSWORD_BCRYPT);"
LOGIN_USERNAME=admin
LOGIN_PASSWORD=$2y$10$hashed_password_here
# Email Configuration (get free API key from resend.com)
RESEND_API_KEY=re_YOUR_API_KEY_HERE
MAIL_FROM_ADDRESS=[email protected]
MAIL_FROM_NAME="Your Company Name"curl -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "yourpass"}'Response:
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGc..."
}curl http://localhost:8080/facilities \
-H "Authorization: Bearer YOUR_JWT_TOKEN"- Docker:
http://localhost:8080 - Local:
http://localhost/Catering-API/public
GET /health- API health status (no auth required)
POST /auth/login- Get JWT token
GET /facilities- List all facilities (pagination supported)GET /facilities/{id}- Get facility by IDGET /facilities/search- Search facilities with filtersPOST /facilities- Create new facilityPUT /facilities/{id}- Update facilityDELETE /facilities/{id}- Delete facility
GET /locations- List all locationsGET /locations/{id}- Get location by IDPOST /locations- Create new locationPUT /locations/{id}- Update locationDELETE /locations/{id}- Delete location
GET /tags- List all tagsGET /tags/{id}- Get tag by IDPOST /tags- Create new tagPUT /tags/{id}- Update tagDELETE /tags/{id}- Delete tag
GET /employees- List all employeesGET /employees/{id}- Get employee by IDGET /employees/facility/{facility_id}- Get employees by facilityPOST /employees- Create new employee (sends welcome email automatically)PUT /employees/{id}- Update employeeDELETE /employees/{id}- Delete employee
curl -X POST http://localhost:8080/facilities \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"name": "Grand Conference Hall",
"location_id": 1,
"tagIds": [1, 2],
"tagNames": ["Wedding", "Corporate"]
}'# Search with filters and AND operator
curl "http://localhost:8080/facilities/search?query=Conference&filter=city,tag&operator=AND" \
-H "Authorization: Bearer YOUR_TOKEN"curl "http://localhost:8080/facilities?page=1&per_page=10" \
-H "Authorization: Bearer YOUR_TOKEN"curl -X POST http://localhost:8080/employees \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"name": "John Doe",
"email": "[email protected]",
"phone": "1234567890",
"address": "123 Main St",
"facilityIds": [1, 2]
}'Automated email notifications via Resend API (3,000 emails/month free).
Features:
- Welcome email on employee creation
- HTML + plain text templates
- Custom domain (
[email protected]) - Non-blocking (employee creation succeeds even if email fails)
Quick Setup:
# .env
RESEND_API_KEY=re_YOUR_KEY_HERE # Get from resend.com
MAIL_FROM_ADDRESS=[email protected]
MAIL_FROM_NAME="Catering Management"Monitor: resend.com/emails | docker logs catering_api_app | grep -i email
# Docker
docker-compose exec app vendor/bin/phpunit
docker-compose exec app vendor/bin/phpunit --testdox
# Local
vendor/bin/phpunit
composer test-unit
# With coverage
composer test-coverageCurrent Status: 166/166 tests passing (100%) β
π Complete Testing Guide: docs/TEST_COMMANDS.md
# Docker
docker exec catering_api_app php sql/database_manager.php [command]
# Local
php sql/database_manager.php [command]Available Commands:
setup- Fresh installation with sample datastatus- Check database statereset- Clear and reload data (dev only)clear-data- Remove data, keep structuredrop-tables- Remove all tables (dangerous!)
π Details: sql/README.md
After running setup, you get:
- β 25 locations (Dutch cities)
- β 25 catering facilities
- β 7 category tags
- β Realistic relationships
| Service | Container | Port | Purpose |
|---|---|---|---|
| Nginx | catering_api_nginx |
80, 443 | Web server |
| PHP-FPM | catering_api_app |
8080 | Application |
| MySQL | catering_api_db |
3307 | Database |
| phpMyAdmin | catering_phpmyadmin |
8081 | DB management |
Useful Commands:
# View logs
docker-compose logs -f app
# Access shell
docker-compose exec app bash
# Stop containers
docker-compose down
# Restart
docker-compose restartCatering-API/
βββ App/
β βββ Controllers/ # HTTP request handlers
β βββ Services/ # Business logic
β βββ Repositories/ # Data access layer
β βββ Models/ # Domain models
β βββ Domain/
β β βββ Exceptions/ # Custom exceptions
β βββ Helpers/ # Utility classes
β βββ Middleware/ # JWT authentication
β βββ Plugins/ # HTTP, DI, Database
βββ docs/ # Documentation
βββ sql/ # Database scripts
βββ tests/ # PHPUnit tests
βββ public/ # Entry point
π Detailed Structure: docs/PROJECT_STRUCTURE.md
- β RESTful API design
- β JWT authentication
- β Automated email notifications (Resend API)
- β Custom domain email ([email protected])
- β Domain-driven exception handling
- β Comprehensive input validation
- β Security-focused logging (sensitive data sanitization)
- β Pagination support
- β Advanced search and filtering
- β Docker containerization
- β 100% unit test coverage (166 tests)
- β PSR-4 autoloading
- JWT token-based authentication
- Password hashing (bcrypt)
- Input sanitization (XSS protection)
- SQL injection prevention (prepared statements)
- Sensitive data sanitization in logs
- HTTPS support (production ready)
The API uses standard HTTP status codes:
| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created |
| 400 | Bad Request (validation errors) |
| 401 | Unauthorized (invalid/missing token) |
| 404 | Not Found |
| 409 | Conflict (resource in use) |
| 422 | Unprocessable Entity (business rule violation) |
| 500 | Internal Server Error |
Example Error Response:
{
"error": "Facility with ID 999 not found"
}- Write tests for new features
- Follow PSR-12 coding standards
- Update documentation
- Run tests before committing
This project is open source and available for educational purposes.
For issues or questions, please refer to the documentation in the docs/ directory.