DEV Community

Schat Carino
Schat Carino

Posted on

SmartPark : une app IoT de stationnement intelligent

Application indépendante de stationnement intelligent — suivi temps réel, détection d'anomalies IoT, pilotage des interventions terrain.


Table des matières

  1. Contexte — Smart City & SmartPark
  2. Étude de marché
  3. Analyse des besoins
  4. Acteurs & services
  5. Veille technologique IoT
  6. Architecture — Comparaison & choix hexagonale
  7. Équipe, budget & planning
  8. Faisabilité technique
  9. Choix technologiques
  10. Synthèse & recommandation

1. Contexte

Qu'est-ce qu'une Smart City ?

Une Smart City est une copie numérique de gestion d'une ville existante. Elle utilise les technologies numériques (IoT, data, IA) pour optimiser les services urbains : mobilité, énergie, environnement, sécurité. L'objectif : améliorer la qualité de vie tout en rationalisant les coûts.

Jumeau numérique urbain — La Smart City crée un miroir digital de la ville physique. Chaque capteur alimente un modèle vivant permettant d'agir en temps réel plutôt qu'en réaction.

Piliers d'une Smart City

  • Smart Mobility — Trafic intelligent, stationnement, transports connectés, mobilités douces
  • Smart Energy — Smart grids, éclairage adaptatif, bâtiments à énergie positive
  • Smart Environment — Qualité de l'air, gestion déchets, arrosage intelligent
  • Smart Governance — Open data, e-administration, participation citoyenne

SmartPark — Application indépendante

SmartPark est une application indépendante de stationnement intelligent qui s'inscrit dans le pilier Smart Mobility. C'est un logiciel autonome, déployable seul, avec sa propre base de données, son propre cycle de vie et sa propre équipe. Elle n'est pas un microservice d'une plateforme plus large — elle est conçue pour fonctionner en standalone tout en exposant des APIs pour s'intégrer avec d'autres modules Smart City si besoin.

Périmètre pilote — Centre-Ville, 500 places équipées de capteurs magnétiques. Objectif : réduire le temps de détection d'anomalie de 72h à 15 minutes, augmenter la rotation de +25%.

QQOQCP

Question Réponse
Qui ? Commanditaire : Direction du Numérique. Utilisateurs : agents voirie, superviseurs CRU, direction Mobilités, citoyens. Partenaires : prestataire IoT, DSI.
Quoi ? Application indépendante : suivi temps réel occupation, détection anomalies capteurs, pilotage interventions, information citoyenne.
Où ? Cloud collectivité. Web desktop (CRU) + responsive tablettes (agents) + app citoyenne.
Quand ? Pilote Centre-Ville (Sprint 1). Généralisation Sprint 3. Schéma Smart City 2025-2030.
Comment ? Architecture hexagonale (ports & adapters). React, NestJS, PostgreSQL, Docker, MQTT.
Pourquoi ? Occupation mal connue, capteurs non détectés (72h), coordination défaillante, perte revenus.

Scénario de catastrophe

⚠️ Inondation du parking souterrain Centre-Ville — Besoins révélés : capteurs niveau d'eau, notification urgente, fermeture accès auto, basculement guidage, traçabilité incident. Chaque catastrophe expose des acteurs et contraintes invisibles en fonctionnement nominal.


2. Étude de marché

Taille du marché mondial

Le marché du stationnement intelligent connaît une croissance forte, porté par l'urbanisation, l'IoT et les programmes Smart City gouvernementaux.

Source Taille 2024-25 Prévision CAGR
Grand View Research ~6.5 Md $ (2022) 53.4 Md $ (2033) 23.3%
IMARC Group 5.7 Md $ (2024) 14.1 Md $ (2033) 10.5%
Allied Market Research 8.5 Md $ (2023) 48.3 Md $ (2033) 19.3%
Straits Research 9.37 Md $ (2025) 33.8 Md $ (2033) 17.4%
Market Research Future 6.77 Md $ (2025) 16.3 Md $ (2035) 9.1%

Acteurs existants

