System design
Skill endorphin-ai/claude-code-teams/go-react-team/.claude/skills/system-design
System design and code review skill for fullstack Go+React apps. Use when designing architecture or reviewing code against design specifications.From its SKILL.md
npx -y skills add endorphin-ai/claude-code-teams --skill system-designAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
13.8 KB, ~3.2k tokens by cl100k_base, as published. Nobody here has run it
System Design
Purpose
This skill provides the knowledge base for designing and reviewing fullstack applications built with Go (backend) and React (frontend) with PostgreSQL as the data layer. It covers two operating modes:
- Design Mode (Phase 1): Produce a complete system design document from a PRD -- API contracts, database schema, component architecture, and Go project structure.
- Review Mode (Phase 4): Verify implemented code conforms to the design document, flagging deviations, anti-patterns, and missing pieces.
Key Patterns
1. REST API Design (OpenAPI/Swagger)
Endpoint Naming Conventions:
- Use plural nouns for resource collections:
/api/v1/users,/api/v1/projects - Use path parameters for specific resources:
/api/v1/users/{id} - Nest related resources max 2 levels deep:
/api/v1/projects/{id}/tasks - Use query parameters for filtering, sorting, pagination:
?status=active&sort=created_at&order=desc&page=1&limit=20 - API versioning in path prefix:
/api/v1/,/api/v2/ - Use kebab-case for multi-word paths:
/api/v1/user-profiles
HTTP Methods:
| Method | Purpose | Idempotent | Request Body | Success Code |
|---|---|---|---|---|
| GET | Retrieve resource(s) | Yes | No | 200 |
| POST | Create resource | No | Yes | 201 |
| PUT | Full replace | Yes | Yes | 200 |
| PATCH | Partial update | Yes | Yes | 200 |
| DELETE | Remove resource | Yes | No | 204 |
Standard Status Codes:
200 OK-- Successful GET, PUT, PATCH201 Created-- Successful POST (includeLocationheader)204 No Content-- Successful DELETE400 Bad Request-- Validation errors, malformed input401 Unauthorized-- Missing or invalid authentication403 Forbidden-- Authenticated but not authorized404 Not Found-- Resource does not exist409 Conflict-- Duplicate resource, version conflict422 Unprocessable Entity-- Semantically invalid input500 Internal Server Error-- Unexpected server failure
Standard Error Response Schema:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Human-readable description",
"details": [
{
"field": "email",
"message": "must be a valid email address"
}
]
}
}
Pagination Response Envelope:
{
"data": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 142,
"total_pages": 8
}
}
2. Database Schema Design (PostgreSQL)
Table Conventions:
- Table names: plural, snake_case (
users,project_tasks) - Column names: snake_case (
created_at,user_id) - Every table MUST have:
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() - Soft delete via
deleted_at TIMESTAMPTZcolumn (nullable, NULL = active) - Foreign keys always have explicit
ON DELETEclause (CASCADE, SET NULL, or RESTRICT) - Create indexes on: foreign keys, columns used in WHERE clauses, columns used in ORDER BY, unique constraints
Migration Conventions:
- Sequential numbered files:
001_create_users.up.sql,001_create_users.down.sql - Every UP migration has a corresponding DOWN migration
- DOWN migrations must be reversible (drop what UP created)
- Use
golang-migrate/migrateorpressly/gooseformat - Never modify existing migrations in production -- create new ones
Common Patterns:
-- Audit columns trigger
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Apply to every table
CREATE TRIGGER set_updated_at
BEFORE UPDATE ON {table_name}
FOR EACH ROW
EXECUTE FUNCTION update_updated_at();
-- Soft delete index (only index active rows)
CREATE INDEX idx_{table}_active ON {table} (id) WHERE deleted_at IS NULL;
Relationship Patterns:
- One-to-many: FK on the "many" side (
user_id UUID REFERENCES users(id)) - Many-to-many: Junction table with composite PK (
user_roleswithuser_id+role_id) - One-to-one: FK with UNIQUE constraint
- Self-referential: FK referencing same table (
parent_id UUID REFERENCES categories(id))
3. React Component Architecture
Component Hierarchy:
App
Layout
Header (auth state, navigation)
Sidebar (navigation menu)
Main
Page (route-level, fetches data)
Container (state logic, data transformation)
Presentational (UI rendering, props only)
Component Classification:
- Page Components (
pages/): Route entry points. Own data fetching via hooks. Pass data down. - Container Components (
containers/): Business logic, state management, API calls. Minimal JSX. - Presentational Components (
components/): Pure rendering. Props in, JSX out. No side effects. - Layout Components (
layouts/): Page structure (header, sidebar, footer). Renderchildren.
State Management Strategy:
- Server state: React Query / TanStack Query (caching, refetching, optimistic updates)
- Local UI state:
useState/useReducer(form inputs, toggles, modals) - Global app state: React Context (auth, theme, feature flags) -- NOT for server data
- URL state: React Router search params (filters, pagination, sort)
Props Flow Rules:
- Props flow DOWN only. Never pass setters more than 2 levels.
- If prop drilling exceeds 2 levels, extract to Context or compose with render props.
- Define explicit TypeScript interfaces for all props.
- Use
childrenfor composition over configuration.
File Naming:
- Components: PascalCase (
UserProfile.tsx,TaskList.tsx) - Hooks: camelCase with
useprefix (useAuth.ts,useTasks.ts) - Utils: camelCase (
formatDate.ts,validators.ts) - Types: PascalCase in dedicated files (
types.tsorUser.types.ts)
4. Go Project Structure
Standard Layout (handler -> service -> repository):
cmd/
server/
main.go # Entry point: config, DI, server startup
internal/
config/
config.go # Environment/config loading
handler/
user_handler.go # HTTP handlers (parse request, call service, write response)
user_handler_test.go
middleware.go # Auth, logging, CORS, recovery middleware
service/
user_service.go # Business logic (validation, orchestration, rules)
user_service_test.go
repository/
user_repository.go # Database access (queries, transactions)
user_repository_test.go
model/
user.go # Domain models (structs, enums, constants)
errors.go # Domain error types
dto/
user_dto.go # Request/response DTOs (separate from domain models)
validation.go # DTO validation rules
router/
router.go # Route definitions, middleware chaining
pkg/
response/
response.go # Standard JSON response helpers
pagination/
pagination.go # Pagination parsing and response
migrations/
001_create_users.up.sql
001_create_users.down.sql
api/
openapi.yaml # OpenAPI 3.0 specification
Layer Responsibilities:
| Layer | Does | Does NOT |
|---|---|---|
| Handler | Parse HTTP request, validate input, call service, write HTTP response | Contain business logic, access DB directly |
| Service | Business rules, validation, orchestrate repositories, error wrapping | Know about HTTP, parse requests, write responses |
| Repository | SQL queries, scan results into models, manage transactions | Contain business logic, know about HTTP |
| Model | Define domain types, constants, domain errors | Import from handler/service/repository |
| DTO | Define API request/response shapes, input validation | Contain business logic |
Dependency Direction:
handler -> service -> repository
| | |
v v v
dto model model
Handlers depend on services. Services depend on repositories. All depend on models. Never reverse this flow.
Interface Pattern (dependency injection):
// Define interface in the CONSUMER package (service defines what it needs from repo)
type UserRepository interface {
GetByID(ctx context.Context, id uuid.UUID) (*model.User, error)
Create(ctx context.Context, user *model.User) error
Update(ctx context.Context, user *model.User) error
Delete(ctx context.Context, id uuid.UUID) error
List(ctx context.Context, filter UserFilter) ([]model.User, int, error)
}
// Implement in the PROVIDER package
type userRepository struct {
db *sql.DB
}
func NewUserRepository(db *sql.DB) UserRepository {
return &userRepository{db: db}
}
Error Handling:
- Define domain errors in
model/errors.go - Services wrap repository errors with domain context
- Handlers map domain errors to HTTP status codes
- Never expose internal error details to clients
// model/errors.go
var (
ErrNotFound = errors.New("resource not found")
ErrAlreadyExists = errors.New("resource already exists")
ErrForbidden = errors.New("access denied")
)
5. API Contract Definition
Request/Response Type Rules:
- Every endpoint has explicitly defined request and response types
- Request types: only fields the client sends (no
id, nocreated_at) - Response types: what the client receives (includes
id, timestamps) - List endpoints return paginated envelope, not raw arrays
- Use
omitemptyon optional fields in Go structs - Validate requests at the handler/DTO layer, not in services
Go DTO Patterns:
// CreateUserRequest -- POST /api/v1/users
type CreateUserRequest struct {
Email string `json:"email" validate:"required,email"`
Name string `json:"name" validate:"required,min=2,max=100"`
Password string `json:"password" validate:"required,min=8"`
}
// UserResponse -- returned by all user endpoints
type UserResponse struct {
ID uuid.UUID `json:"id"`
Email string `json:"email"`
Name string `json:"name"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// ListResponse[T] -- generic paginated response
type ListResponse[T any] struct {
Data []T `json:"data"`
Pagination Pagination `json:"pagination"`
}
TypeScript API Types (frontend mirror):
// types/api.ts
interface CreateUserRequest {
email: string;
name: string;
password: string;
}
interface UserResponse {
id: string;
email: string;
name: string;
created_at: string;
updated_at: string;
}
interface PaginatedResponse<T> {
data: T[];
pagination: {
page: number;
limit: number;
total: number;
total_pages: number;
};
}
6. Code Review Patterns
Conformance Checking (Design vs Implementation):
- Every endpoint in the design doc MUST exist in the router
- Every DB table in the design doc MUST have a migration file
- Every React component in the design doc MUST exist as a file
- Request/response types MUST match the design doc field-for-field
- HTTP methods and status codes MUST match the design doc
Anti-Pattern Detection:
| Anti-Pattern | What to Flag | Correct Pattern |
|---|---|---|
| Fat handler | Business logic in handler | Move to service layer |
| Anemic service | Service just passes through to repo | Add validation/rules to service |
| Direct DB in handler | sql.DB used in handler | Use repository interface |
| God component | React component > 200 lines | Split into container + presentational |
| Prop drilling | Props passed > 2 levels | Use Context or composition |
| Raw SQL strings | Unparameterized queries | Use parameterized queries ($1, $2) |
| Missing error handling | Unchecked err returns | Always check and handle errors |
| N+1 queries | Query in a loop | Use JOINs or batch queries |
| Hardcoded config | Connection strings in code | Use environment variables |
| Missing indexes | FK columns without indexes | Add indexes on FK columns |
Severity Levels:
- CRITICAL: Security vulnerability, data loss risk, broken functionality. MUST fix before merge.
- HIGH: Design deviation, missing validation, incorrect status code. Should fix before merge.
- MEDIUM: Anti-pattern, suboptimal structure, missing index. Fix in this PR or next.
- LOW: Style issue, naming convention, minor improvement. Suggestion only.
Conventions
- API-first design: Define endpoints and contracts BEFORE writing code.
- One migration per change: Each schema change gets its own numbered migration pair.
- Interface-driven Go: Define interfaces in consumers, implement in providers.
- Strict layer separation: Handlers never import repositories. Services never import
net/http. - TypeScript strict mode: All React projects use
"strict": truein tsconfig. - Explicit error types: No generic error strings. Define typed errors in
model/errors.go. - Context propagation: Every Go function that does I/O takes
context.Contextas first parameter. - UUID primary keys: Always use UUIDs, never auto-increment integers, for all public-facing IDs.
- Timestamps are UTC: All
TIMESTAMPTZvalues stored and transmitted in UTC. - JSON field naming: Use
snake_casein JSON (Go tags + TypeScript interfaces must match).
Knowledge Strategy
- Patterns to capture: Successful API designs, reusable SQL migration templates, component tree patterns that scaled well, Go error handling chains that worked cleanly.
- Examples to collect: Complete design documents that passed review, review reports that caught real issues, migration sequences that handled complex schema evolution.
- Update permission: Agents may freely add/update files in
references/. Changes toSKILL.mdorscripts/require user approval.
What ships with it: 6 files
39.3 KB alongside SKILL.md
workflows/
- bugfix.md6.4 KB
- feature.md5.9 KB
- review.md8.0 KB
- DRY_RUN.md4.3 KB
- FORMAT.md10.6 KB
- VOICE.md4.2 KB
Gives 0 of the 12 instructions most architecture codebase skills give in ~3.2k tokens
Counted across 811 of the 1,134 authors here whose files we hold, read 2026-08-07
- Ask the user which candidate to explorein 45 of 811, across 15 files
- Apply the deletion test to suspected shallow modulesin 43 of 811, across 15 files
- Read any relevant architecture decision records firstin 31 of 811, across 8 files
- Use exact glossary terms in every suggestionin 30 of 811, across 10 files
- Accept dependencies instead of creating themin 24 of 811, across 5 files
- Include before and after visualisations for each candidatein 24 of 811, across 5 files
- Read the domain glossary before exploringin 24 of 811, across 6 files
- Return results instead of producing side effectsin 23 of 811, across 4 files
- Explore the codebase for shallow modules and frictionin 23 of 811, across 3 files
- Introduce seams only where things varyin 22 of 811, across 3 files
- Reduce the number of methodsin 21 of 811, across 2 files
- Design deep modules with small interfacesin 21 of 811, across 3 files
Said here and by no other author read
- create corresponding down migration for every up migration
- define explicit typescript interfaces for all props
- enforce strict handler to service to repository dependency flow
- use standard json response helpers
- wrap list endpoints in a paginated envelope
- validate requests at the handler or dto layer
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.