Assessment Link: Backend Developer Assessment Task
A modern PHP-based real-time sales tracking system with WebSocket support, dynamic pricing based on weather conditions, and live analytics.
- Features
- Architecture
- Requirements
- Installation
- Configuration
- Usage
- API Documentation
- Troubleshooting
- Project Structure
- Real-Time Order Tracking: WebSocket-based live updates for new orders
- Dynamic Analytics Dashboard: Live revenue tracking and product statistics
- Weather-Based Pricing: Automatic price adjustments based on current temperature
- Dual Database Support: Works with both SQLite and MySQL
- Redis Caching: Optional Redis integration for performance optimization
- RESTful API: Clean, well-documented API endpoints
- Migration System: Database version control with automatic migrations
- Docker Support: Containerized deployment option
- Backend: PHP 8.2+ with PDO
- WebSocket: Ratchet (PHP WebSocket library)
- Database: SQLite (default) or MySQL
- Cache: Redis (optional)
- Frontend: Vanilla JavaScript with Tailwind CSS
- External APIs: OpenWeatherMap for weather data
- MVC Architecture: Clean separation of concerns
- Repository Pattern: Data access abstraction
- Service Layer: Business logic encapsulation
- Dependency Injection: Flexible component composition
- Factory Pattern: Order creation and service instantiation
- PHP 7.2 or higher (PHP 8.2+ recommended)
- PDO extension
- Composer
- One of the following databases:
- SQLite 3 (included, no setup needed)
- MySQL 5.7+ / MariaDB 10.2+
- Redis 5.0+ (for caching and real-time features)
- OpenWeatherMap API key (for weather-based recommendations)
# Clone the repository
git clone https://github.com/yahongie2014/PentavalueTask.git
cd PentavalueTask
# Run the installation script
Installation.bat# Clone repository
git clone https://github.com/yahongie2014/PentavalueTask.git
cd PentavalueTask
# Install PHP dependencies
composer install# Copy environment template
cp .env.example .env
# Edit .env file with your configuration
# nano .env # Linux/Mac
# notepad .env # WindowsOption A: SQLite (Default - No Setup Required)
The application will automatically create sales.sqlite in the project root.
Option B: MySQL
-- Create database
CREATE DATABASE sales CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- Create user (optional)
CREATE USER 'sales_user'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON sales.* TO 'sales_user'@'localhost';
FLUSH PRIVILEGES;Update .env:
DB_DRIVER=mysql
DB_HOST=localhost
DB_NAME=sales
DB_USERNAME=sales_user
DB_PASSWORD=your_password
DB_PORT=3306# Run database migrations
php migrate.php
# Seed with demo data
curl http://localhost:8080/seedTerminal 1: WebSocket Server
php server.phpTerminal 2: HTTP Server
php -S 127.0.0.1:8080Windows: Start Both at Once
start-all.bat# Build and start containers
docker-compose up --build
# Access the application
# http://localhost:8080# Database
DB_DRIVER=sqlite # sqlite or mysql
DB_PATH=sales.sqlite # SQLite path
DB_HOST=localhost # MySQL host
DB_NAME=sales # MySQL database
DB_USERNAME=root # MySQL username
DB_PASSWORD= # MySQL password
DB_PORT=3306 # MySQL port
# External APIs
OPENAI_API_KEY=your_key_here # Optional: AI recommendations
WATHER_API_KEY=your_key_here # OpenWeatherMap API key
CITY=Cairo # City for weather data
# WebSocket
WS_HOST=127.0.0.1 # WebSocket bind address
WS_PORT=8000 # WebSocket port
WS_PROTOCOL=ws # ws or wss
# Redis (Optional)
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
# Application
APP_ENV=local # local, production
APP_DEBUG=true # true or false
APP_URL=http://localhost:8080
# Security
CORS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8000
API_RATE_LIMIT=100
# Cache
CACHE_DRIVER=redis # redis or file
CACHE_TTL=55 # Cache lifetime in seconds- Sign up at OpenWeatherMap
- Get your free API key
- Add to
.env:WATHER_API_KEY=your_api_key_here CITY=YourCity
- Open browser:
http://localhost:8080 - Click "Create Random Order" to test real-time updates
- View live analytics and order stream
- Navigate to:
http://localhost:8080/test-api.php - Select endpoint from dropdown
- Fill in required fields
- Submit and view response
# Seed database with demo data
curl http://localhost:8080/seed
# Get all products
curl http://localhost:8080/products
# Create an order
curl -X POST http://localhost:8080/create_order \
-H "Content-Type: application/json" \
-d '{"product_id":1,"quantity":3,"price":10.0}'
# Get analytics
curl http://localhost:8080/analytics
# Get AI recommendations
curl http://localhost:8080/recommendationsGet all available products.
Response:
{
"data": [
{ "id": 1, "name": "Cola", "price": 10.0 },
{ "id": 2, "name": "Water", "price": 5.0 }
],
"count": 2
}Create a new order.
Request:
{
"product_id": 1,
"quantity": 2,
"price": 10.0,
"date": "2025-10-12 14:30:00"
}Response:
{
"data": {
"product_name": "Cola",
"quantity": 2,
"price": 10.0,
"date": "2025-10-12 14:30:00"
},
"status": "order saved"
}Get real-time analytics (cached for 55 seconds).
Response:
{
"total_revenue": 1250.5,
"top_products": [
{ "product_name": "Cola", "total_sold": 45 },
{ "product_name": "Water", "total_sold": 38 }
],
"orders_last_minute": {
"product_name": "Coffee",
"total_sold": 5
},
"revenue_last_minute": 75.0,
"count_orders_last_minute": 3
}Get AI-powered product recommendations based on weather.
Response:
{
"current_temperature": 32.5,
"recommendations": "Temperature: 32.5Β°C. Suggested promotion: cold drinks like Juice, Water, Cola. Pricing strategy: cold drinks prioritized.",
"adjusted_prices": [
{
"product": "Cola",
"original_price": "10 LE",
"adjusted_price": "11 LE",
"change": "10%"
}
],
"suggested_products": ["Cola", "Water", "Juice"]
}Seed database with demo products and orders.
Response:
{
"message": "Database seeded with demo products and orders",
"products_created": 5,
"orders_created": 25
}Download the Postman collection from docs/api.json to test all endpoints.
Problem: "WebSocket connection failed"
Solutions:
- Ensure
server.phpis running:php server.php
- Check if port 8000 is available:
netstat -ano | findstr :8000 # Windows lsof -i :8000 # Linux/Mac
- Verify firewall settings allow port 8000
- Check browser console for detailed error messages
Problem: "Database connection failed"
Solutions:
For SQLite:
- Ensure PHP has write permissions to project directory
- Check if SQLite extension is enabled:
php -m | grep sqlite
For MySQL:
- Verify credentials in
.env - Test connection:
mysql -h localhost -u root -p sales
- Ensure MySQL service is running
- Check
DB_PORTmatches your MySQL configuration
Problem: Migrations fail to run
Solutions:
- Check migration status:
php migrate.php status
- Drop tables and re-run (development only):
DROP TABLE IF EXISTS orders; DROP TABLE IF EXISTS products; DROP TABLE IF EXISTS migrations;
- Run migrations again:
php migrate.php
Problem: Analytics not updating
Solutions:
- Disable Redis caching temporarily (set to file-based):
CACHE_DRIVER=file - Clear Redis cache:
redis-cli FLUSHALL
- Restart Redis service
- Check Redis connection:
redis-cli ping
Problem: Recommendations return 503 error
Solutions:
- Verify API key is valid
- Check API key has not exceeded rate limits
- Test API directly:
curl "https://api.openweathermap.org/data/2.5/weather?q=Cairo&appid=YOUR_KEY&units=metric" - Ensure city name is correct in
.env
Problem: Slow response times
Solutions:
- Enable Redis caching
- Increase
CACHE_TTLin.env - Add database indexes (already included in migrations)
- Use MySQL instead of SQLite for production
- Monitor PHP error logs:
tail -f /var/log/apache2/error.log # Linux
PentavalueTask/
βββ App/
β βββ Controllers/
β β βββ BaseController.php # Base controller with common methods
β β βββ SalesController.php # Main sales endpoint controller
β βββ Repositories/
β β βββ OrderRepository.php # Order data access
β β βββ ProductRepository.php # Product data access
β βββ Services/
β β βββ OrderService.php # Order business logic
β β βββ ProductService.php # Product business logic
β βββ Validators/
β β βββ OrderValidator.php # Input validation
β βββ Helpers/
β β βββ ResponseHelper.php # JSON response helper
β βββ Events/
β βββ getAnalyticsData.php # Analytics worker (optional)
βββ Connectivity/
β βββ DB.php # Database factory
β βββ DBConnectionInterface.php # Connection interface
β βββ MySQLConnection.php # MySQL implementation
β βββ SQLiteConnection.php # SQLite implementation
β βββ Migrator.php # Migration system
βββ MindMap/
β βββ Router.php # Simple routing system
βββ public/
β βββ index.php # Main dashboard
β βββ test-api.php # API testing interface
β βββ .htaccess # Apache rewrite rules
βββ docs/
β βββ api.json # Postman collection
βββ server.php # WebSocket server
βββ index.php # Application entry point
βββ migrate.php # Migration CLI tool
βββ .env # Environment configuration
βββ composer.json # PHP dependencies
βββ docker-compose.yml # Docker configuration
βββ README.md # This file
-
Disable Debug Mode:
APP_DEBUG=false APP_ENV=production
-
Secure Database Credentials:
- Never commit
.envto version control - Use strong passwords
- Restrict database user privileges
- Never commit
-
Enable HTTPS:
- Use WSS (WebSocket Secure) for WebSocket connections
- Configure SSL certificates
- Update
WS_PROTOCOL=wss
-
Rate Limiting:
- Implement the rate limiting system in
BaseController.php - Use Redis for distributed rate limiting
- Implement the rate limiting system in
-
CORS Configuration:
- Restrict
CORS_ALLOWED_ORIGINSto specific domains - Remove wildcard (
*) from production
- Restrict
-
Input Validation:
- All inputs are validated through
OrderValidator - SQL injection protection via PDO prepared statements
- XSS protection via
sanitize()method
- All inputs are validated through
- Upload files to web root
- Configure
.envfor production - Set up supervisor for WebSocket:
[program:websocket] command=php /path/to/server.php autostart=true autorestart=true
- Configure web server virtual host
- Run migrations:
php migrate.php
docker-compose -f docker-compose.yml up -dConfiguration files included:
fly.toml- Fly.io configurationProcfile- Heroku configuration
- Fork the repository
- Create feature branch:
git checkout -b feature-name - Commit changes:
git commit -am 'Add feature' - Push to branch:
git push origin feature-name - Submit pull request
This project is open-source and available under the MIT License.
Ahmed Saeed
- GitHub: @yahongie2014
- Project: PentavalueTask
- Ratchet for WebSocket implementation
- Predis for Redis client
- OpenWeatherMap for weather API
- Tailwind CSS for styling
Need Help? Open an issue on GitHub or contact the maintainer.