Acteur Spécialité Technologies
Urbiotica (Espagne) Capteurs magnétiques voirie + plateforme cloud LoRaWAN, Sigfox, NB-IoT
Nedap SENSIT (Pays-Bas) Capteurs au sol haute précision LoRaWAN, propre réseau
PNI PlacePod (USA) Capteurs magnétiques IoT LoRaWAN, cellular
Bosch Parking Solutions Capteurs + plateforme intégrée LoRaWAN, caméras
SKIDATA (Autriche) Gestion accès parkings couverts RFID, LPR, barrières
Flowbird (ex-Parkeon, France) Horodateurs connectés, paiement NFC, app mobile
EasyPark / ParkMobile App citoyenne paiement + guidage App mobile, GPS
Cleverciti (Allemagne) Détection par caméra overhead Vision IA, cloud

Sources de veille


3. Analyse des besoins

Besoins fonctionnels

Gestion du stationnement

  • Visualiser en temps réel l'occupation (libre / occupée / réservée / hors-service)
  • Cartographier les zones avec taux d'occupation par zone, secteur, étage
  • Calculer le taux de rotation par place et par zone
  • Historiser les données (heure, jour, semaine, mois)
  • Gérer les places spéciales : PMR, livraison, électriques, deux-roues
  • Supporter voirie et ouvrage (souterrains/aériens)
  • Guidage dynamique vers les places libres les plus proches
  • Réservation à l'avance (phases ultérieures)

Gestion des capteurs IoT

  • Détection automatique anomalies (signal perdu, valeurs aberrantes, batterie faible)
  • Supervision santé capteurs (uptime, dernière communication, batterie)
  • Réception trames temps réel via MQTT / LoRaWAN
  • Cycle de vie : installation, calibration, maintenance, remplacement
  • Support multi-types : magnétiques, ultrasons, caméras
  • Agrégation et normalisation données hétérogènes

Alertes & interventions

  • Alertes automatiques selon règles configurables
  • Dispatch interventions aux agents géolocalisés
  • Cycle : créée → assignée → en cours → clôturée
  • Report mobile (photo, commentaire, statut)
  • Escalade auto si non traité dans le délai
  • Gestion urgences (inondation, vandalisme)

Reporting & tableaux de bord

  • Dashboard temps réel CRU avec vue cartographique
  • Rapports automatiques (quotidien, hebdomadaire, mensuel)
  • KPI : occupation, rotation, incidents, revenus, SLA capteurs
  • Exports PDF/CSV pour le COPIL
  • Analyse prédictive ML sur historiques

Utilisateurs & droits

  • Auth sécurisée (SSO, LDAP, MFA superviseurs)
  • RBAC (rôles et permissions par profil)
  • Audit trail (journalisation actions)
  • App citoyenne consultation disponibilités

Besoins non fonctionnels

Critère Exigence Priorité
Performance API < 200ms, 500+ trames/s, rafraîchissement carte < 2s 🔴 Critique
Sécurité TLS 1.3, AES-256, RGPD, WAF, MFA admin 🔴 Critique
Scalabilité 500 → 50 000 places sans refonte. Extensible Smart City 🟠 Haute
Haute disponibilité SLA 99.9%. Réplication. Failover auto. Mode dégradé 🔴 Critique
Maintenabilité Architecture hexagonale. Coverage >80%. OpenAPI. CI/CD 🟢 Standard
Accessibilité RGAA AA. Responsive desktop/tablette/mobile 🟢 Standard

4. Acteurs

Acteurs métier

Acteur Rôle Interface
Agent de terrain Intervient sur capteurs/places, reçoit missions, reporte (photo/statut) App mobile (React Native), 4G/VPN
Superviseur CRU Dashboard temps réel, dispatch interventions, gestion alertes Web desktop multi-écrans
Citoyen / Usager Consultation disponibilités, signalement problèmes App mobile, panneaux dynamiques

Acteurs décisionnels

Acteur Rôle
Direction du Numérique Commanditaire. Orientations stratégiques, budgets, schéma Smart City
Direction Mobilités Sponsor métier. Politique stationnement, exigences, validation KPI
COPIL Gouvernance. Validation livrables sprint, arbitrage priorités/risques

Acteurs techniques

Acteur Rôle
DSI interne Infra cloud, déploiement, sécurité réseau, monitoring, support N2/N3
Prestataire IoT Capteurs, maintenance hardware, API/SDK, gateway LoRaWAN
Équipe dev PO + SM + Tech Lead + devs. Scrum. Conception, dev, tests, déploiement
RSSI / DPO Architecture sécurité, audits, conformité RGPD

