Files
argoyle 84b18860b5
Unbound Release / Check Preconditions (push) Successful in 34s
Unbound Release / Create Release (push) Skipped
schemas / vulnerabilities (push) Successful in 1m9s
schemas / check-release (push) Successful in 57s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 39s
Unbound Release / Create Tag (push) Successful in 33s
Release / release (push) Successful in 1m25s
schemas / check (push) Successful in 1m34s
pre-commit / pre-commit (push) Successful in 3m17s
schemas / build (push) Successful in 6m34s
schemas / deploy-prod (push) Successful in 1m11s
refactor: migrate eventsourced to codeberg and go-messaging-amqp (#949)
2026-09-16 16:52:14 +00:00

4.8 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

This is a GraphQL schema registry service that manages federated GraphQL schemas for microservices. It allows services to publish their subgraph schemas and provides merged supergraphs with Cosmo Router configuration for federated GraphQL gateways.

Architecture

Event Sourcing

The system uses event sourcing via codeberg.org/eventsourced. Key domain aggregates are:

  • Organization (domain/aggregates.go): Manages organizations, users, and API keys
  • SubGraph (domain/aggregates.go): Tracks subgraph schemas with versioning

All state changes flow through events (domain/events.go) and commands (domain/commands.go). The EventStore persists events to PostgreSQL, and events are published to RabbitMQ for downstream consumers.

GraphQL Layer

  • Schema: graph/schema.graphqls defines the API
  • Resolvers: graph/schema.resolvers.go implements mutations/queries
  • Generated Code: graph/generated/ and graph/model/ (auto-generated by gqlgen)

The resolver (graph/resolver.go) coordinates between the EventStore, Publisher (RabbitMQ), Cache, and PubSub for subscriptions.

Schema Merging

The sdlmerge/ package handles GraphQL schema federation:

  • Merges multiple subgraph SDL schemas into a unified supergraph
  • Uses wundergraph/graphql-go-tools for AST manipulation
  • Removes duplicates, extends types, and applies federation directives

Authentication & Authorization

  • Auth0 JWT (middleware/auth0.go): Validates user tokens from Auth0
  • API Keys (middleware/apikey.go): Validates service API keys
  • Auth Middleware (middleware/auth.go): Routes auth based on context

The @auth directive controls field-level access (user vs organization API key).

Cosmo Router Integration

The service generates Cosmo Router configuration (graph/cosmo.go) using the wgc CLI tool installed in the Docker container. This config enables federated query execution across subgraphs.

PubSub for Real-time Updates

graph/pubsub.go implements subscription support for schemaUpdates, allowing clients to receive real-time notifications when schemas change.

Commands

Code Generation

# Generate GraphQL server code (gqlgen), format, and organize imports
go generate ./...

Always run this after modifying graph/schema.graphqls. The go:generate directives are in:

  • graph/resolver.go: runs gqlgen, gofumpt, and goimports
  • ctl/ctl.go: generates genqlient client code

Testing

# Run all tests
go test ./... -v

# Run tests with race detection and coverage (as used in CI)
CGO_ENABLED=1 go test -race -coverprofile=coverage.txt -covermode=atomic ./...

# Run specific package tests
go test ./middleware -v
go test ./graph -v -run TestGenerateCosmoRouterConfig

# Run single test
go test ./cmd/service -v -run TestWebSocket

Building

# Build the service binary
go build -o service ./cmd/service/service.go

# Build the CLI tool
go build -o schemactl ./cmd/schemactl/schemactl.go

# Docker build (multi-stage)
docker build -t schemas .

The Dockerfile runs tests with coverage before building the production binary.

Running the Service

# Start the service (requires PostgreSQL and RabbitMQ)
go run ./cmd/service/service.go \
  --postgres-url="postgres://user:pass@localhost:5432/schemas?sslmode=disable" \
  --amqp-url="amqp://user:pass@localhost:5672/" \
  --issuer="your-auth0-domain.auth0.com"

# The service listens on port 8080 by default
# GraphQL Playground available at http://localhost:8080/

Using the schemactl CLI

# Publish a subgraph schema
schemactl publish \
  --api-key="your-api-key" \
  --schema-ref="production" \
  --service="users" \
  --url="http://users-service:8080/query" \
  --sdl=schema.graphql

# List subgraphs for a ref
schemactl list \
  --api-key="your-api-key" \
  --schema-ref="production"

Development Workflow

  1. Schema Changes: Edit graph/schema.graphqls → run go generate ./...
  2. Resolver Implementation: Implement in graph/schema.resolvers.go
  3. Testing: Write tests, run go test ./...
  4. Pre-commit: Hooks run go-mod-tidy, goimports, gofumpt, golangci-lint, and tests

Key Dependencies

  • gqlgen: GraphQL server generation
  • genqlient: GraphQL client generation (for ctl package)
  • eventsourced: Event sourcing framework
  • wundergraph/graphql-go-tools: Schema federation and composition
  • wgc CLI: Cosmo Router config generation (Node.js tool)
  • Auth0: JWT authentication
  • OpenTelemetry: Observability (traces, metrics, logs)

Important Files

  • gqlgen.yml: gqlgen configuration
  • graph/tools.go: Declares build-time tool dependencies
  • .pre-commit-config.yaml: Pre-commit hooks configuration
  • cliff.toml: Changelog generation config