This file provides comprehensive guidance for AI agents working with this Go-based SQLC demo application.
The repository currently contains:
- Domain models in
internal/domain/(business entities with value objects) - Port interfaces in
internal/port/(repository interface definitions) - SQL queries in
internal/db/queries/for SQLC code generation - Database schema migrations in
internal/migrations/ - Complete SQLC configuration with type mappings
- Repository skill for guided implementation in
.crush/skills/repository/ - Generated repository files were deleted - use
/generate-repository <domain>to generate them
The internal/repository/ and internal/db/ directories are currently empty of Go files after cleanup.
Key Technologies:
- Go 1.25
- SQLC for database code generation
- PostgreSQL with pgx/v5 driver
- Testcontainers for integration testing
- Domain-driven design with hexagonal architecture
- Crush AI Assistant with repository skill for guided code generation
After cleanup, the recommended workflow is:
- Regenerate Repository Code: Run
/generate-repository <domain>to create repository files for any domain model - Verify Generation: Check that files are created in
internal/db/andinternal/repository/ - Build and Test: Ensure
go build ./...succeeds andmake testpasses - Clean Dependencies: Run
go mod tidyto remove unused dependencies
sqlc generate # Generate Go code from SQL queries
make sqlc # Same as above (via Makefile)go build . # Build the whole project
go build ./... # Build all packages
make build # Build via Makefile
make test # Run all tests with race detection and coverage
go mod tidy # Clean up dependenciesgh api -H "Accept: application/vnd.github.raw" repos/nikolayk812/sqlcpp/contents/path/to/file.go
# Fetch reference files from the main sqlcpp repository./cleanup.sh # Delete all generated Go files in internal/db and internal/repository.crush/
└── skills/
└── repository/ # Repository implementation skill and guidance
internal/
├── domain/ # Business models/entities (Cart, Money)
├── port/ # Repository interfaces (hexagonal architecture ports)
├── repository/ # Repository implementations
├── db/ # SQLC-generated queries and models
│ └── queries/ # SQL query files for SQLC
└── migrations/ # Database schema migration files
Domain Layer (internal/domain/)
- Contains pure business logic and entities
- No dependencies on persistence or external concerns
- Uses value objects with proper type safety (e.g., Money with decimal.Decimal and currency.Unit)
Port Layer (internal/port/)
- Defines repository interfaces
- Follows hexagonal architecture port concept
- Interface naming:
<Domain>Repositorypattern
Database Layer (internal/db/)
- Contains SQLC-generated code
- SQL queries live in
internal/db/queries/ - Generated models are called "records" (different from domain models)
- Never edit generated files directly
Repository Layer (internal/repository/)
- Implements port interfaces
- Maps between SQLC records and domain models
- Handles database transactions when multiple queries needed
- Uses dependency injection pattern with constructors
Migration Layer (internal/migrations/)
- SQL schema migration files
- Named with incrementing numbers:
01_<table_name>.up.sql - Used by SQLC to understand database schema
- Applied automatically in test setup
Skill Layer (.crush/skills/repository/)
- Contains repository implementation guidance and patterns
- Provides structured approach to implementing repository layer
- Includes mapping conventions, transaction handling, and error patterns
- Constructor Pattern: Create constructors for both
*pgxpool.Poolandpgx.Tx - Domain Model Mapping: Repository methods must accept/return only domain models, never SQLC records
- Transaction Handling:
- Single SQLC query: avoid
withTxmethod - Multiple SQLC queries: use proper
withTxXYZmethod
- Single SQLC query: avoid
- Struct Initialization: Initialize structs with 4+ fields before calling methods
- Reference Implementation: Follow patterns in
internal/repository/order_repository.gofrom main sqlcpp repo
When generating repository code:
- Run
sqlc generatefirst - Add generated SQLC files to context
- Reference domain models and port interfaces
- Use GitHub reference files for implementation patterns
- Create both repository and test files
- Ensure compilation with
go build ./... - Verify tests pass with
make test
- Integration Tests: Use Testcontainers with real PostgreSQL
- Test Database: Automatically configured with schema migrations
- Test Naming:
<domain>_repository_test.go - Reference: Follow patterns from
order_repository_test.goin main repo
overrides:
- db_type: "uuid" → github.com/google/uuid.UUID
- db_type: "numeric" → github.com/shopspring/decimal.Decimal
- db_type: "timestamp" → time.Time- Use
-- name: QueryName :returntypeformat :manyfor SELECT returning multiple rows:execfor INSERT/UPDATE/DELETE:execrowsfor DELETE with row count return- Use
ON CONFLICTfor upsert operations
github.com/jackc/pgx/v5 # PostgreSQL driver
github.com/shopspring/decimal # Decimal arithmetic
github.com/google/uuid # UUID handling
github.com/testcontainers/testcontainers-go/modules/postgres # Testing
github.com/stretchr/testify # Test assertions
github.com/brianvoe/gofakeit/v7 # Test data generation
golang.org/x/text # Currency handling
- PostgreSQL database (handled via testcontainers in tests)
- Docker (required for testcontainers)
- SQLC CLI tool (installed via
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest)
- Special Docker socket override:
TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock - Race detection enabled in tests
- Coverage reporting enabled
- Domain models: PascalCase (e.g.,
Order,Product) - Repository interfaces:
<Domain>Repository - Repository implementations:
<domain>Repository - Test files:
<domain>_repository_test.go - SQL files: lowercase with underscores (e.g.,
order.sql)
- Use Go standard formatting (gofmt)
- Import ordering: standard library, third party, local
- Error handling: always handle errors, use descriptive messages
- Context: always accept
context.Contextas first parameter in repository methods
- Table names: snake_case (e.g.,
order_items) - Column names: snake_case (e.g.,
owner_id,product_id) - Primary keys: composite where logical (e.g.,
owner_id, product_id) - Indexes: descriptive names (e.g.,
idx_order_items_owner) - Timestamps: use
TIMESTAMP DEFAULT CURRENT_TIMESTAMP
Use Claude Code's custom command:
/generate-repository <domain>
This command (defined in .claude/commands/generate-repository.md):
- Runs
sqlc generatecommand to generate SQLC code - Adds generated SQLC files to context
- Adds domain model and port interface files to context
- Creates or modifies
internal/repository/repository_test.gofor testcontainer setup - Creates
internal/repository/{domain}_repository_test.gofor integration tests - Creates
internal/repository/{domain}_repository.gofor implementation - Organizes imports with
goimports - Ensures compilation with
go build ./... - Verifies tests pass with
make test - References implementation patterns from main sqlcpp repo
The repository skill (.crush/skills/repository/) provides:
- Core principles for repository implementation
- Constructor patterns and method structures
- Transaction handling guidance
- Error handling patterns
- Mapping conventions between SQLC records and domain models
The project references implementation patterns from:
https://github.com/nikolayk812/sqlcpp/blob/main/internal/repository/repository_test.gohttps://github.com/nikolayk812/sqlcpp/blob/main/internal/repository/order_repository.gohttps://github.com/nikolayk812/sqlcpp/blob/main/internal/repository/order_repository_test.go
Access the repository skill for guided implementation:
- File:
.crush/skills/repository/SKILL.md - Provides step-by-step guidance for implementing repositories
- Includes mapping conventions and error handling patterns
- Follows hexagonal architecture principles
- Always run
sqlc generateafter changing SQL files or migrations - Generated files should never be edited manually
- SQLC reads migration files to understand schema
- Don't mix domain models with SQLC records
- Always map between record and domain model types
- Use transactions only when calling multiple SQLC queries
- Repository constructors must support both pool and transaction
- Tests require Docker for testcontainers
- Database schema applied automatically from migrations
- Integration tests run against real PostgreSQL instances
- Use
make testnotgo testto get proper Docker socket configuration
- Only add dependencies that exist in main sqlcpp repo
- Run
go mod tidyafter adding dependencies - Check main repo's go.mod for version compatibility
GitHub Actions workflow (.github/workflows/test.yml):
- Runs on Ubuntu with Go 1.25
- Installs SQLC CLI tool
- Generates code before testing
- Runs full test suite with proper environment
The workflow ensures:
- Code generation works
- All tests pass
- Build succeeds
- Dependencies are correctly managed