Systèmes externes

  • Capteurs IoT — Trames occupé/libre toutes les 30s via MQTT
  • Gateway LoRaWAN — Agrégation données → broker MQTT
  • SIG municipal — Fonds de carte, géolocalisation places
  • Système de paiement — Horodateurs, paiement mobile
  • Panneaux dynamiques — Affichage places libres en entrée
  • SI collectivité — LDAP/AD (auth), SI RH (agents)

5. Veille technologique IoT

Protocoles réseau IoT

Critère LoRaWAN Sigfox NB-IoT Zigbee Wi-Fi
Portée 2-5 km urbain 10 km urbain 1-10 km 10-100 m 50-100 m
Consommation Très faible (5-10 ans batterie) Très faible Faible (2-5 ans) Très faible Élevée
Débit 0.3-50 kbps 100-600 bps 20-250 kbps 250 kbps 1-100+ Mbps
Coût capteur 15-30 € 10-25 € 20-40 € 5-15 € 10-30 €
Adapté parking ✅ Idéal ⚠️ Possible ⚠️ Possible ❌ Portée insuffisante ❌ Conso trop élevée

Choix : LoRaWAN — Standard de facto pour l'IoT urbain. Batterie 5-10 ans, portée suffisante avec 2-3 gateways, pas de câblage électrique, écosystème mature de capteurs compatibles.

Types de capteurs

Type Précision Coût Installation Limites
Magnétique au sol 95-98% 50-120 € Carottage chaussée Perturbations magnétiques (tramway)
Ultrason (plafond) 90-95% 30-60 € Fixé au plafond Parking couvert uniquement
Caméra + IA 97-99% 200-500 € + serveur Mât/bâtiment RGPD, coût, météo
Radar 93-97% 80-150 € Encastré/poteau Plus cher, moins mature
Infrarouge 85-90% 20-40 € Barrière entrée Comptage uniquement

Choix : magnétique (voirie) + ultrason (couverts) — Le magnétique est le standard voirie. Ultrasons en plafonnier pour les parkings couverts sans contraintes RGPD des caméras.

Protocole applicatif

Protocole Modèle Overhead Adapté IoT Verdict
MQTT Pub/Sub Très faible (2 octets) Conçu pour l'IoT ✅ Retenu
HTTP/REST Req/Resp Élevé (headers) Trop lourd ❌ Écarté
CoAP Req/Resp (UDP) Faible Oui mais moins mature ⚠️ Alternative
AMQP Queue/Exchange Moyen Trop lourd ❌ Écarté

Broker MQTT

Broker Clustering MQTT 5.0 Licence Verdict
EMQX Natif Oui Open source ✅ Retenu
Mosquitto Non (bridge) Oui Open source ⚠️ Dev/POC
HiveMQ Natif Oui Commercial ~30k€/an ❌ Budget
VerneMQ Natif Partiel Open source ⚠️ Alternative

Sources veille IoT


6. Architecture

Tableau comparatif des architectures

Critère Layered (N-tiers) Clean Architecture Onion Architecture Hexagonale (Ports & Adapters) Microservices
Principe Couches empilées (UI → Business → Data) Cercles concentriques (Entities → Use Cases → Adapters → Frameworks) Cercles concentriques (Domain → Services → Infra) Hexagone : domaine au centre, ports = interfaces, adapters = implémentations Services indépendants par domaine métier
Isolation domaine Faible Forte Forte Très forte Variable
Testabilité Moyenne Bonne Bonne Excellente — adaptateurs mockables via ports Bonne par service, tests intégration complexes
Changement de techno Difficile Facile Facile Très facile — changer un adaptateur Par service
Complexité Faible Moyenne Moyenne Moyenne Élevée (K8s, réseau, observabilité)
Adapté app indépendante Oui mais couplage Oui Oui Idéal — conçu pour ça Non — systèmes distribués
Adapté IoT temps réel Possible Possible Possible Idéal — port MQTT = adaptateur Oui mais overhead réseau
Auteur Classique (90s) R.C. Martin (2012) J. Palermo (2008) A. Cockburn (2005) Fowler, Newman
Verdict SmartPark ❌ Écarté ⚠️ Proche mais moins concret ⚠️ Proche mais moins concret Retenu ❌ Surdimensionné

Architecture retenue : Hexagonale (Ports & Adapters) — Alistair Cockburn, 2005

