Communitygithub.com

lguidolin/graphql-contract-testing

Use when writing a GraphQL query/mutation that the UI and a test will share, or building route/schema contract or smoke tests. Symptoms — copying a query into a test, a test asserting on query text, schema change that didn't break the UI build, or RLS/permission drift. Keywords — graphql-codegen, typed document, contract test, route smoke test.

graphql-contract-testing 是什么?

graphql-contract-testing is a Claude Code agent skill that use when writing a GraphQL query/mutation that the UI and a test will share, or building route/schema contract or smoke tests. Symptoms — copying a query into a test, a test asserting on query text, schema change that didn't break the UI build, or RLS/permission drift. Keywords — graphql-codegen, typed document, contract test, route smoke test.

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/lguidolin/agent-skills/tree/main/skills/graphql-contract-testing

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

GraphQL Contract Testing

Overview

Tests that sit on the seam between layers and break when either side moves without the other's consent — tests-as-a-control applied to boundaries. The cardinal rule: assert on the contract — the data shape and access semantics the consumer depends on — never on the query string itself. A test that breaks on a cosmetic query edit is a change-detector anti-pattern; a test that breaks when the guaranteed shape or permission moves is a control.

§1 — The GraphQL Query Contract

  • Every operation is authored once as a typed document in a known location, exported to be imported. The UI imports it; the test imports the exact same artifact — never a re-typed copy. Copying a query into a test silently kills the contract (editing the UI query no longer breaks the test). DRY made load-bearing.
  • It breaks in both directions, by construction:
    • DB → UI drift, at compile time. graphql-codegen generates TypeScript types from the live schema. Rename or drop a used field and tsc fails on every usage and the shared document — build breaks before a user sees a blank panel. This is why codegen-against-live-schema is mandatory.
    • UI → DB / permission drift, at runtime. The shared document runs against a seeded test DB through the real call path, under role context, asserting on the returned shape and access outcome — not the query text.
  • Contract tests and the RLS role matrix are the same harness. Run the one document through PostGraphile as role A (expect data) and role B (expect denied/empty). One mechanism proves three things: query still matches schema, UI assumptions still hold, RLS still enforces the boundary.

Worked example — how a real bug gets caught

  • DB→UI: a migration removes equipment.is_active. Codegen regenerates from the new schema; the generated type loses the field; tsc fails on the shared document and every component using it — caught at build, before merge. No test asserts "query text == X."
  • UI→DB: a dev widens the UI query to pull cancellation_reason (RLS exposes it only to elevated roles). The runtime test running as a plain member asserts the member-visible shape, now gets null/denied, and fails — forcing "did we mean to expose this?"

§2 — Route Contract and Smoke Tests

  • Routes enumerated from a single source. Each route has a smoke test: renders without error + shows a minimal required element set (a heading, a landmark, a key control — not detailed interaction).
  • Adding/removing a route forces a matching test change — a new URL is incomplete without its smoke test; a removed URL removes its test. URLs never appear or vanish silently.
  • Explicitly NOT detailed UI/interaction testing — deliberate, scope-limited. The question is "does this URL work and render the essentials," nothing more.

Enforcement: graphql-codegen + tsc in CI (blocking) for the compile-time half; runtime contract + route smoke tests in CI against a seeded DB.

Full rationale: Article XV of the constitution, bundled at 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.

相关技能