Architecture interne : patterns, modélisation des données et extensibilité dans Mes Recettes

Vue en couches de l’architecture Mes Recettes (Blazor + Supabase)

Architecture interne : patterns, modélisation des données et extensibilité dans Mes Recettes

Partie 2 sur 3 de la série Mes Recettes : Partie 1 – Aperçu · Partie 3 – Tests & Livraison | English

Vue en couches

Les premières itérations restent légères, mais la conception s’oriente vers une architecture « clean » pragmatique :

P a g f M P e S u o S o s e t d D s r u è K t & v r l S g i e C u r C c R s l p e o e e i a S m s c d e b Q p i e n a L o ( p t s s A e d e | a u S o n t v m t h c a s , ) i n B e l a | z o r

Composition des composants

App.razorMainLayout → pages (Recipes.razor, Books.razor, Authors.razor) + composants de dialogue pour le CRUD.

Avantages :

  • Style de layout partagé
  • Création/édition via dialogues (rapidité perçue)
  • Espace pour injecter plus tard des préoccupations transverses (chargement, notifications)

Stratégie de modélisation des données

Mappage direct table ↔ modèle via attributs :

Concept Table Relation
Auteur authors M:N avec Books
Livre books 1:N Recettes, M:N Auteurs
Recette recettes FK Livre optionnelle
BookAuthor books_authors Table de jonction

Diagramme simplifié :

C h a i f l A m d i a U p r s T s s t E : t _ U _ n R n a a m m e e M : N ( L l I i V a R i E s _ A n U ) T E U R C h M a : m i n r b N p d a a o R s m t o E : e i k C n _ E g i T d L 1 T I : E V N o R p E t i o n n e l )

Approche de validation

  • DataAnnotations assurent cohérence UI + serveur.
  • Tests unitaires valident les bornes (ex. note).
  • Plus tard : couche FluentValidation si règles contextuelles.

Patterns documentés (durcissement futur)

Pattern Pourquoi Quand l’activer
Repository Changer de stockage, mocking aisé Quand la logique grossit
Unit of Work Grouper transactions Si modifications multi-entités
Décorateur de cache Réduire lectures répétées Après identification des hotspots
Specification Requêtes complexes Quand conditions combinées répétées

Exemple : Repository (différé)

public class SupabaseRepository<T> : IRepository<T> where T : BaseModel, new()
{
    private readonly SupabaseClient _client;
    public async Task<List<T>> GetAllAsync() =>
        (await _client.From<T>().Get()).Models ?? new();
}

Non activé pour éviter l’abstraction prématurée.

Temps réel & réhydratation

Supabase Realtime est pré‑activé (AutoConnectRealtime = true). Une fois abonné :

  1. Écoute INSERT/UPDATE/DELETE
  2. Mise à jour UI optimiste
  3. Réconciliation optionnelle après refetch silencieux

Points d’extensibilité

Extension Point d’ancrage
Mode hors ligne Service worker / cache stockage local
Recherche Full‑text PostgreSQL + index
Thème Service de palette MudBlazor
Journal d’audit Triggers BD → table append-only
Analytics Bus d’événements minimal

Compromis

Décision Avantage Inconvénient
Modèle direct ↔ table Simplicité, vitesse Couplage schéma
Service layer minimale Itération rapide Injection transverses plus difficile
Supabase BaaS Auth + Realtime + DB packagés Surface fixée par le fournisseur
100% WASM Déploiement CDN, faible coût Bundle initial plus lourd, pas de prerender

Stratégie de migration (si besoin)

  1. Ajouter un serveur (ASP.NET) pour prerender + endpoints protégés.
  2. Extraire des services métier dédiés.
  3. Ajouter un broker messages si collaboration s’intensifie.
  4. Passer progressivement du client direct aux services médiateurs.

Checklist futur

  • RLS (propriété par utilisateur)
  • Repository/cache seulement si métriques favorables
  • Flags de fonctionnalités simples
  • Suivi dérive schéma BD (diff CI)
  • Budget taille bundle (< 2 Mo compressé)

Source : https://github.com/mongeon/RecettesIndex



Suggestions de lecture :