SmartPark est une application indépendante, pas un système distribué. L'hexagonale est conçue exactement pour ça : isoler le domaine métier de toutes les technologies. Chaque technologie est un adaptateur interchangeable. Pas besoin de la complexité des microservices pour une app standalone.

Clean et Onion sont des variations proches mais l'hexagonale est plus concrète (ports/adapters vs couches abstraites) et mieux adaptée à l'IoT (un port MQTT avec son adaptateur est un concept naturel).

Architecture hexagonale — SmartPark

         ┌─────────────────────────────────────────┐
         │       ADAPTATEURS PRIMAIRES (Driving)    │
         │  ┌───────────┐ ┌──────────┐ ┌─────────┐ │
         │  │ REST API  │ │MQTT Sub  │ │WebSocket│ │
         │  │Controller │ │Listener  │ │Handler  │ │
         │  │(NestJS)   │ │(IoT)     │ │(Dash)   │ │
         │  └─────┬─────┘ └────┬─────┘ └────┬────┘ │
         └────────┼────────────┼────────────┼───────┘
                  ▼            ▼            ▼
         ┌──────────────────────────────────────────┐
         │            PORTS ENTRANTS                 │
         │                                          │
         │  «interface» ParkingUseCase               │
         │    getOccupancy(zoneId)                   │
         │    updatePlaceStatus(placeId, status)     │
         │    findNearestAvailable(lat, lng)         │
         │                                          │
         │  «interface» SensorUseCase                │
         │    processTrame(trame)                    │
         │    getSensorHealth(sensorId)              │
         │                                          │
         │  «interface» AlertUseCase                 │
         │    createAlert(anomaly)                   │
         │    assignIntervention(alertId, agentId)   │
         │    escalateAlert(alertId)                 │
         ├──────────────────────────────────────────┤
         │           DOMAINE MÉTIER                  │
         │         (Cœur hexagonal)                  │
         │                                          │
         │  Entités :                               │
         │    ParkingPlace · Zone · Capteur          │
         │    Alerte · Intervention · Agent          │
         │                                          │
         │  Value Objects :                          │
         │    PlaceStatus (LIBRE|OCCUPEE|HS|RESERVEE)│
         │    GeoCoordinate · SensorTrame            │
         │                                          │
         │  Règles métier :                         │
         │    • Libre si capteur = 0 depuis > 30s   │
         │    • Anomalie si silence capteur > 5min  │
         │    • Escalade si alerte non traitée 30min│
         │    • Guidage = place libre la + proche   │
         ├──────────────────────────────────────────┤
         │            PORTS SORTANTS                 │
         │                                          │
         │  «interface» ParkingPlaceRepository       │
         │  «interface» SensorRepository             │
         │  «interface» AlertRepository              │
         │  «interface» NotificationPort             │
         │  «interface» GeoSpatialPort               │
         └──────────────┬───────────────────────────┘
                        ▼
         ┌──────────────────────────────────────────┐
         │      ADAPTATEURS SECONDAIRES (Driven)     │
         │  ┌──────────┐ ┌──────────┐ ┌──────────┐ │
         │  │PostgreSQL│ │  MQTT    │ │  Email   │ │
         │  │+ PostGIS │ │  Pub     │ │  Notif   │ │
         │  └──────────┘ └──────────┘ └──────────┘ │
         │  ┌──────────┐ ┌──────────┐ ┌──────────┐ │
         │  │Timescale │ │  SMS     │ │  Redis   │ │
         │  │DB        │ │  Notif   │ │  Cache   │ │
         │  └──────────┘ └──────────┘ └──────────┘ │
         └──────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Structure de dossiers

