.claude/skills/do-domain/SKILL.md
Implement business logic for a domain
npx skillsauth add viqueen/claude-go-playground .claude/skills/do-domainInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Implement the business logic for a domain. This PR is auditable as: "Is the logic correct?"
Depends on: do-entity-store agent PR (gen/db/ must exist).
All file paths are relative to the chosen project: connect-rpc-backend/ or grpc-backend/.
The user will specify which project. All make commands must be run from the project root.
The user will specify:
content)internal/domain/<domain>/errors.goSentinel errors for the domain:
package <domain>
import "errors"
var (
ErrNotFound = errors.New("<domain> not found")
ErrAlreadyExists = errors.New("<domain> already exists")
// ... domain-specific errors
)
internal/domain/<domain>/events.goEvent type constants for outbox events. These are shared between the domain ops and the outbox mapEvent — never hardcode event type strings.
package <domain>
const (
EventCreated = "<domain>.created"
EventUpdated = "<domain>.updated"
EventDeleted = "<domain>.deleted"
// ... additional events for cascade side-effects
)
internal/domain/<domain>/service.goService interface + private struct + constructor:
package <domain>
type Service interface {
Create(ctx context.Context, params db<domain>.Create<Resource>Params) (*db<domain>.<Resource>, error)
Get(ctx context.Context, id uuid.UUID) (*db<domain>.<Resource>, error)
List(ctx context.Context, pageSize int32, pageToken string) ([]db<domain>.<Resource>, string, error)
Update(ctx context.Context, id uuid.UUID, params db<domain>.Update<Resource>Params) (*db<domain>.<Resource>, error)
Delete(ctx context.Context, id uuid.UUID) error
}
type Dependencies struct {
Pool *pgxpool.Pool
Queries *db<domain>.Queries
Cache cache.Cache[uuid.UUID, *db<domain>.<Resource>]
Outbox outbox.Outbox[pgx.Tx]
}
func New(deps Dependencies) Service {
return &service{ /* inline deps */ }
}
internal/domain/<domain>/op_<operation>.go — One file per operationEach write operation:
pgerrcode.UniqueViolation to ErrAlreadyExists when the SQL schema has unique constraints (use github.com/jackc/pgerrcode — never hardcode postgres error codes)Cascade deletes (e.g., deleting a parent soft-deletes children):
Each read operation:
pgx.ErrNoRows → ErrNotFoundService interface is public, service struct is privateDependenciesop_create.go, op_get.go, op_list.go, op_update.go, op_delete.goevents.go, use in ops — never hardcode event type stringsQueries used directlygen/db/<domain>, pkg/cache, pkg/outbox, pkg/paginationgen/sdk/, internal/api/, internal/outbox/, cmd/pkg/pagination.DecodePageToken and pkg/pagination.NextPageToken for list operations — do NOT duplicate pagination logic in domain packagesmake vet — fix all compilation errorsop_*.go follows the transaction + outbox + cache patternerrors.go with domain-specific sentinel errorsevents.go with event type constants (Event*) — used by ops and outboxservice.go with interface, Dependencies, constructorop_*.go per operationevents.go (not hardcoded strings)pgerrcode.UniqueViolation → ErrAlreadyExists when unique constraints existpkg/pagination (not local helpers)pgx.ErrNoRows mapped to ErrNotFoundinternal/api/, internal/outbox/, cmd/, or gen/sdk/make vet passestesting
Review a test PR
tools
Review a search indexing PR
tools
Review a scaffold PR
tools
Review a proto PR