Architecture
API Internals
Module structure, code organization, and codegen tools.
API Internals
The Go API (api/) follows a vertical slice architecture — each business domain is a self-contained module.
Module Structure
api/internal/modules/
├── customers/ # Customer CRUD
├── instances/ # Instance CRUD + usage reporting
├── licenses/ # License CRUD + entitlement association
├── entitlements/ # Entitlement CRUD + values
├── featureflags/ # Feature flag CRUD + OpenFeature (OFREP)
├── deploymentzones/ # Deployment zone CRUD + deploy
├── releases/ # Release CRUD
├── identity/ # Service accounts + tokens
├── organization/ # Organization context
├── outwebhooks/ # Outgoing webhooks (Svix)
└── webhooks/ # Incoming webhooks (Clerk)Inside a Module
Each module follows the same structure:
module/
├── create{entity}/
│ ├── endpoint.go # HTTP handler registration
│ ├── endpoint_openapi.go # OpenAPI metadata
│ ├── handler.go # Business logic
│ ├── register.go # Dependency injection
│ └── repository.go # Database queries
├── get{entity}/
├── getall{entity}/
├── update{entity}/
├── delete{entity}/
├── events/
│ └── events.go # Domain event definitions
└── schema/
└── types.go # Domain types and enumsCode Generation
| Tool | Purpose | Command |
|---|---|---|
| sqlc | Type-safe SQL queries → Go structs | make sqlc |
| gqlgen | GraphQL schema → Go resolvers | make gqlgen |
| Huma v2 | Go handler annotations → OpenAPI spec | Automatic at runtime |
Key Patterns
Unit of Work (UoW)
Database operations use a Unit of Work pattern for transactional consistency. Domain writes and outbox event inserts happen in the same transaction.
Principal Context
Every request carries a Principal (UserID, OrganizationID, Scopes) extracted from the JWT. All repository queries are automatically scoped by organization_id.
Outbox Events
Mutations insert events into outbox_events in the same transaction as the domain write. Debezium CDC captures these events for downstream processing.