smartpark/
├── src/
│   ├── domain/                  ← Centre hexagonal (AUCUNE dépendance)
│   │   ├── entities/            (ParkingPlace, Zone, Capteur, Alerte, Intervention, Agent)
│   │   ├── value-objects/       (PlaceStatus, GeoCoordinate, SensorTrame)
│   │   ├── errors/              (PlaceNotFoundError, SensorTimeoutError)
│   │   └── rules/               (OccupancyRule, AnomalyDetectionRule, EscalationRule)
│   │
│   ├── application/             ← Ports + Use Cases
│   │   ├── ports/
│   │   │   ├── in/              (ParkingUseCase, SensorUseCase, AlertUseCase)
│   │   │   └── out/             (ParkingPlaceRepo, SensorRepo, NotificationPort, GeoSpatialPort)
│   │   └── services/            (ParkingService, SensorService, AlertService)
│   │
│   ├── infrastructure/          ← Adaptateurs concrets
│   │   ├── persistence/         (PostgresParkingRepo, TimescaleDBSensorRepo)
│   │   ├── messaging/           (MqttSensorAdapter, MqttPublishAdapter)
│   │   ├── notification/        (EmailAdapter, SmsAdapter, PushAdapter)
│   │   ├── cache/               (RedisCacheAdapter)
│   │   ├── geo/                 (PostGisGeoAdapter)
│   │   └── http/                (ParkController, AlertController, SensorController)
│   │
│   └── config/                  (di-container, app-config, env)
│
├── test/
│   ├── unit/                    ← Tests domaine (rapides, sans infra)
│   ├── integration/             ← Tests adaptateurs (avec BDD/MQTT)
│   └── e2e/                     ← Tests API complets
│
├── docker-compose.yml
├── Dockerfile
└── .gitlab-ci.yml
Enter fullscreen mode Exit fullscreen mode

Hexagonale + Framework : comment ça marche ?

La plupart des frameworks sont opinionated — ils imposent leur structure. Avec Express, Laravel ou Django, le domaine est noyé dans le framework. L'hexagonale dit l'inverse : le domaine ne connaît pas le framework.

NestJS rend ça naturel grâce à son injection de dépendances native :

// 1. Port (interface) — dans domain/
export interface ParkingPlaceRepository {
  findByZone(zoneId: string): Promise<ParkingPlace[]>;
  updateStatus(placeId: string, status: PlaceStatus): Promise<void>;
}

// 2. Domaine — AUCUN import NestJS
export class ParkingService {
  constructor(private readonly repo: ParkingPlaceRepository) {}
  async getOccupancy(zoneId: string) {
    return this.repo.findByZone(zoneId);
  }
}

// 3. Adaptateur — dans infrastructure/
@Injectable()
export class PostgresParkingRepo implements ParkingPlaceRepository {
  async findByZone(zoneId: string) { /* PostgreSQL + PostGIS */ }
}

// 4. NestJS câble le tout
@Module({
  providers: [
    ParkingService,
    { provide: 'ParkingPlaceRepository', useClass: PostgresParkingRepo },
  ],
})
export class ParkingModule {}
Enter fullscreen mode Exit fullscreen mode

Compatibilité framework :

Framework DI natif Hexagonale-friendly Notes
NestJS Oui ✅ Excellent Modules, providers, DI — conçu pour ça
Spring Boot Oui ✅ Excellent @bean, @Autowired, interfaces
.NET Core Oui ✅ Excellent IServiceCollection, interfaces
FastAPI Partiel ⚠️ Possible avec discipline Pas de vrai conteneur DI
Express.js Non ⚠️ Difficile Utiliser tsyringe ou inversify
Django Non ❌ Pénible ORM profondément couplé
Laravel Oui (Service Container) ⚠️ Possible mais rare Communauté Active Record

Sources architecture


7. Équipe, budget & planning

Durée totale du projet : ~6 mois (Sprint 0 à Sprint 3) soit 21 semaines. Phase pilote (500 places) livrée en 9 semaines (Sprint 0+1). Équipe de 10 personnes dont 5.5 ETP en Sprint 0-1, montant à 7.5 ETP en Sprint 2-3.

Composition de l'équipe

Rôle Nb Profil TJM Affectation Sprints
Product Owner 1 Chef de projet Direction Mobilités 650 € 50% S0 → S3
Scrum Master 1 Coach agile certifié PSM II 600 € 50% S0 → S3
Tech Lead / Architecte 1 Senior 8+ ans, hexagonale/DDD 750 € 100% S0 → S3
Dev fullstack senior 1 5+ ans, NestJS/React/TypeScript 550 € 100% S0 → S3
Dev fullstack junior 1 2+ ans, React/TypeScript 350 € 100% S1 → S3
Dev IoT / backend 1 3+ ans, Python/FastAPI, MQTT 550 € 100% S0 → S3
Dev mobile 1 3+ ans, React Native, offline 500 € 100% S2 → S3
DevOps / SRE 1 3+ ans, Docker, GitLab CI, Prometheus 600 € 50% S0 → S3
UX/UI Designer 1 3+ ans, data viz, responsive 450 € 50% S0 → S1 (ponctuel)
QA / Testeur 1 2+ ans, E2E, tests de charge 400 € 50% S1 → S3
Total 10 5.5 → 7.5 ETP 21 semaines

