Communitygithub.com

lguidolin/graphql-contract-testing

À utiliser lors de l'écriture d'une requête/mutation GraphQL partagée entre l'UI et un test, ou pour construire des tests de contrat de routes/schéma ou des tests de fumée. Symptômes — copie d'une requête dans un test, test qui vérifie le texte de la requête, changement de schéma qui n'a pas cassé la build UI, ou dérive RLS/permissions.

Qu'est-ce que graphql-contract-testing ?

Cette compétence pour agents IA (Claude Code, Cursor, etc.) implémente une stratégie de test de contrat GraphQL qui agit comme un filet de sécurité entre le schéma backend et les consommateurs frontend. Elle repose sur un principe fondamental : ne jamais dupliquer les requêtes GraphQL — chaque opération est écrite une seule fois comme document typé, importé à la fois par l'UI et les tests. Cette approche garantit que tout changement de schéma (renommage, suppression de champ) casse la build TypeScript immédiatement, bien avant qu'un utilisateur ne voie une erreur. La compétence couvre également les tests de contrat de routes (smoke tests) qui vérifient que chaque route s'affiche sans erreur et contient les éléments minimaux requis. Le tout est renforcé par `graphql-codegen` contre le schéma live et des tests runtime exécutés avec différents rôles RLS, permettant de détecter aussi bien les dérives de schéma que les problèmes de permissions. L'objectif est de remplacer les tests fragiles qui comparent du texte de requête par des tests robustes qui vérifient des contrats de forme et d'accès.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/lguidolin/agent-skills/tree/main/skills/graphql-contract-testing

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Test de contrat GraphQL

Vue d'ensemble

Des tests qui se situent sur la jointure entre les couches et cassent lorsqu'un côté bouge sans le consentement de l'autre — tests-comme-contrôle appliqué aux frontières. La règle cardinale : vérifiez le contrat — la forme des données et la sémantique d'accès dont dépend le consommateur — jamais la chaîne de la requête elle-même. Un test qui casse sur une modification cosmétique de requête est un anti-patron de détection de changement ; un test qui casse lorsque la forme garantie ou la permission bouge est un contrôle.

§1 — Le contrat de requête GraphQL

  • Chaque opération est écrite une seule fois comme document typé dans un emplacement connu, exportée pour être importée. L'UI l'importe ; le test importe le même artefact — jamais une copie retapée. Copier une requête dans un test tue silencieusement le contrat (modifier la requête UI ne casse plus le test). DRY devient porteur de charge.
  • Il casse dans les deux directions, par construction :
    • Dérive DB → UI, au moment de la compilation. graphql-codegen génère des types TypeScript à partir du schéma live. Renommer ou supprimer un champ utilisé et tsc échoue sur chaque utilisation et le document partagé — la build casse avant qu'un utilisateur ne voie un panneau vide. C'est pourquoi le codegen contre le schéma live est obligatoire.
    • Dérive UI → DB / permission, au moment de l'exécution. Le document partagé s'exécute contre une base de test ensemencée via le chemin d'appel réel, sous un contexte de rôle, en vérifiant la forme retournée et le résultat d'accès — pas le texte de la requête.
  • Les tests de contrat et la matrice de rôles RLS sont le même harnais. Exécutez le document unique via PostGraphile en tant que rôle A (données attendues) et rôle B (refus/vide attendus). Un mécanisme prouve trois choses : la requête correspond toujours au schéma, les hypothèses UI tiennent toujours, le RLS applique toujours la frontière.

