Skill: architecture
What I do
I enforce clean architecture: layer separation (domain → service → repository → handler), dependency direction (inward only), and boundary rules that keep the codebase maintainable as it grows.
When to use me
- Designing new packages, intents, or modules
- Reviewing code for layer boundary violations
- Deciding where new logic belongs (domain vs service vs handler)
- Structuring Go projects with clean dependency flow
- Diagnosing tight coupling or circular dependencies
Core principles
- Dependencies point inward — Domain knows nothing about HTTP, databases, or frameworks
- Layer isolation — Each layer has a single responsibility; no layer skipping
- Interface boundaries — Layers communicate through interfaces defined by the consumer
- Domain is king — Business rules live in domain; everything else is infrastructure
- Package by feature — Group by capability (
user/, order/), not by type (models/, handlers/)
Patterns & examples
Layer responsibilities:
| Layer |
Responsibility |
Depends on |
Example |
| Domain |
Business rules, entities, value objects |
Nothing |
User, Email, validation |
| Service |
Orchestration, use cases |
Domain |
RegisterUser, PlaceOrder |
| Repository |
Data persistence (interface) |
Domain |
UserRepository interface |
| Handler |
HTTP/CLI transport |
Service |
POST /users handler |
| Infrastructure |
Framework adapters |
Domain interfaces |
GORM repo, SMTP sender |
Dependency flow in Go:
// domain/ — no imports from other layers
type User struct {
ID string
Email string
Name string
}
type UserRepository interface {
Save(ctx context.Context, user *User) error
FindByEmail(ctx context.Context, email string) (*User, error)
}
// service/ — depends only on domain
type UserService struct {
repo domain.UserRepository // interface, not concrete
}
func (s *UserService) Register(ctx context.Context, email, name string) error {
user := &domain.User{Email: email, Name: name}
return s.repo.Save(ctx, user)
}
// handler/ — depends on service
func (h *Handler) RegisterUser(w http.ResponseWriter, r *http.Request) {
// Decode request, call service, encode response
err := h.svc.Register(r.Context(), req.Email, req.Name)
}
// infrastructure/ — implements domain interfaces
type GORMUserRepo struct{ db *gorm.DB }
func (r *GORMUserRepo) Save(ctx context.Context, u *domain.User) error { ... }
Package structure (feature-based):
intent/
├── user/
│ ├── domain/ # entities, value objects, interfaces
│ ├── service/ # use cases
│ ├── repository/ # data access implementation
│ └── handler/ # HTTP handlers
├── order/
│ ├── domain/
│ ├── service/
│ └── ...
Boundary validation checklist:
- Domain imports: only stdlib (
fmt, errors, time)
- Service imports: domain only
- Handler imports: service only (never domain directly for persistence)
- Repository imports: domain (for interfaces/entities) + infrastructure (GORM, etc.)
Anti-patterns to avoid
- ❌ Handler calling repository directly — Skips business logic; service layer exists for a reason
- ❌ Domain importing infrastructure — Domain must not know about GORM, HTTP, or external services
- ❌ Circular dependencies — Package A imports B, B imports A; restructure with interfaces
- ❌ God package — Single
models/ package with everything; package by feature instead
- ❌ Leaking implementation — Returning GORM models from service layer; map to domain types
KB Reference
~/vaults/baphled/3. Resources/Knowledge Base/AI Development System/Skills/Domain-Architecture/Architecture.md
Related skills
domain-modeling - Designing entities and value objects in the domain layer
service-layer - Orchestrating use cases in the service layer
design-patterns - Patterns that support architectural boundaries
clean-code - Code quality within each layer
modular-design - Unit-level composability and testability within each layer
1---2name: architecture-103description: Enforce architectural patterns and layer boundaries4---5
6# Skill: architecture
7
8## What I do
9
10I enforce clean architecture: layer separation (domain → service → repository → handler), dependency direction (inward only), and boundary rules that keep the codebase maintainable as it grows.
11
12## When to use me
13
14- Designing new packages, intents, or modules
15- Reviewing code for layer boundary violations
16- Deciding where new logic belongs (domain vs service vs handler)
17- Structuring Go projects with clean dependency flow
18- Diagnosing tight coupling or circular dependencies
19
20## Core principles
21
221. **Dependencies point inward** — Domain knows nothing about HTTP, databases, or frameworks
232. **Layer isolation** — Each layer has a single responsibility; no layer skipping
243. **Interface boundaries** — Layers communicate through interfaces defined by the consumer
254. **Domain is king** — Business rules live in domain; everything else is infrastructure
265. **Package by feature** — Group by capability (`user/`, `order/`), not by type (`models/`, `handlers/`)
27
28## Patterns & examples
29
30**Layer responsibilities:**
31
32| Layer | Responsibility | Depends on | Example |
33|-------|---------------|------------|---------|
34| Domain | Business rules, entities, value objects | Nothing | `User`, `Email`, validation |
35| Service | Orchestration, use cases | Domain | `RegisterUser`, `PlaceOrder` |
36| Repository | Data persistence (interface) | Domain | `UserRepository` interface |
37| Handler | HTTP/CLI transport | Service | `POST /users` handler |
38| Infrastructure | Framework adapters | Domain interfaces | GORM repo, SMTP sender |
39
40**Dependency flow in Go:**
41```go
42// domain/ — no imports from other layers
43type User struct {
44 ID string
45 Email string
46 Name string
47}
48
49type UserRepository interface {
50 Save(ctx context.Context, user *User) error
51 FindByEmail(ctx context.Context, email string) (*User, error)
52}
53
54// service/ — depends only on domain
55type UserService struct {
56 repo domain.UserRepository // interface, not concrete
57}
58
59func (s *UserService) Register(ctx context.Context, email, name string) error {
60 user := &domain.User{Email: email, Name: name}
61 return s.repo.Save(ctx, user)
62}
63
64// handler/ — depends on service
65func (h *Handler) RegisterUser(w http.ResponseWriter, r *http.Request) {
66 // Decode request, call service, encode response
67 err := h.svc.Register(r.Context(), req.Email, req.Name)
68}
69
70// infrastructure/ — implements domain interfaces
71type GORMUserRepo struct{ db *gorm.DB }
72func (r *GORMUserRepo) Save(ctx context.Context, u *domain.User) error { ... }
73```
74
75**Package structure (feature-based):**
76```
77intent/
78├── user/
79│ ├── domain/ # entities, value objects, interfaces
80│ ├── service/ # use cases
81│ ├── repository/ # data access implementation
82│ └── handler/ # HTTP handlers
83├── order/
84│ ├── domain/
85│ ├── service/
86│ └── ...
87```
88
89**Boundary validation checklist:**
90- Domain imports: only stdlib (`fmt`, `errors`, `time`)
91- Service imports: domain only
92- Handler imports: service only (never domain directly for persistence)
93- Repository imports: domain (for interfaces/entities) + infrastructure (GORM, etc.)
94
95## Anti-patterns to avoid
96
97- ❌ **Handler calling repository directly** — Skips business logic; service layer exists for a reason
98- ❌ **Domain importing infrastructure** — Domain must not know about GORM, HTTP, or external services
99- ❌ **Circular dependencies** — Package A imports B, B imports A; restructure with interfaces
100- ❌ **God package** — Single `models/` package with everything; package by feature instead
101- ❌ **Leaking implementation** — Returning GORM models from service layer; map to domain types
102
103## KB Reference
104
105`~/vaults/baphled/3. Resources/Knowledge Base/AI Development System/Skills/Domain-Architecture/Architecture.md`
106
107## Related skills
108
109- `domain-modeling` - Designing entities and value objects in the domain layer
110- `service-layer` - Orchestrating use cases in the service layer
111- `design-patterns` - Patterns that support architectural boundaries
112- `clean-code` - Code quality within each layer
113- `modular-design` - Unit-level composability and testability within each layer