Outils

Catégorie Outil Coût/an
Gestion projet Jira / Azure DevOps ~3 000 €
Documentation Confluence / SharePoint Inclus
Communication Microsoft Teams Existant DSI
Code source + CI/CD GitLab (self-hosted) Existant DSI
Design Figma ~800 €
Modélisation Draw.io / PlantUML Gratuit
Tests Jest + Cypress + K6 Gratuit (OSS)
Monitoring Prometheus + Grafana + ELK Gratuit (self-hosted)

Budget prévisionnel

Poste Sprint 0-1 (3 mois) Sprint 2-3 (3 mois) Total année 1
Ressources humaines 148 500 € 198 000 € 346 500 €
Infrastructure cloud 8 000 € 12 000 € 20 000 €
Capteurs IoT (500 magnétiques + 10 ultrasons) 40 500 € 40 500 €
Gateways LoRaWAN (3 × 500 € + install) 3 000 € 3 000 €
Licences & outils 2 000 € 2 000 € 4 000 €
Installation terrain (carottage, pose, câblage) 25 000 € 25 000 €
Formation agents 5 000 € 5 000 €
Contingence 15% 34 050 € 32 550 € 66 600 €
TOTAL 261 050 € 249 550 € 510 600 €

Planning macro — 21 semaines (~6 mois)

Phase Durée Équipe Livrables Jalon
Sprint 0 — Cadrage 3 sem. 5 pers. Archi validée, POC MQTT→BDD, environnements, backlog Go/No-Go COPIL
Sprint 1 — MVP 6 sem. 7 pers. Occupation temps réel, dashboard CRU, alertes (500 places) Démo + déploiement pilote
Sprint 2 — Mobile 6 sem. 9 pers. App mobile agents (offline), interventions, push, reporting Formation agents terrain
Sprint 3 — Scale 6 sem. 9 pers. App citoyenne, ML prédictif, scaling 5k places Bilan COPIL final

ROI estimé

Gains annuels : revenus stationnement +25% rotation (~200k €/an) + réduction maintenance (-60% temps détection ~30k €/an) + réduction coordination manuelle (~50k €/an) = ~280k €/an. Investissement 510k € → ROI positif dès la 2e année.


8. Faisabilité technique

Analyse par critère

Critère Exigence Solution Risque
Haute dispo SLA 99.9% Réplication PostgreSQL, cluster MQTT (EMQX), Redis Sentinel, Docker health checks 🟠 Moyen
Performance <200ms, 500 trames/s Redis cache statuts, TimescaleDB séries tempo, CQRS 🟢 Faible
Volumétrie 500→50k places Partitionnement géo PostgreSQL, pagination API, scaling vertical puis horizontal 🟠 Moyen
Sécurité RGPD, intégrité TLS 1.3, mTLS MQTT, AES-256, WAF, SAST/DAST CI/CD 🟢 Faible
Résilience Mode dégradé Circuit breaker, retry backoff, cache fallback, mode offline mobile 🟢 Faible

Matrice des risques

Risque Prob. Impact Criticité Mitigation
Panne massive capteurs Moy. Élevé 🟠 Haute Mode dégradé, alertes préventives, stock remplacement
Surcharge broker MQTT Faible Élevé 🟠 Haute Cluster EMQX, throttling, file tampon
Faille sécurité Moy. Critique 🔴 Critique mTLS, WAF, pen testing, SAST/DAST
Latence 4G agents Élevée Moyen 🟠 Haute Mode offline, cache SQLite local
Résistance changement Élevée Moyen 🟠 Haute Formation, accompagnement, feedback

Estimation charges (3 points)

Formule : E = (TO + 4×TM + TP) / 6

Module Optimiste Probable Pessimiste Estimé (j)
Module Parking 15 22 35 23
Module IoT 12 18 30 19
Module Alertes 10 15 25 16
Module Auth 8 12 18 12
Frontend 20 30 45 31
Infra 8 12 20 13
Total 73 109 173 114 j

9. Choix technologiques

