Skip to content

Lm-hg/clean_architecture

Repository files navigation

Clean Architecture Parking System 🚗

A parking management system built with Clean Architecture principles using PHP 8.3, PostgreSQL (relational data), MongoDB (flexible data), and Docker.

📋 Table of Contents


🏗️ Architecture

This project follows Clean Architecture principles with clear separation of concerns:

  • Domain Layer: Business entities and repository interfaces (no dependencies)
  • Application Layer: Use cases and DTOs (depends only on Domain)
  • Infrastructure Layer: Database implementations, external services (depends on Domain)
  • Presentation Layer: HTTP controllers, routing (depends on Application)

Hybrid Database Architecture

This project uses a hybrid database approach:

PostgreSQL (Relational Data):

  • Users, parkings, reservations, payments
  • Parking sessions (stationnements)
  • Subscriptions (abonnements)
  • Structured data with relationships

MongoDB (Flexible Data):

  • Pricing grids (custom rates per parking)
  • Subscription time slots (flexible schedules)
  • Invoices (variable structure)
  • Parking events logs
  • System logs

✅ Prerequisites

With Docker:

  • Docker Desktop (or Docker Engine + Docker Compose)
  • Git

Without Docker:

  • PHP 8.3 or higher
  • PostgreSQL 14 or higher
  • MongoDB 7 or higher
  • Composer
  • Apache or Nginx (optional, can use PHP built-in server)

📦 Installation

1. Clone the repository

git clone <repository-url>
cd clean_architecture

2. Configure environment variables

cp .env.exemple .env

Edit .env with your database credentials:

# PostgreSQL Database Configuration
POSTGRES_USER=parking_user
POSTGRES_PASSWORD=your_secure_password
POSTGRES_DB=parking_db

# Application Database Connection
DB_HOST=db                    # Use 'localhost' if running without Docker
DB_NAME=parking_db
DB_USER=parking_user
DB_PASSWORD=your_secure_password
DB_PORT=5432

# MongoDB Configuration
MONGO_USER=parking_mongo
MONGO_PASSWORD=your_mongo_password
MONGO_DB=parking_db

🚀 Running the Project

With Docker (Recommended)

First Time Setup

# Build and start containers
docker compose up -d --build

# View logs
docker compose logs -f

The application will be available at:

Subsequent Runs

# Start containers
docker compose up -d

# Stop containers
docker compose down

# Stop and remove volumes (fresh database)
docker compose down -v

Useful Docker Commands

# View logs
docker compose logs -f web
docker compose logs -f db

# Access web container shell
docker exec -it parking_app_web bash

# Access PostgreSQL shell
docker exec -it parking_app_db psql -U parking_user -d parking_db

# Access MongoDB shell
docker exec -it parking_app_mongodb mongosh -u parking_mongo -p your_mongo_password parking_db

# Restart containers
docker compose restart

# Rebuild after code changes
docker compose up -d --build

Without Docker

1. Install Dependencies

composer install

2. Setup PostgreSQL Database

Create a PostgreSQL database and user:

CREATE DATABASE parking_db;
CREATE USER parking_user WITH PASSWORD 'your_secure_password';
GRANT ALL PRIVILEGES ON DATABASE parking_db TO parking_user;

3. Initialize Database Schema

psql -U parking_user -d parking_db -f src/docker/postgres/init.sql

4. Configure Environment

Update .env file:

DB_HOST=localhost
DB_NAME=parking_db
DB_USER=parking_user
DB_PASSWORD=your_secure_password

5. Start PHP Development Server

php -S localhost:8000 -t public

The application will be available at: http://localhost:8000


🗄️ Database

PostgreSQL Schema (Relational Data)

The PostgreSQL database includes the following tables:

  • users: User accounts (owners, customers, admins) with company info
  • parkings: Parking spots/locations with GPS and opening hours
  • reservations: Booking records with payment status
  • payments: Payment transactions
  • stationnements: Actual parking sessions (entry/exit tracking)
  • abonnements: Subscriptions with custom time slots

MongoDB Collections (Flexible Data)

The MongoDB database includes the following collections:

  • pricing_grids: Custom pricing rates per parking (15min, 30min, 1h, 2h, day, night, special rates)
  • subscription_time_slots: Flexible time schedules for subscriptions
  • invoices: Detailed invoice metadata (items, taxes, totals)
  • parking_events: Entry/exit logs and events
  • system_logs: Application logs and errors

Seed Data

The database is automatically seeded with test data on first initialization:

Test Accounts (Password: admin123)

Email Role Description
[email protected] Admin System administrator
[email protected] Owner Parking spot owner
[email protected] Customer Regular customer

Test Parkings

  • Central Parking Spot: Paris city center (€5.50/hour)
  • Airport Parking: Near CDG Airport (€3.00/hour)

Database Management

Reset Database (Docker)

# Stop containers and remove volumes
docker compose down -v

# Restart (will recreate database with seed data)
docker compose up -d

Reset Database (Without Docker)

