← Tous les projets

Mobile App

WashFamily

Application mobile Flutter de location de lave-linge entre particuliers. En cours de développement — réservation de créneaux, gestion des disponibilités et multi-authentification via Firebase.

FlutterDartFirebaseRiverpodGoRouter
WashFamily

Contexte

🚧 Projet en cours de développement — WashFamily est actuellement en cours de développement actif. Les fonctionnalités décrites ci-dessous reflètent l'état d'avancement actuel du projet.

WashFamily est une application mobile de location de lave-linge entre particuliers. L'idée : permettre à des propriétaires de machines à laver de les mettre à disposition de leur entourage ou de leurs voisins, et à des locataires sans équipement de réserver un créneau directement depuis leur téléphone.

C'est un projet personnel développé en autonomie, de la conception de l'architecture à la mise en production des règles Firestore. Il couvre l'intégralité du cycle d'une application mobile moderne : authentification multi-méthode, gestion de rôles, réservation avec disponibilités en temps réel et interface d'administration.

Fonctionnalités

Côté utilisateur

  • Authentification complète — email/mot de passe, numéro de téléphone (OTP), connexion Google, configuration de profil à la première connexion
  • Catalogue de laveries — liste des machines disponibles avec localisation, programmes disponibles et options de service (pliage, ramassage, livraison)
  • Réservation d'un créneau — sélection de la date, du programme de lavage et des options, récapitulatif avant confirmation
  • Suivi des réservations — historique complet avec statuts (en attente, confirmé, en cours, terminé, annulé)
  • Messagerie — échange de messages entre locataire et propriétaire
  • Boutique — achat de produits complémentaires (lessive, assouplissant…)
  • Profil utilisateur — gestion du compte, préférences et données personnelles

Côté propriétaire (owner)

  • Gestion de la laverie — création et configuration des machines et programmes
  • Validation des réservations — acceptation ou refus des demandes entrantes
  • Suivi des réservations reçues — tableau de bord avec toutes les réservations actives et passées

Panneau d'administration

  • Gestion des abonnements — suivi et validation des abonnements propriétaires
  • Gestion des produits — catalogue de la boutique
  • Tableau de bord — vue d'ensemble de l'activité

Stack technique

Flutter          Framework mobile multiplateforme (Android + iOS)
Dart             Langage principal
Firebase Auth    Authentification (email, téléphone, Google, OTP)
Cloud Firestore  Base de données temps réel (NoSQL)
Firebase Rules   Sécurisation des accès côté Firestore
Riverpod         Gestion d'état (providers générés par code)
GoRouter         Navigation déclarative avec redirection d'auth
build_runner     Génération de code (providers .g.dart, router .g.dart)

Architecture

Le projet suit un pattern Feature-First couplé à une architecture en couches data / domain / presentation :

lib/src/
  core/
    router_config.dart       — Navigation globale (GoRouter + StatefulShellRoute)
    theme/
      app_colors.dart        — Palette de couleurs
      app_text_styles.dart   — Typographie
      app_theme.dart         — Thème Material global
      app_spacing.dart       — Espacements

  features/
    authentication/          — Connexion, inscription, OTP, profil
    home/                    — Écran principal, carte des laveries
    booking/                 — Réservation, suivi, calendrier de disponibilités
    admin/                   — Tableau de bord administrateur

Chaque feature respecte la structure :

feature/
  data/
    providers/       — Riverpod providers (+ fichiers .g.dart générés)
    repositories/    — Accès Firestore (lecture, écriture, streaming)
    services/        — Logique d'appel Firebase Auth
  domain/
    models/          — Modèles de données (UserModel, ReservationModel…)
  presentation/
    screens/         — Écrans Flutter
    widgets/         — Composants UI réutilisables

Modèle de données (Firestore)

LaundryModel (laundries/{id})
  └── MachineModel (laundries/{id}/machines/{id})
        └── WashProgram (liste embarquée dans MachineModel)

ReservationModel (reservations/{id})
  ├── machineId
  └── laundryId       ← dénormalisé pour simplifier les requêtes

UserModel (users/{id})
  ├── role            ← "user" | "owner" | "admin"
  └── profile data

CartItem (panier local, géré par Riverpod)

Les options de service (pliage, ramassage, livraison) sont portées par LaundryModel, pas par MachineModel, afin de centraliser la configuration au niveau de la laverie plutôt que de chaque machine.

GoRouter avec un StatefulShellRoute pour la barre de navigation à 5 onglets :

/home        — Accueil (carte et liste des laveries)
/shop        — Boutique
/bookings    — Réservations
/messages    — Messagerie
/profile     — Profil

La redirection d'authentification est gérée automatiquement : toute route privée non authentifiée redirige vers /login, et un utilisateur déjà connecté qui tente d'accéder à /login est renvoyé vers /home.

Ce que j'ai appris

WashFamily a été mon premier projet Flutter d'envergure — et la première fois que j'ai eu à concevoir l'intégralité d'un système : schéma de données, règles de sécurité, gestion des rôles, navigation, état global et interface.

La génération de code avec Riverpod et GoRouter a été une découverte marquante : définir des providers avec des annotations et laisser build_runner générer le code boilerplate change profondément la façon d'organiser l'état dans une application Flutter. L'approche feature-first m'a également appris à compartimenter clairement les responsabilités, ce qui rend le projet navigable même quand le nombre de fichiers augmente.

La modélisation Firestore a été le défi le plus structurant : NoSQL impose de dénormaliser certaines données (comme laundryId dans chaque réservation) pour rendre les requêtes efficaces, et les règles de sécurité côté serveur demandent une réflexion différente de celle qu'on aurait avec une API REST classique.

Projet suivant

Analyse du temps d'écran des enfants.