api-contract-versioning
Governs API contract changes to prevent type mismatches.
Install
mkdir -p .claude/skills/api-contract-versioning && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15843" && unzip -o skill.zip -d .claude/skills/api-contract-versioning && rm skill.zipInstalls to .claude/skills/api-contract-versioning
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Shared API contract governance across server, web, and mini-program clients. Covers Zod schemas derived from Drizzle tables, DTOs in packages/shared/src/api.ts (barrel) and domain modules under packages/shared/src/api/*.ts, cross-platform type consumption, and the lightweight /api/v1/* versioning rewrite. Use when adding, changing, or reviewing a shared API type, Zod validation schema, or route payload shape consumed by more than one surface. Trigger phrases: "add a shared DTO", "change API response shape", "Zod schema drift", "safeParse validation", "cross-platform contract", "api.ts type".Key capabilities
- →Add a field to a shared API request type
- →Change an existing Zod validation schema
- →Modify DTOs in packages/shared/src/api.ts
- →Add a new API endpoint for mini-program and web clients
- →Review if a server route's response shape matches client expectation
- →Update EventPoolRegistrationPayload with a new field
How it works
This skill governs shared API contracts across server, web, and mini-program clients by managing Zod schemas, DTOs, and cross-platform type consumption. It ensures validation across all consuming platforms before merging changes.
Inputs & outputs
When to use api-contract-versioning
- →Update shared dto
- →Change api response shape
- →Fix zod schema mismatch
About this skill
api-contract-versioning
Core rule: API contracts are owned by packages/shared and consumed by the server and both clients. Changing a shared type or Zod schema is a cross-cutting change — validate all consumers before merging.
When to use this skill
- Adding, removing, or renaming a field in a shared API request/response type
- Creating a new Zod validation schema for a route payload
- Modifying an existing schema exported from
packages/shared/src/schema.ts - Changing
packages/shared/src/api.tsDTOs or theApiTransportcontract - Adding a new API endpoint that both mini-program and web will call
- Reviewing whether a server route's response shape matches the client's expectation
When NOT to use this skill
- Task is purely about internal server business logic with no exposed contract change
- Task is only about a client-local UI type that never crosses the network
- Task is about database schema evolution without API surface impact (use
database-migration-safety) - Task is about adding a new route file or domain decomposition (use
server-domain-architecture)
Shared contract layers
JoyJoin API contracts live in three layers inside packages/shared:
| Layer | Location | Purpose |
|---|---|---|
| Database + Zod schemas | packages/shared/src/schema.ts | Drizzle tables + runtime validation |
| API DTOs + transport | packages/shared/src/api.ts (barrel) and packages/shared/src/api/*.ts | TypeScript types, transport contract, domain modules |
| Domain types | packages/shared/src/types/*.ts | Cross-cutting domain types |
Versioning: The server strips /api/v1/ prefixes and routes identically to /api/*. There is no active breaking-version negotiation. Prefer additive fields with feature detection over version bumps.
For implementation details — Zod/Drizzle examples, DTO patterns, drift detection, and cross-platform consumption — see references/implementation.md.
Quick examples
User says: "I need to add a new field dietaryNotes to the event pool registration payload."
Apply this skill by:
- Add the column to
eventPoolsinpackages/shared/src/schema.ts(if persisted) - Update
insertEventPoolRegistrationSchemain the same file - Add
dietaryNotes?: string[] | nulltoEventPoolRegistrationPayloadinpackages/shared/src/api/eventPools.ts(re-exported throughpackages/shared/src/api.ts) - Run
npm run typecheckacross@joyjoin/server,@joyjoin/user-client, andmini-programResult: The contract is updated in one place and all consumers type-check together.
User says: "The server is returning a new themeEmoji field but the mini-program isn't seeing it."
Apply this skill by: Checking packages/shared/src/api/eventPools.ts for PoolGroupSummary — if themeEmoji is missing from the interface, add it there and re-export it through packages/shared/src/api.ts. Also verify apps/mini-program/src/lib/api/api.ts imports the updated type via @shared/api.
Result: Type drift is caught at the shared boundary, not at runtime in the client.
Troubleshooting
- Type mismatch between server and client after schema change — Run
npm run typecheckacross all workspaces. Fixpackages/shared/src/api.tsorschema.tsbefore checking consumers. - Zod validation rejects a payload that looks correct — Check whether the schema uses
.strict(),.omit(), or.extend()in a way that forbids the field. - Client sees
unknownfor an API response field — The field is likely not declared in the relevantpackages/shared/src/api/<domain>.tsmodule (re-exported throughpackages/shared/src/api.ts). Add it there and re-export frompackages/shared/src/index.tsif needed. - Adding a required field to a response breaks an older client — Make the field optional (
?:) in the shared DTO first, then migrate clients before making it required.
Review checklist
- Zod schema changes in
schema.tsare reflected in all serversafeParseconsumers - New or changed response fields are added to the corresponding interface in
packages/shared/src/api/<domain>.ts(and re-exported throughpackages/shared/src/api.ts) - Both web and mini-program clients import the updated type from
@shared/api - No duplicate local types were created when a shared type already exists
- Additive changes use optional fields (
?:) before making them required across all surfaces -
npm run typecheckpasses for@joyjoin/server,@joyjoin/user-client, andmini-program
When not to use it
- →Task is purely about internal server business logic with no exposed contract change
- →Task is only about a client-local UI type that never crosses the network
- →Task is about database schema evolution without API surface impact
Limitations
- →There is no active breaking-version negotiation
- →The server strips `/api/v1/` prefixes and routes identically to `/api/*`
- →Prefer additive fields with feature detection over version bumps
How it compares
This workflow centralizes API contract definitions in `packages/shared` and enforces cross-platform type-checking, preventing runtime type mismatches that manual approaches might miss.
Compared to similar skills
api-contract-versioning side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| api-contract-versioning (this skill) | 0 | 1mo | No flags | Intermediate |
| api-contract-sync-manager | 1 | 10mo | No flags | Intermediate |
| exa-upgrade-migration | 1 | 1mo | Review | Intermediate |
| obsidian-upgrade-migration | 0 | 1mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
api-contract-sync-manager
ananddtyagi
Validate OpenAPI, Swagger, and GraphQL schemas match backend implementation. Detect breaking changes, generate TypeScript clients, and ensure API documentation stays synchronized. Use when working with API spec files (.yaml, .json, .graphql), reviewing API changes, generating frontend types, or validating endpoint implementations.
exa-upgrade-migration
jeremylongshore
Analyze, plan, and execute Exa SDK upgrades with breaking change detection. Use when upgrading Exa SDK versions, detecting deprecations, or migrating to new API versions. Trigger with phrases like "upgrade exa", "exa migration", "exa breaking changes", "update exa SDK", "analyze exa version".
obsidian-upgrade-migration
jeremylongshore
Migrate Obsidian plugins between API versions and handle breaking changes. Use when upgrading to new Obsidian versions, handling API deprecations, or migrating plugin code to new patterns. Trigger with phrases like "obsidian upgrade", "obsidian migration", "obsidian API changes", "update obsidian plugin".
instantly-sdk-patterns
jeremylongshore
Apply production-ready Instantly SDK patterns for TypeScript and Python. Use when implementing Instantly integrations, refactoring SDK usage, or establishing team coding standards for Instantly. Trigger with phrases like "instantly SDK patterns", "instantly best practices", "instantly code patterns", "idiomatic instantly".
juicebox-sdk-patterns
jeremylongshore
Apply production-ready Juicebox SDK patterns. Use when implementing robust error handling, retry logic, or enterprise-grade Juicebox integrations. Trigger with phrases like "juicebox best practices", "juicebox patterns", "production juicebox", "juicebox SDK architecture".
deepgram-sdk-patterns
jeremylongshore
Apply production-ready Deepgram SDK patterns for TypeScript and Python. Use when implementing Deepgram integrations, refactoring SDK usage, or establishing team coding standards for Deepgram. Trigger with phrases like "deepgram SDK patterns", "deepgram best practices", "deepgram code patterns", "idiomatic deepgram", "deepgram typescript".