agents/openai.yaml
interface:
display_name: "Golang DDD Refactor"
short_description: "Refactor Go code into a behavior-first domain"
default_prompt: "Use $golang-ddd-refactor to refactor this Go code toward a behavior-first domain model with explicit invariants and clearer boundaries."
references/domain-rules.md
# Domain Rules
## Rule 1: Reflect Business Logic Literally
- Model behavior with business verbs such as `ScheduleTraining`, `CancelTraining`, `ApproveReschedule`.
- Prefer types with behavior over passive data containers with setters and getters.
- Ask whether a non-technical stakeholder could roughly understand the important method names.
## Rule 2: Keep A Valid State In Memory
- Validate invariants at construction time when possible.
- Keep fields private if direct mutation would bypass business rules.
- Make illegal state transitions impossible or at least explicit.
- Favor behavior methods over sequences of `if` checks in calling code.
## Rule 3: Keep The Domain Database-Agnostic
- Do not let Firestore, SQL, protobuf, or JSON tags define the shape of the domain.
- Create persistence models when storage and business needs diverge.
- Defer database decisions when the domain is still being discovered.
## Signs The Domain Is Missing
- Handlers or repositories contain large validation trees.
- Repositories know too much about business rules.
- The same struct is tagged for database and transport and also carries business logic.
- Tests need running infrastructure just to verify basic business behavior.
## Helpful Test Style
- Test exported behavior as a black box.
- Use table-driven tests for corner cases.
- Use domain-specific helpers to make scenarios readable.
- Keep domain tests free of mocks and infrastructure.
references/refactor-playbook.md
# Refactor Playbook
## Before You Move Code
- Start from one painful use case, not the whole service.
- Prefer an endpoint or command with visible business rules over a data-only read.
- Write down who can do what, when, and under which constraints.
## Migration Steps
1. Identify the behavior hidden inside a handler, service, or repository transaction.
2. Name the operation in business language.
3. Create or refine a domain type that owns the rule.
4. Move validation and state transitions into behavior methods.
5. Add or tighten constructors so invalid instances are rejected.
6. Introduce persistence mapping if the old model leaks storage concerns.
7. Replace repository business methods with load or update capabilities.
8. Add domain tests before deleting the old validation code.
9. Collapse the old handler or service into orchestration only.
## Repository Pattern Guidance
- Put repository interfaces in the package that needs them.
- Keep repository names generic enough to survive domain changes.
- Prefer methods like `Get`, `GetOrCreate`, `Update`, `Save`.
- Use `Update(ctx, id, fn)` when the repository should own the transaction and the domain should own the decision.
## Anti-Pattern Checklist
- one shared model for API, DB, and domain,
- setters and public fields controlling core state,
- repository methods mirroring every business action,
- authorization checks mixed with transport parsing,
- domain packages importing persistence or transport libraries,
- business logic tested only through slow integration tests.
## Example Direction In This Style
- `UpdateHour` with many transport-level flags becomes domain behavior like `ScheduleTraining` or `CancelTraining`.
- Reschedule approval logic moves from an application service callback into `Training.ApproveReschedule`.
- Transactional persistence stays in the repository, while the business decision lives in the closure and domain type.
SKILL.md
---
name: golang-ddd-refactor
description: "Refactor existing Go code toward a behavior-first, invariant-protecting domain model. Use when business rules live in handlers or repositories, shared structs couple DB and API models, entities expose setters or mutable public fields, or a service needs domain methods, constructors, private state, repository update closures, and focused domain tests."
user-invocable: true
license: MIT
compatibility: Designed for Codex, Claude Code, Gemini CLI, Cursor, OpenCode, and similar AI coding agents working with Go services.
metadata:
author: joeyave
version: "0.3.0"
---
# Golang DDD Refactor
Use this skill when the code already works but is becoming hard to trust, test, or extend because the business rules are scattered across transport and persistence code.
## Refactor Loop
1. Find the use case from the edge of the system.
- Start from HTTP handlers, gRPC methods, commands, repository callbacks, or transaction blocks.
- Write down the business operation in plain language before introducing any new types.
2. Extract the rules hiding inside conditionals.
- Look for "walls of `if`" that decide whether something may happen.
- Turn those rules into invariants and behavior methods on a domain type.
3. Create or tighten the domain type.
- Prefer constructors that reject invalid state.
- Prefer private fields when external mutation would bypass invariants.
- Replace setters with behavior methods named in business language.
4. Make the domain database-agnostic.
- Remove Firestore, SQL, protobuf, or HTTP concerns from domain packages.
- Introduce separate persistence models if storage shape differs from the domain shape.
5. Rebuild the repository boundary.
- Put the repository interface next to the code that consumes it.
- Prefer generic repository capabilities such as load or update over repository methods that mirror every business action.
- Use closure-based update methods when the write requires transactional read-modify-save behavior.
6. Add black-box tests around the domain.
- Test exported behavior, not private fields.
- Use helpers that create meaningful domain objects such as "available hour" or "canceled training".
- Keep mocks out of domain tests.
7. Shrink the old code paths.
- Make handlers, services, and repositories delegate to the new domain behavior.
- Delete duplicated validation once the domain enforces it reliably.
## Guardrails
- Do not invent entities and value objects unless they clarify real business behavior.
- Do not move pure transport validation into the domain unless it is a business rule.
- Do not leak database transaction types or clients into the domain.
- Do not keep public writable fields just because the old code used them.
## Use These References
- Read [references/domain-rules.md](references/domain-rules.md) for the core rules adapted for this skill pack.
- Read [references/refactor-playbook.md](references/refactor-playbook.md) for a step-by-step migration path and anti-pattern checklist.
## Deliverables
- behavior-oriented domain methods,
- constructors or factories that enforce validity,
- narrowed repository contracts,
- removed duplicated business checks from handlers or adapters,
- focused domain tests that describe the behavior in business terms.