Technical Architecture
This page describes the technical architecture of PCH-SIG.
Overview
PCH-SIG follows a classic 3-tier architecture:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Presentation │ │ Business │ │ Data │
│ │ │ │ │ │
│ React + Nginx │────▶│ Symfony API │────▶│ PostgreSQL │
│ │ │ │ │ + PostGIS │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
┌─────────────┐
│ Redis │
│ (Cache) │
└─────────────┘
Technical Stack
Frontend
| Technology | Version | Usage |
|---|---|---|
| React | 18.x | UI Framework |
| TypeScript | 5.x | Static typing |
| TanStack Query | 5.x | API request management |
| Zustand | 4.x | State management |
| Tailwind CSS | 3.x | CSS Framework |
| Leaflet | 1.9 | Mapping |
| Recharts | 2.x | Charts |
Backend
| Technology | Version | Usage |
|---|---|---|
| PHP | 8.3 | Server language |
| Symfony | 6.4 | PHP Framework |
| API Platform | 3.x | Automatic REST API |
| Doctrine ORM | 2.x | Object-relational mapping |
| LexikJWT | 2.x | JWT Authentication |
Database
| Technology | Version | Usage |
|---|---|---|
| PostgreSQL | 15 | Relational DBMS |
| PostGIS | 3.4 | Geospatial extension |
Infrastructure
| Technology | Version | Usage |
|---|---|---|
| Docker | 24.x | Containerization |
| Nginx | 1.25 | Web server / Reverse proxy |
| Redis | 7 | Cache and sessions |
Container Architecture
┌─────────────────────────────────────────────────────────────┐
│ Docker Network │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ pch_frontend│ │pch_nginx_ │ │ pch_backend │ │
│ │ (Nginx) │───▶│ backend │───▶│ (PHP-FPM) │ │
│ │ :80 │ │ :8000 │ │ :9000 │ │
│ └─────────────┘ └─────────────┘ └──────┬──────┘ │
│ │ │
│ ┌─────────────────────────┼─────────┐ │
│ │ │ │ │
│ ┌─────▼─────┐ ┌───────▼───────┐ │ │
│ │pch_postgres│ │ pch_redis │ │ │
│ │ :5432 │ │ :6379 │ │ │
│ └───────────┘ └───────────────┘ │ │
│ │ │
└─────────────────────────────────────────────────────────────┘
Request flow
- Client accesses frontend via port 80 (or 3000)
/api/*requests are proxied to backend (port 8000)- Nginx backend passes PHP requests to PHP-FPM
- PHP-FPM queries PostgreSQL and Redis
- Response returns to client
Backend Architecture
Folder structure
backend/
├── bin/ # Console scripts
├── config/ # Symfony configuration
│ ├── packages/ # Bundle configs
│ └── routes/ # Routes
├── migrations/ # Doctrine migrations
├── public/ # Web entry point
├── src/
│ ├── Controller/ # API Controllers
│ ├── Entity/ # Doctrine Entities
│ ├── Repository/ # Repositories
│ ├── Service/ # Business Services
│ ├── Security/ # Voters, Authenticators
│ └── EventListener/ # Listeners
└── var/ # Cache and logs
Main entities
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ Menage │────▶│ ChefMenage │ │ Logement │
│ │ │ │ │ │
│ - codeMenage │ │ - nomComplet │ │ - typeLogement│
│ - tailleMenage│ │ - telephone │ │ - nbPieces │
│ - scorePmt │ │ - age │ │ - sourceEau │
└───────┬───────┘ └───────────────┘ └───────────────┘
│
│ 1:N
▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ MembreMenage │ │ Beneficiaire │────▶│ Paiement │
│ │ │ │ │ │
│ - nomComplet │ │ - actif │ │ - montant │
│ - lienParente │ │ - modePaiement│ │ - statut │
└───────────────┘ └───────┬───────┘ └───────────────┘
│
│ N:1
▼
┌───────────────┐
│ Cycle │
│ │
│ - nom │
│ - statut │
│ - montantTotal│
└───────────────┘
Frontend Architecture
Folder structure
frontend/
├── public/ # Static assets
├── src/
│ ├── components/ # Reusable components
│ ├── layouts/ # Layouts (MainLayout)
│ ├── pages/ # Pages by module
│ │ ├── menages/
│ │ ├── beneficiaires/
│ │ ├── paiements/
│ │ └── ...
│ ├── services/ # API client (axios)
│ ├── stores/ # Zustand stores
│ ├── utils/ # Utilities
│ └── App.tsx # Entry point
└── package.json
Data flow
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Pages │───▶│ Stores │───▶│ Services │
│ │ │ (Zustand) │ │ (API) │
└─────────────┘ └─────────────┘ └──────┬──────┘
│ │
│ ▼
│ ┌─────────────┐
└──────────────────────────────▶│ Backend │
TanStack Query │ API │
└─────────────┘
Security
Authentication
- JWT (JSON Web Tokens) via LexikJWTAuthenticationBundle
- Access token (1 hour) + Refresh token (7 days)
- Token storage in localStorage
Authorization
- Granular permissions format
module.action - Symfony Voters for authorization logic
- Frontend and backend verification
Data protection
- HTTPS encryption in production
- Passwords hashed with bcrypt
- CSRF protection on forms
- Input validation
Scalability
Horizontal
- Frontend: CDN or multiple Nginx instances
- Backend: Load balancer + multiple PHP-FPM
- Database: PostgreSQL read replicas
Vertical
- Increased CPU/RAM resources
- SQL query optimization
- Redis caching