Refactor existing packages toward the standard service/adapter pattern. Use when restructuring a domain package, splitting a monolithic package, or removing anti-patterns.
72
90%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
You are helping the user refactor existing openmeter/ packages toward the standard service/adapter pattern described in the /service skill.
See the /service skill for the full target pattern. In summary, every feature package should have:
openmeter/<domain>/
├── service.go # Service interface definition
├── adapter.go # Adapter interface definition
├── <domain>.go # Domain types and models
├── errors.go # Custom errors (optional, only when needed)
├── event.go # Domain events (optional, for packages that modify DB entities)
├── adapter/ # Adapter layer implementation (data access)
│ ├── adapter.go # Config, New(), transaction boilerplate
│ ├── <operation>.go # One file per operation (list.go, get.go, create.go, etc.)
│ └── mapping.go # Entity ↔ domain type mapping functions
├── service/ # Service layer implementation (business logic + orchestration)
│ └── service.go
├── driver/ # v1 API, do not implement for new services (also called: httpdriver, driver)
│ └── <operation>.goKey rules:
Complex domain packages with non-standard structure:
| Package | Issues |
|---|---|
subscription | 30+ files in root, logic spread across root (apply, billing, context, locks, patch), specialized subdirs (addon/, entitlement/, hooks/, patch/) |
productcatalog | 20+ files in root, multiple entity types mixed together (addon, plan, feature, discount, entitlement), inconsistent subdir naming (driver/ vs adapter/) |
billing | 20+ files in root (invoice, customer, discount, app), complex domain mixed into single package |
app | Heavy root (app, appbase, customer, marketplace, webhook, registry, input), multiple impl subdirs (stripe/, sandbox/, custominvoicing/) |
credit | Domain split across balance/, grant/, engine/ subdirs with connector pattern in root |
entitlement | Has adapter/service but also boolean/, metered/, static/, snapshot/, balanceworker/, hooks/ — uses connector pattern |
notification | Has adapter/service but also consumer/, eventhandler/, internal/ — non-standard extensions |
Partially compliant or minor structural issues:
| Package | Issues |
|---|---|
ingest | Non-standard adapter naming (ingestadapter/), mixed patterns (kafkaingest/, inmemory in root) |
streaming | Uses connector pattern, clickhouse/ impl dir, no service/adapter split |
sink | No service/adapter pattern, utility-focused with flushhandler/, models/ |
These are infrastructure, utility, or minimal packages where the pattern may not apply:
ent, watermill, dedupe, server, namespace, registry, event, apiconverter, testutils, debug, session, info
When refactoring a package toward the standard pattern:
Analyze current structure: Read the package to understand all files, types, and dependencies. Map out which code is domain types, which is business logic, and which is data access.
Identify entity boundaries: If the package mixes multiple independent entities (e.g., productcatalog has plan, addon, feature), consider splitting into separate packages first.
Extract root interfaces: Move all types, interfaces, input DTOs, and errors to the root package. Remove any implementation code from root.
Create adapter/: Move all database queries, entity mapping, and Ent ORM code into adapter/. Ensure it only does data access — no business decisions.
Create service/: Move all business logic, orchestration, and transaction wrapping into service/. This includes validation beyond simple input checks, precondition enforcement, multi-step operations, and event publishing.
Remove anti-patterns: Eliminate connectors, deep nesting, scattered types. Replace global state with constructor injection.
Update wiring: Update app/common/<domain>.go and cmd/*/wire.go to match new constructor signatures. Run make generate.
Update imports: Fix all imports across the codebase that reference moved types or functions.
Run tests: make test to verify nothing is broken.
grep to find all import paths.make generate to update wire_gen.go files.1cdc2cb
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.