Qualité et livraison : tests, sécurité, performance et CI dans Mes Recettes

Piliers Qualité & Livraison : Tests · Sécurité · Performance · CI/CD

Qualité et livraison : tests, sécurité, performance et CI dans Mes Recettes

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

Philosophie de test

Focus actuel : exactitude des modèles & règles de validation. Portée réduite = moins de fragilité tout en protégeant les invariants.

Couche Statut Notes
Validation modèle Implémentée Bornes de note, champs requis
Relations Implémentées Intégrité Livre–Auteur–Recette
Tests flux auth À faire Mock auth Supabase
Tests d’intégration Prévu Schéma Supabase de staging
Tests composants UI Différé Quand la logique interactive augmentera

Exemple validation de note

[Theory]
[InlineData(1,true)]
[InlineData(5,true)]
[InlineData(0,false)]
[InlineData(6,false)]
public void Rating_Range_Validation(int value, bool expected)
{
    var recipe = new Recipe { Name = "Test", Rating = value };
    var ctx = new ValidationContext(recipe);
    var results = new List<ValidationResult>();
    var valid = Validator.TryValidateObject(recipe, ctx, results, true);
    Assert.Equal(expected, valid);
}

Posture de sécurité (actif + prévu)

Sujet Approche
Auth Supabase GoTrue (email/mot de passe)
Transport HTTPS via hébergeur/CDN
RLS Patterns de politiques rédigés
Validation entrée Encodage + DataAnnotations
Gestion secrets Clés via configuration (env vars en CI plus tard)
Moindre privilège Politiques BD limiteront la visibilité

Exemple conceptuel RLS :

ALTER TABLE recettes ENABLE ROW LEVEL SECURITY;

CREATE POLICY select_own ON recettes
  FOR SELECT USING (auth.uid() = user_id);

(Suppose une colonne user_id — migration à ajouter.)

Stratégie performance

Domaine Mesure
Taille bundle Tree-shaking, chargement différé futur
Sur‑fetch Pagination + .Range()
Appels dupliqués Décorateur cache mémoire
Latence perçue UI optimiste, squelettes
Recherche Index GIN + vecteur full‑text

Index planifié :

CREATE INDEX idx_recipes_search ON recettes USING gin(
  to_tsvector('english', name || ' ' || coalesce(notes,''))
);

Pattern de cache (prévu)

public class CachedRecipeService : IRecipeService
{
    private readonly IRecipeService _inner;
    private readonly IMemoryCache _cache;
    public async Task<List<Recipe>> GetRecipesAsync() =>
        await _cache.GetOrCreateAsync("recipes_all", _ => _inner.GetRecipesAsync());
}

Activé après justification métrique.

Schéma CI/CD

Étapes pipeline :

  1. Restore
  2. Build
  3. Test
  4. (Futur) Lint & scan sécurité
  5. Publish static
  6. Déploiement CDN

Extrait workflow :

- name: Test
  run: dotnet test --no-build --verbosity normal

Extensions possibles : couverture, SAST, audit dépendances, diff schéma BD.

Feuille de route observabilité

Couche Court terme Long terme
Logs Console + devtools Logs structurés externes
Metrics Timings manuels Export OpenTelemetry
Erreurs Error boundary Blazor Pipeline centralisé
Perf front Lighthouse local Seuils automatisés CI

Cibles de déploiement

Initial : GitHub Pages / Azure Static Web Apps.
Futur : Serveur minimal si SSR ou endpoints protégés requis.

Risques condensés

Risque Mitigation
Dérive schéma vs docs Notes migrations /docs
Couplage fournisseur Abstraction progressive
Logique UI non testée Ajouter tests composants
Cas limites refresh token Surveiller logs, gérer explicitement

Prochaines actions qualité

  1. Ajouter RLS + colonne user_id
  2. Intégration test Supabase jetable
  3. Badge couverture
  4. Error boundary + logging dialogues

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



Suggestions de lecture :