# Drop and recreate database
psql -U postgres -c "DROP DATABASE parking_db;"
psql -U postgres -c "CREATE DATABASE parking_db;"
psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE parking_db TO parking_user;"

# Re-run initialization script
psql -U parking_user -d parking_db -f src/docker/postgres/init.sql

Access Database Directly

With Docker:

# PostgreSQL
docker exec -it parking_app_db psql -U parking_user -d parking_db

# MongoDB
docker exec -it parking_app_mongodb mongosh -u parking_mongo -p your_mongo_password parking_db

Without Docker:

# PostgreSQL
psql -U parking_user -d parking_db

# MongoDB
mongosh -u parking_mongo -p your_mongo_password parking_db

🌐 API Endpoints

Health Check

curl http://localhost/health

Response:

{
  "status": "ok",
  "message": "Clean Architecture Parking API is running",
  "timestamp": "2025-11-25T10:00:00+00:00",
  "environment": {
    "php_version": "8.3.x",
    "db_host": "db"
  }
}

Database Connection Test

curl http://localhost/db-test

Response:

{
  "status": "success",
  "message": "Database connection successful",
  "database": {
    "version": "PostgreSQL 14.x...",
    "host": "db",
    "name": "parking_db",
    "tables_count": "6"
  }
}

MongoDB Connection Test

curl http://localhost/mongo-test

Response:

{
  "status": "success",
  "message": "MongoDB connection successful",
  "database": {
    "host": "mongodb",
    "name": "parking_db",
    "collections_count": "5"
  }
}

🧪 Testing

Run Tests

# With Docker
docker exec -it parking_app_web ./vendor/bin/phpunit

# Without Docker
./vendor/bin/phpunit

Run Tests with Coverage

# With Docker
docker exec -it parking_app_web ./vendor/bin/phpunit --coverage-html coverage

# Without Docker
./vendor/bin/phpunit --coverage-html coverage

📁 Project Structure

/
├── bin/                          # Executable scripts
├── config/                       # Configuration files
│   ├── database.php              # PostgreSQL PDO configuration
│   └── mongodb.php               # MongoDB client configuration
├── public/                       # Web root (Front Controller)
│   └── index.php                 # Application entry point
├── src/                          # Application source code
│   ├── Application/              # Use Cases and DTOs
│   │   ├── dtos/
│   │   ├── services/
│   │   └── usecases/
│   ├── Domain/                   # Business entities and rules
│   │   ├── Entities/
│   │   └── Repositories/         # Repository interfaces
│   ├── Infrastructure/           # Technical implementations
│   │   ├── persistences/         # Database repositories
│   │   │   ├── PostgreSQL/       # SQL repositories
│   │   │   └── MongoDB/          # NoSQL repositories
│   │   └── services/             # External services
│   ├── Presentation/             # HTTP layer
│   │   └── router.php
│   └── docker/                   # Docker configuration
│       ├── php/
│       │   └── Dockerfile
│       ├── postgres/
│       │   └── init.sql          # PostgreSQL schema
│       └── mongodb/
│           └── init-mongo.js     # MongoDB collections
├── tests/                        # Test files
├── .env                          # Environment variables (not in git)
├── .env.exemple                  # Environment template
├── composer.json                 # PHP dependencies
└── docker-compose.yml            # Docker services configuration

🔧 Development

PSR-4 Autoloading

The project uses PSR-4 autoloading with the following namespaces:

  • App\Domain\src/Domain/
  • App\Application\src/Application/
  • App\Infrastructure\src/Infrastructure/
  • App\Presentation\src/Presentation/

Code Standards

  • PHP 8.3+ with strict types
  • Clean Architecture principles
  • Hybrid database architecture (PostgreSQL + MongoDB)
  • Repository pattern for data access
  • Dependency injection
  • SOLID principles

📝 License

MIT


👥 Author

HETIC Student Project


🆘 Troubleshooting

Docker Issues

Port already in use:

# Change ports in docker-compose.yml
ports:
  - "8080:80"  # Instead of "80:80"

Database connection fails:

# Check if database is ready
docker compose logs db

# Restart database
docker compose restart db

Permission issues:

# Fix permissions
sudo chown -R $USER:$USER .

Without Docker Issues

Composer not found:

# Install Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

PostgreSQL connection refused:

# Check if PostgreSQL is running
sudo systemctl status postgresql

# Start PostgreSQL
sudo systemctl start postgresql

PHP extensions missing:

# Install required extensions
sudo apt-get install php8.3-pgsql php8.3-zip php8.3-gd php8.3-mongodb

MongoDB connection issues:

# Check MongoDB logs
docker compose logs mongodb

# Restart MongoDB
docker compose restart mongodb

🚀 Next Steps

  1. Implement your first use case in src/Application/usecases/
  2. Create repository implementations in src/Infrastructure/persistences/
  3. Add controllers in src/Presentation/
  4. Write tests in tests/
  5. Expand the API with more endpoints

Happy coding! 🎉

About

Un projet de groupe pour nous initier à la clean architecture

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages