# rebecca-roussel/ecoride architecture

> Architecture diagram of the GitHub repository rebecca-roussel/ecoride, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-22). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/rebecca-roussel/ecoride
- Repository: https://github.com/rebecca-roussel/ecoride

## Overview

1. **Overall shape**
   EcoRide is a Symfony 7 application built as a classic server-rendered stack: HTTP requests enter through Nginx, are handled by PHP-FPM, routed to Symfony controllers, and rendered mainly with Twig templates.

2. **Request flow**
   The main runtime path is: browser → Nginx → `public/index.php` → controller → service layer → PostgreSQL/MongoDB/email/geocoding as needed → Twig view → HTML response. The architecture is centered on synchronous server-side rendering rather than an API-first front end.

3. **Presentation layer**
   The UI lives in `templates/` and `public/`. Twig handles page composition, fragments, and email templates; `public/css` and `public/js` contain page-specific assets for features like login, geocoding suggestions, results, profiles, roles, and dashboards. Static files are served directly by Nginx.

4. **Controller layer**
   `src/Controller/` is organized by business journey: public pages (`Accueil`, `Contact`, `MentionsLegales`, `Credits`), identity flows (`Connexion`, `Inscription`, `MotDePasseOublie`, `ReinitialiserMotDePasse`), ride flows (`Recherche`, `Resultats`, `Details`, `PublierCovoiturage`, `ParticiperCovoiturage`), account/vehicle management (`Profil`, `TableauDeBord`, `GererVehicules`, `Historique`), and back-office areas (`EspaceEmploye`, `EspaceAdmin`, `GererRoles`). `ApiGeocodageController` is the main HTTP endpoint for autocomplete/geocoding behavior.

5. **Service layer**
   `src/Service/` contains the actual business and persistence logic. The code deliberately avoids an ORM: services use PDO-based PostgreSQL access and keep SQL explicit. The service set is split by concern: connection handling, user session state, emailing, address geocoding, event logging, and per-domain persistence services.

6. **Primary data store: PostgreSQL**
   PostgreSQL holds the structured business data: users, vehicles, rides, participations, credits, history, password reset state, and admin/employe-related records. The README indicates that important invariants are enforced in the database itself with constraints, functions, and triggers, so some business rules live below the application layer.

7. **Secondary data store: MongoDB**
   MongoDB is used as an operational event journal rather than the main business database. It records chronological events such as logins, participations, incidents, moderation actions, and suspensions. This makes the architecture split between transactional business data in PostgreSQL and trace/audit data in MongoDB.

8. **Mail and external integrations**
   `EnvoiCourriels` supports email-based workflows such as password reset and ride validation/cancellation. In local development the app uses MailHog, so email delivery is observable without sending real mail. `GeocodageAdresse` powers address lookup/suggestions for ride publication and search.

9. **Security and session boundary**
   Authentication/session state is handled explicitly through `SessionUtilisateur`. The app uses password hashing, CSRF protection in forms, reset tokens with limited lifetime, and a set of HTTP security headers configured at the web server level. Environment secrets are kept in `.env` variants rather than in code.

10. **Runtime and deployment**
   The repo is container-first. Docker Compose orchestrates Nginx, PHP-FPM, PostgreSQL, MongoDB, and MailHog in development; a production compose file and Nginx production config provide the deployment boundary. Code is mounted read-only into Nginx in production, and DBs are kept off the public network.

11. **Build, test, and release support**
   GitHub Actions workflows support continuous integration and deployment. Tests live under `tests/` and include application-level checks plus database connectivity tests. The `docs/sql/` scripts initialize the schema and demo data, and the `docker/sauvegardes/` scripts handle backup/restore of PostgreSQL and MongoDB.

12. **Documentation as part of the architecture**
   The repository is unusually documentation-heavy: generated code docs, UML, data-model diagrams, UI mockups, deployment notes, and user manuals all exist alongside the code. For architecture diagramming, this indicates the project was designed with explicit separation between business workflows, data model, and operational deployment.

Main entry points: [`templates`](https://github.com/rebecca-roussel/ecoride/tree/main/templates) (Twig views), [`config/routes.yaml`](https://github.com/rebecca-roussel/ecoride/blob/main/config/routes.yaml) (Routing), [`src/Controller/ConnexionController.php`](https://github.com/rebecca-roussel/ecoride/blob/main/src/Controller/ConnexionController.php) (Identity), [`src/Controller/RechercheController.php`](https://github.com/rebecca-roussel/ecoride/blob/main/src/Controller/RechercheController.php) (Ride flows)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_presentation["Presentation"]
  node_templates["Twig views<br/>presentation"]
  node_assets_css["Stylesheets<br/>static assets"]
  node_assets_js["Client scripts<br/>static assets"]
  node_uploads["Photos<br/>static uploads"]
end

subgraph group_http["HTTP & App"]
  node_public_index["Front controller<br/>Symfony entrypoint<br/>[index.php]"]
  node_kernel["Kernel<br/>Symfony boot<br/>[Kernel.php]"]
  node_routes["Routing<br/>route config<br/>[routes.yaml]"]
  node_controllers_public["Public pages<br/>controllers"]
  node_controllers_identity["Identity<br/>controllers"]
  node_controllers_ride["Ride flows<br/>controllers"]
  node_controllers_account["Account area<br/>controllers"]
  node_controllers_backoffice["Back office<br/>controllers"]
  node_controllers_geo_api["Geocoding API<br/>controller"]
end

subgraph group_domain["Services"]
  node_session["Session state"]
  node_db_conn["PostgreSQL access"]
  node_persistence["Persistence layer<br/>service adapters"]
  node_mailer["Mail service<br/>integration<br/>[EnvoiCourriels.php]"]
  node_geocoding["Geocoding<br/>integration"]
  node_journal["Event journal<br/>integration"]
end

subgraph group_ops["Data & Ops"]
  node_db_schema["SQL schema<br/>database definition<br/>[01_schema.sql]"]
  node_docker_compose["Compose stack<br/>deployment"]
  node_docker_prod["Prod stack<br/>deployment"]
  node_ci_cd["CI/CD<br/>automation"]
end

node_public_index -->|"boots"| node_kernel
node_public_index -->|"dispatches via"| node_routes
node_routes -->|"maps to"| node_controllers_public
node_routes -->|"maps to"| node_controllers_identity
node_routes -->|"maps to"| node_controllers_ride
node_routes -->|"maps to"| node_controllers_account
node_routes -->|"maps to"| node_controllers_backoffice
node_routes -->|"maps to"| node_controllers_geo_api
node_controllers_public -->|"renders"| node_templates
node_controllers_identity -->|"renders"| node_templates
node_controllers_ride -->|"renders"| node_templates
node_controllers_account -->|"renders"| node_templates
node_controllers_backoffice -->|"renders"| node_templates
node_controllers_identity -->|"uses"| node_session
node_controllers_ride -->|"uses"| node_geocoding
node_controllers_identity -->|"uses"| node_mailer
node_controllers_ride -->|"uses"| node_persistence
node_controllers_account -->|"uses"| node_persistence
node_controllers_backoffice -->|"reads events"| node_journal
node_persistence -->|"executes SQL"| node_db_conn
node_persistence -->|"relies on"| node_db_schema
node_journal -.->|"separates from"| node_db_schema
node_templates -.->|"pairs with"| node_assets_css
node_templates -.->|"enhanced by"| node_assets_js
node_templates -.->|"references"| node_uploads
node_docker_compose -->|"serves"| node_public_index
node_docker_compose -->|"provides"| node_db_conn
node_docker_compose -->|"provides"| node_journal
node_docker_prod -.->|"specializes"| node_docker_compose
node_ci_cd -->|"deploys"| node_docker_prod

click node_public_index "https://github.com/rebecca-roussel/ecoride/blob/main/public/index.php"
click node_kernel "https://github.com/rebecca-roussel/ecoride/blob/main/src/Kernel.php"
click node_routes "https://github.com/rebecca-roussel/ecoride/blob/main/config/routes.yaml"
click node_controllers_public "https://github.com/rebecca-roussel/ecoride/blob/main/src/Controller/AccueilController.php"
click node_controllers_identity "https://github.com/rebecca-roussel/ecoride/blob/main/src/Controller/ConnexionController.php"
click node_controllers_ride "https://github.com/rebecca-roussel/ecoride/blob/main/src/Controller/RechercheController.php"
click node_controllers_account "https://github.com/rebecca-roussel/ecoride/blob/main/src/Controller/ProfilController.php"
click node_controllers_backoffice "https://github.com/rebecca-roussel/ecoride/blob/main/src/Controller/EspaceAdminController.php"
click node_controllers_geo_api "https://github.com/rebecca-roussel/ecoride/blob/main/src/Controller/ApiGeocodageController.php"
click node_templates "https://github.com/rebecca-roussel/ecoride/tree/main/templates"
click node_assets_css "https://github.com/rebecca-roussel/ecoride/tree/main/public/css"
click node_assets_js "https://github.com/rebecca-roussel/ecoride/tree/main/public/js"
click node_uploads "https://github.com/rebecca-roussel/ecoride/tree/main/public/photos"
click node_session "https://github.com/rebecca-roussel/ecoride/blob/main/src/Service/SessionUtilisateur.php"
click node_db_conn "https://github.com/rebecca-roussel/ecoride/blob/main/src/Service/ConnexionPostgresql.php"
click node_persistence "https://github.com/rebecca-roussel/ecoride/blob/main/src/Service/PersistanceUtilisateurPostgresql.php"
click node_mailer "https://github.com/rebecca-roussel/ecoride/blob/main/src/Service/EnvoiCourriels.php"
click node_geocoding "https://github.com/rebecca-roussel/ecoride/blob/main/src/Service/GeocodageAdresse.php"
click node_journal "https://github.com/rebecca-roussel/ecoride/blob/main/src/Service/JournalEvenements.php"
click node_db_schema "https://github.com/rebecca-roussel/ecoride/blob/main/docs/sql/01_schema.sql"
click node_docker_compose "https://github.com/rebecca-roussel/ecoride/blob/main/docker-compose.yaml"
click node_docker_prod "https://github.com/rebecca-roussel/ecoride/blob/main/docker-compose.production.yaml"
click node_ci_cd "https://github.com/rebecca-roussel/ecoride/blob/main/.github/workflows/deploiement_continu.yml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_templates,node_assets_css,node_assets_js,node_uploads toneBlue
class node_public_index,node_kernel,node_routes,node_controllers_public,node_controllers_identity,node_controllers_ride,node_controllers_account,node_controllers_backoffice,node_controllers_geo_api toneAmber
class node_session,node_db_conn,node_persistence,node_mailer,node_geocoding,node_journal toneMint
class node_db_schema,node_docker_compose,node_docker_prod,node_ci_cd toneRose
```

## Components

### Presentation

Twig pages and browser assets rendered by Symfony.

- [Twig views](https://github.com/rebecca-roussel/ecoride/tree/main/templates): presentation · Server-rendered pages, fragments, and email templates. · `templates`
- [Stylesheets](https://github.com/rebecca-roussel/ecoride/tree/main/public/css): static assets · Page-specific CSS for public and authenticated screens. · `public/css`
- [Client scripts](https://github.com/rebecca-roussel/ecoride/tree/main/public/js): static assets · Browser behavior for forms, suggestions, dashboards, and navigation. · `public/js`
- [Photos](https://github.com/rebecca-roussel/ecoride/tree/main/public/photos): static uploads · User-uploaded vehicle or profile imagery served statically. · `public/photos`

### HTTP & App

Front controller, routing, and business-facing controllers.

- [Front controller](https://github.com/rebecca-roussel/ecoride/blob/main/public/index.php): Symfony entrypoint · HTTP requests enter here before Symfony routing and controller dispatch. · `public/index.php`
- [Kernel](https://github.com/rebecca-roussel/ecoride/blob/main/src/Kernel.php): Symfony boot · Application bootstrap and bundle/runtime wiring. · `src/Kernel.php`
- [Routing](https://github.com/rebecca-roussel/ecoride/blob/main/config/routes.yaml): route config · Maps incoming paths to controllers and framework endpoints. · `config/routes.yaml`
- [Public pages](https://github.com/rebecca-roussel/ecoride/blob/main/src/Controller/AccueilController.php): controllers · Landing and legal pages for anonymous visitors. · `src/Controller/AccueilController.php`
- [Identity](https://github.com/rebecca-roussel/ecoride/blob/main/src/Controller/ConnexionController.php): controllers · Login, registration, and password reset flows. · `src/Controller/ConnexionController.php`
- [Ride flows](https://github.com/rebecca-roussel/ecoride/blob/main/src/Controller/RechercheController.php): controllers · Search, results, details, publishing, and participation journeys. · `src/Controller/RechercheController.php`
- [Account area](https://github.com/rebecca-roussel/ecoride/blob/main/src/Controller/ProfilController.php): controllers · Profile, dashboard, vehicle, and history management. · `src/Controller/ProfilController.php`
- [Back office](https://github.com/rebecca-roussel/ecoride/blob/main/src/Controller/EspaceAdminController.php): controllers · Employee and admin moderation, roles, and operational review. · `src/Controller/EspaceAdminController.php`
- [Geocoding API](https://github.com/rebecca-roussel/ecoride/blob/main/src/Controller/ApiGeocodageController.php): controller · Autocomplete and address lookup endpoint used by ride forms. · `src/Controller/ApiGeocodageController.php`

### Services

Business logic, persistence adapters, and external integrations.

- [Session state](https://github.com/rebecca-roussel/ecoride/blob/main/src/Service/SessionUtilisateur.php): service · Explicit user session and authentication state handling. · `src/Service/SessionUtilisateur.php`
- [PostgreSQL access](https://github.com/rebecca-roussel/ecoride/blob/main/src/Service/ConnexionPostgresql.php): service · PDO connection and explicit SQL execution against the main database. · `src/Service/ConnexionPostgresql.php`
- [Persistence layer](https://github.com/rebecca-roussel/ecoride/blob/main/src/Service/PersistanceUtilisateurPostgresql.php): service adapters · Per-domain PostgreSQL persistence for users, rides, vehicles, credits, history, and resets. · `src/Service/PersistanceUtilisateurPostgresql.php`
- [Mail service](https://github.com/rebecca-roussel/ecoride/blob/main/src/Service/EnvoiCourriels.php): integration · Sends password reset and ride validation/cancellation emails. · `src/Service/EnvoiCourriels.php`
- [Geocoding](https://github.com/rebecca-roussel/ecoride/blob/main/src/Service/GeocodageAdresse.php): integration · Address lookup and suggestion logic for search and ride publication. · `src/Service/GeocodageAdresse.php`
- [Event journal](https://github.com/rebecca-roussel/ecoride/blob/main/src/Service/JournalEvenements.php): integration · Chronological operational logging for logins, participations, incidents, and moderation. · `src/Service/JournalEvenements.php`

### Data & Ops

Datastores, deployment, and release support.

- [SQL schema](https://github.com/rebecca-roussel/ecoride/blob/main/docs/sql/01_schema.sql): database definition · Database structure, constraints, functions, triggers, and demo data source. · `docs/sql/01_schema.sql`
- [Compose stack](https://github.com/rebecca-roussel/ecoride/blob/main/docker-compose.yaml): deployment · Container orchestration for Nginx, PHP-FPM, PostgreSQL, MongoDB, and MailHog. · `docker-compose.yaml`
- [Prod stack](https://github.com/rebecca-roussel/ecoride/blob/main/docker-compose.production.yaml): deployment · Production compose boundary and Nginx production configuration. · `docker-compose.production.yaml`
- [CI/CD](https://github.com/rebecca-roussel/ecoride/blob/main/.github/workflows/deploiement_continu.yml): automation · GitHub Actions workflows for integration and deployment. · `.github/workflows/deploiement_continu.yml`

## Connections

- Front controller → Kernel: boots · Symfony runtime is initialized from the front controller.
- Front controller → Routing: dispatches via · Incoming requests are matched to routes before controller execution.
- Routing → Public pages: maps to · Public pages are routed to their controllers.
- Routing → Identity: maps to · Authentication and reset flows are routed here.
- Routing → Ride flows: maps to · Ride search and participation journeys are routed here.
- Routing → Account area: maps to · Account and dashboard screens are routed here.
- Routing → Back office: maps to · Employee and admin paths are routed here.
- Routing → Geocoding API: maps to · Autocomplete and geocoding requests are routed here.
- Public pages → Twig views: renders · Controllers return Twig views for server-side HTML.
- Identity → Twig views: renders · Identity screens and email-related templates are rendered here.
- Ride flows → Twig views: renders · Ride journeys are rendered as Twig pages and fragments.
- Account area → Twig views: renders · Account and dashboard screens use Twig templates.
- Back office → Twig views: renders · Back-office screens are server-rendered.
- Identity → Session state: uses · Authentication and reset flows rely on explicit session state.
- Ride flows → Geocoding: uses · Ride forms and search use address lookup suggestions.
- Identity → Mail service: uses · Password reset and validation emails are sent through mail services.
- Ride flows → Persistence layer: uses · Ride creation, results, and participation are backed by persistence adapters.
- Account area → Persistence layer: uses · Profile, vehicles, and history are loaded and updated through persistence.
- Back office → Event journal: reads events · Moderation and employee views inspect operational event history.
- Persistence layer → PostgreSQL access: executes SQL · Domain adapters share the explicit PostgreSQL connection layer.
- Persistence layer → SQL schema: relies on · Business invariants are enforced by SQL constraints, functions, and triggers.
- Event journal → SQL schema: separates from · Operational event history is modeled alongside the relational schema boundary.
- Twig views → Stylesheets: pairs with · Rendered pages are styled by page-specific CSS assets.
- Twig views → Client scripts: enhanced by · Interactive screens use browser-side scripts for form behavior and suggestions.
- Twig views → Photos: references · Views can display user-uploaded images.
- Compose stack → Front controller: serves · Nginx and PHP-FPM expose the server-rendered application.
- Compose stack → PostgreSQL access: provides · The compose stack includes PostgreSQL and related services used by the app.
- Compose stack → Event journal: provides · Operational event storage is backed by the container stack.
- Prod stack → Compose stack: specializes · Production deployment refines the development container boundary.
- CI/CD → Prod stack: deploys · Workflow automation targets the production deployment stack.