Exemple concret — comment un vrai bug est attrapé

  • DB→UI : une migration supprime equipment.is_active. Codegen regénère à partir du nouveau schéma ; le type généré perd le champ ; tsc échoue sur le document partagé et chaque composant qui l'utilise — attrapé à la build, avant le merge. Aucun test ne vérifie "texte de requête == X."
  • UI→DB : un développeur élargit la requête UI pour inclure cancellation_reason (RLS l'expose uniquement aux rôles élevés). Le test runtime exécuté en tant que membre simple vérifie la forme visible pour le membre, obtient maintenant null/refus, et échoue — forçant "avions-nous l'intention d'exposer ceci ?"

§2 — Tests de contrat de route et de fumée

  • Routes énumérées à partir d'une source unique. Chaque route a un test de fumée : s'affiche sans erreur + affiche un ensemble minimal d'éléments requis (un titre, un repère, un contrôle clé — pas une interaction détaillée).
  • Ajouter/supprimer une route force un changement de test correspondant — une nouvelle URL est incomplète sans son test de fumée ; une URL supprimée supprime son test. Les URL n'apparaissent ni ne disparaissent silencieusement.
  • Explicitement PAS des tests détaillés UI/interaction — délibérés, de portée limitée. La question est "cette URL fonctionne-t-elle et affiche-t-elle l'essentiel," rien de plus.

Application : graphql-codegen + tsc en CI (bloquant) pour la partie compilation ; tests runtime de contrat + tests de fumée de route en CI contre une base de données ensemencée.

Raisonnement complet : Article XV de la constitution, regroupé dans engineering-constitution/references/engineering-constitution.md.

Individual skills in this repo

This repo contains 18 individual skills — each has its own dedicated page.

lguidolin/change-hygiene-and-code-craft

Use when writing or refactoring code, structuring a commit or PR, or deciding whether to abstract duplication. Symptoms — mixing reorg with logic changes, a PR doing several things at once, a file growing large, the second copy of similar code, or unsure whether to DRY something up.

lguidolin/cloud-delivery-aks

Use when deploying to Kubernetes or Azure Kubernetes Service (AKS), configuring cloud secrets, setting up progressive rollout/canary, per-PR ephemeral environments, or k8s health probes. Keywords — Kubernetes, AKS, Key Vault, Argo Rollouts, Flagger, canary, blue-green, liveness, readiness, PodDisruptionBudget, HPA, rollback, GHCR.

lguidolin/commit-history-rewrite

Use when an existing repository has messy commit history that needs to conform to conventional commits before adopting release-please, or when intermediate WIP/fixup/merge commits need to be cleaned up.

lguidolin/conventional-commits-and-releases

Use when committing, writing a commit message, opening a PR that will be squash-merged, or configuring automated versioning/changelogs. Keywords — conventional commits, release-please, semver, feat/fix/chore, breaking change, changelog.

lguidolin/defense-in-depth-security

Use when handling untrusted input, secrets, authentication/authorization, or dependencies — or threat-modeling a new surface. Keywords — STRIDE, threat model, least privilege, secrets management, supply chain, dependency scanning, input validation, audit log, defense in depth.

lguidolin/designing-before-building

Use when starting a feature, fixing a non-trivial bug, or about to write implementation code — before any code exists. Symptoms you need this: "this is simple, I'll just code it", reaching for the editor before a design is approved, or an idea that hasn't been turned into a spec and plan.

lguidolin/engineering-constitution

Use when starting work in a project that follows the engineering constitution, orienting to its rules, or deciding which engineering practice applies to a task — spec writing, commits, testing, security, deploys, database, or UI work.

lguidolin/init-repo-CI

Use when setting up a new repository with conventional commits, release-please, and CI automation, or when retrofitting an existing repository that lacks automated versioning and PR validation workflows.

lguidolin/interface-craft-and-accessibility

Use when building or styling UI — components, layouts, forms, design tokens — or making accessibility decisions. Keywords — a11y, WCAG, keyboard navigation, focus state, contrast, design system, minimalist UI, component reuse, ARIA, semantic HTML.

lguidolin/merge-gates-and-automation

Use when setting up or changing CI, pre-push hooks, or a task runner, or deciding what must pass before merge. Symptoms — tempted to put authoritative checks only in a local hook, skip CI, bypass with --no-verify, or unsure what gates a merge vs. runs locally.

lguidolin/observability-and-slos

Use when adding logging, metrics, tracing, health checks, SLOs, or alerting — or when building a service surface that needs to be operable and debuggable. Keywords — structured logs, OpenTelemetry, correlation id, RED metrics, liveness, readiness, SLI, SLO, error budget, alerting.

lguidolin/performance-and-scale

Use when working on hot paths, list endpoints, pagination, data-access in loops, or public interfaces/schemas. Symptoms — unbounded queries, N+1 access, no latency budget, optimizing without measuring, or changing an interface many consumers depend on. Keywords — pagination, N+1, Hyrum's Law, performance budget, bundle size.

lguidolin/postgres-postgraphile-rls-and-sql

Use when writing PostgreSQL, PostGraphile config, Row-Level Security policies, SQL schema files, or working on the Browser→App→PostGraphile→Postgres data path. Keywords — RLS, SECURITY DEFINER, search_path, pgSettings, grants, roles, GraphQL depth limit, query cost, statement_timeout, SQL file organization.

lguidolin/recording-decisions

Use when a design or architecture decision has been made and needs to be captured — writing a decision record or ADR, updating a decision index, noting a deferred idea, or superseding a past decision. Keywords — ADR, decision record, rationale, rejected alternatives, dependency index.

lguidolin/resilience-and-deploy-safety

Use when planning a deploy, designing a rollback, or responding to an incident or writing a postmortem. Keywords — deploy safety, rollback, immutable artifact, progressive delivery, canary, blast radius, incident response, blameless postmortem, error budget.

lguidolin/ship-it

Use when the user wants to ship work — push, PR, archive decision records, merge, and clean up. Handles the full lifecycle from committing final changes through post-merge cleanup including converting specs/plans to compact decision records.

lguidolin/tests-as-a-control

Use when writing or modifying tests, when a test breaks during a refactor, or when testing permission/role rules. Symptoms — tempted to edit a test to make it pass, testing only the happy path, a deny-test that started passing, flaky tests, or unsure what to assert.

lguidolin/zero-downtime-migrations

Use when changing a database schema where data must survive the change — adding/removing/renaming columns, constraints, indexes, or backfilling. Symptoms — a destructive migration bundled with a code deploy, a NOT NULL column with a backfill, a table-locking UPDATE, or a rename. Keywords — expand/contract, parallel change, backfill, NOT VALID, CREATE INDEX CONCURRENTLY, graphile-migrate.

Skills associés