Composant Technologie Justification Alternatives écartées
Frontend Web React 18 + TypeScript Écosystème mature, WebSocket temps réel, typage sécurisé Vue.js, Angular
Mobile agents React Native Partage code React, GPS/caméra natif, offline SQLite Flutter, natif
Backend NestJS (Node.js + TS) Hexagonale native (modules, DI), I/O non-bloquante, TS E2E Django (GIL), Spring Boot (surcoût)
Module IoT Python / FastAPI Libs ML (pandas, scikit-learn) pour prédictif, async, paho-mqtt Go (ML limité)
BDD PostgreSQL 16 + PostGIS Requêtes géospatiales, JSONB, streaming replication, OSS MySQL (pas PostGIS), SQL Server (licence)
Time-series TimescaleDB Extension PostgreSQL (même stack), compression, requêtes temporelles InfluxDB (langage proprio)
Cache Redis 7 Statuts <1ms, pub/sub dashboards, Sentinel HA Memcached
Broker MQTT EMQX MQTT 5.0, clustering natif, bridge, millions connexions, OSS Mosquitto (pas cluster), HiveMQ (licence)
Conteneurisation Docker + Docker Compose App indépendante → Compose suffit. Pas besoin de K8s K8s (surdimensionné), bare metal
CI/CD GitLab CI/CD lint→tests→SAST/DAST→Docker→deploy, registre intégré GitHub Actions, Jenkins
Monitoring Prometheus + Grafana Métriques temps réel, alerting, dashboards Datadog (coût), New Relic
Logs ELK Stack Centralisation, full-text search, rétention Loki

API REST — Endpoints principaux

GET    /api/v1/zones                        → Zones + taux occupation
GET    /api/v1/zones/:id/places              → Places (statut temps réel)
GET    /api/v1/places/nearest?lat=X&lng=Y    → Places libres proches (PostGIS)
POST   /api/v1/places/:id/status             → MAJ manuelle (agent)
WS     /ws/occupancy                         → Stream temps réel
GET    /api/v1/alerts                        → Liste alertes
POST   /api/v1/alerts/:id/acknowledge        → Prise en charge
POST   /api/v1/interventions/:id/report      → Rapport agent (photo, commentaire)
Enter fullscreen mode Exit fullscreen mode

Topics MQTT

smartpark/zones/{zoneId}/places/{placeId}/status   → Trame capteur
smartpark/zones/{zoneId}/places/{placeId}/health   → Santé capteur
smartpark/alerts/anomaly                            → Anomalie détectée
smartpark/agents/{agentId}/notifications            → Push agents
Enter fullscreen mode Exit fullscreen mode

10. Synthèse

Architecture recommandée : Hexagonale (Ports & Adapters) — Application indépendante

SmartPark est une application autonome, pas un système distribué. L'hexagonale offre le meilleur compromis : domaine métier isolé (testable sans infra), technologies interchangeables (changer de BDD ou de broker sans toucher la logique), complexité maîtrisée (pas de réseau distribué), et évolutivité (nouveaux ports pour s'intégrer à d'autres modules Smart City). Déploiement via Docker Compose, pas besoin de Kubernetes.

En résumé :

  • Domaine — Entités métier pures (Place, Zone, Capteur, Alerte, Intervention). Règles centralisées. Zéro dépendance technique.
  • Ports — Interfaces entrantes (ParkingUseCase, SensorUseCase, AlertUseCase) et sortantes (Repositories, NotificationPort, GeoSpatialPort).
  • Adaptateurs — REST/WebSocket (NestJS), MQTT (EMQX), PostgreSQL+PostGIS, TimescaleDB, Redis, Email/SMS/Push.
  • Déploiement — Docker Compose. CI/CD GitLab. Scaling vertical puis horizontal si besoin.

Feuille de route

  • Sprint 0 — POC capteurs MQTT → BDD, validation archi hexagonale, environnements
  • Sprint 1 — MVP : occupation temps réel + dashboard CRU + alertes (500 places pilote)
  • Sprint 2 — App mobile agents + interventions + mode offline
  • Sprint 3 — App citoyenne, ML prédictif, scaling 5k places
  • Sprint 4+ — Ports d'intégration vers autres modules Smart City

SmartPark — Dossier d'Avant-Projet — Application Indépendante
Architecture Hexagonale (Ports & Adapters) · Docker · NestJS · PostgreSQL · MQTT

Top comments (0)