Back to skills
SKILL.md
Add Domain Entity
ASecurityCreate domain layer components: models, repository interfaces, marshallers, and implementations. Use when: (1) adding domain model in internal/domain/model/, (2) creating repository interface in internal/domain/repository/, (3) implementing repository with marshaller in internal/infrastructure/{db}/. This is Step 2 of CRUD workflow (after add-database-table, before add-api-endpoint).
- 666 stars
- 0 votes
- 0 copies
- 0 views
- Added September 2, 2026
Works with
Security analysis
100/100npx -y skills add majiayu000/claude-skill-registry --skill add-domain-entity --agent claude-codeAre you the author of Add Domain Entity?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/majiayu000-add-domain-entity-claude-skill-registry)---
name: add-domain-entity
description: |
Create domain layer components: models, repository interfaces, marshallers, and implementations.
Use when: (1) adding domain model in internal/domain/model/, (2) creating repository interface in internal/domain/repository/, (3) implementing repository with marshaller in internal/infrastructure/{db}/.
This is Step 2 of CRUD workflow (after add-database-table, before add-api-endpoint).
---
# Add Domain Entity
Create domain layer components for a new entity following DDD patterns.
## Prerequisites
- Database table created (use **add-database-table** skill first)
- SQLBoiler model generated via `make migrate.up`
## Quick Workflow
```
1. Domain Model → internal/domain/model/{entity}.go
2. Domain Error → internal/domain/errors/errors.go
3. Repository Interface → internal/domain/repository/{entity}.go
4. Marshaller → internal/infrastructure/{db}/internal/marshaller/{entity}.go
5. Repository Impl → internal/infrastructure/{db}/repository/{entity}.go
6. Generate Mocks → make generate.mock
```
## Step 1: Create Domain Model
Location: `internal/domain/model/{entity}.go`
Create the entity struct, constructor, update methods, and type aliases.
Key requirements:
- Use `id.New()` for ID generation in constructor
- Set both `CreatedAt` and `UpdatedAt` to the same time parameter
- Define `ReadonlyReference` for relations (always nil in constructor)
- Create slice type alias: `type Examples []*Example`
See: [references/domain-model-patterns.md](references/domain-model-patterns.md)
## Step 2: Add Domain Error
Location: `internal/domain/errors/errors.go`
Add a not-found error for the entity:
```go
ExampleNotFoundErr = NewNotFoundError("E2xxxxx", "Example not found")
```
Follow error code conventions from `.claude/rules/domain-errors.md`.
## Step 3: Create Repository Interface
Location: `internal/domain/repository/{entity}.go`
Define the repository interface with standard CRUD operations and query structs.
Key requirements:
- Add `//go:generate` directive for mock generation
- Use `nullable.Type[T]` for optional enum/custom type filter fields
- Embed `BaseGetOptions` / `BaseListOptions` in query structs
See: [references/repository-patterns.md](references/repository-patterns.md)
## Step 4: Create Marshaller
Location: `internal/infrastructure/{mysql|postgresql|spanner}/internal/marshaller/{entity}.go`
Convert between DB models and domain models.
Key requirements:
- Related entity's `ReadonlyReference` must remain nil (no recursive loading)
- Use var declaration pattern for nullable timestamp fields
- Include both `ToModel` and `ToDBModel` functions
See: [references/marshaller-patterns.md](references/marshaller-patterns.md)
## Step 5: Create Repository Implementation
Location: `internal/infrastructure/{mysql|postgresql|spanner}/repository/{entity}.go`
Implement the repository interface using SQLBoiler.
Key requirements:
- Use `transactable.GetContextExecutor(ctx)` for all DB operations
- Implement `buildListQuery` helper for reusable filter logic
- Implement `buildPreload` helper for relation loading
- Use base helper functions: `addForUpdateFromBaseGetOptions`, `addForUpdateFromBaseListOptions`
See: [references/repository-patterns.md](references/repository-patterns.md)
## Step 6: Generate Mocks
```bash
make generate.mock
```
This generates mock implementations in `internal/domain/repository/mock/`.
## Checklist
### Domain Model
- [ ] Entity struct with all fields
- [ ] `ReadonlyReference` for relations (if any)
- [ ] Constructor with `id.New()` and `ReadonlyReference: nil`
- [ ] Update method using `null.*` types for optional fields
- [ ] Slice type alias (`Examples []*Example`)
- [ ] Helper methods on slice (`IDs()`, `MapByID()`)
### Status/Enum Types (if needed)
- [ ] Type definition with `Unknown` as first constant
- [ ] `String()` and `Valid()` methods
- [ ] `New{Type}(str string)` constructor
### Repository
- [ ] Interface with `//go:generate` directive
- [ ] Query structs with `nullable.Type[T]` for optional enums
- [ ] Domain error added for not-found case
### Implementation
- [ ] Marshaller with `ToModel`, `ToDBModel`, `ToModels`, `ToDBModels`
- [ ] Marshaller handles `ReadonlyReference` correctly
- [ ] Repository implementation with all CRUD methods
- [ ] `buildListQuery` and `buildPreload` helpers
- [ ] Mocks generated
## Next Steps
After creating domain entity, use **add-api-endpoint** skill to create:
- Usecase input/output structs
- Interactor interface and implementation
- Protocol Buffers definition
- gRPC handler
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.