Quality & Delivery: Testing, Security, Performance, and CI in Mes Recettes

Quality & Delivery pillars: Testing · Security · Performance · CI/CD

Quality & Delivery: Testing, Security, Performance, and CI in Mes Recettes

Part 3 of 3 in the Mes Recettes series: Part 1 – Overview · Part 2 – Architecture | 🇫🇷 Version

Testing Philosophy

Current focus: model correctness & validation rules. Keeping scope narrow avoids test brittleness while still guarding domain invariants.

Layer Status Notes
Model validation Implemented Rating bounds, required fields
Relationships Implemented Book–Author–Recipe integrity
Auth flow tests TODO Mock Supabase auth
Integration tests Planned Supabase staging schema
UI component tests Deferred Add once interactive logic increases

Rating Validation Example

[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);
}

Security Posture (Planned + Active)

Concern Approach
Auth Supabase GoTrue (email/password today)
Transport HTTPS via hosting/CDN
RLS Policy patterns drafted (enforce user scoping)
Input sanitization Leverage encoding + validation
Secret handling Keys via configuration (move to env vars in CI)
Least privilege DB policies will gate row visibility

Sample RLS concept:

ALTER TABLE recettes ENABLE ROW LEVEL SECURITY;

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

(Assumes a user_id column—additive migration required.)

Performance Strategy

Early-stage guidelines:

Area Mitigation
Payload size Tree-shake, lazy future component modules
Overfetch Add pagination & range queries (Supabase .Range())
Duplicate calls Introduce in-memory cache decorator
Perceived latency Optimistic UI for inserts, skeleton placeholders
Search latency Add GIN indexes + full-text vector

Planned index example:

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

Caching Decorator Pattern (Planned)

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());
}

Activate once query counts justify.

CI/CD Blueprint

Pipeline stages:

  1. Restore
  2. Build (fail fast)
  3. Test (gate)
  4. (Future) Lint & security scan
  5. Publish static output
  6. Deploy to CDN/static host

Workflow skeleton (excerpt):

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

Add-ons to consider:

Enhancement Tooling
Code coverage coverlet + report badge
SAST CodeQL or Semgrep
Dependency audit dotnet list package --vulnerable
DB migrations diff Custom action + pg_dump

Observability Roadmap

Layer Near-Term Later
Logging Console + browser devtools Structured logs → remote sink
Metrics Manual timings in dev WASM → OpenTelemetry export (experimental)
Errors Blazor error boundary Centralized exception pipeline
Frontend perf Lighthouse local runs Automated thresholds in CI

Deployment Targets

Initial: GitHub Pages / Azure Static Web Apps (build + deploy static wwwroot).
Future: Add minimal server (hybrid hosting) if SSR, protected endpoints, or PDF generation needed.

Risk Register (Condensed)

Risk Mitigation
Schema drift vs. docs Add migration notes in /docs
Vendor coupling (Supabase) Abstract service interfaces incrementally
Growth of untested UI logic Introduce component tests when branching paths arise
Auth edge cases (token refresh) Monitor logs; add explicit refresh handling if needed

Immediate Next Quality Steps

  1. Add RLS + user_id column migrations
  2. Wire minimal integration test against throwaway Supabase project
  3. Introduce coverage reporting badge
  4. Start error boundary + logging wrapper for dialogs

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



See also