swe-workflow-skills 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +144 -0
- package/VERSION +1 -0
- package/bin/cli.mjs +44 -0
- package/catalog.json +225 -0
- package/commands/role.md +34 -0
- package/hooks/session-start.mjs +118 -0
- package/install.mjs +318 -0
- package/package.json +47 -0
- package/roles.json +194 -0
- package/scripts/resolve.mjs +296 -0
- package/skills/accessibility-design/SKILL.md +128 -0
- package/skills/accessibility-design/evals/evals.json +51 -0
- package/skills/accessibility-design/references/accessibility-patterns.md +321 -0
- package/skills/api-design/SKILL.md +144 -0
- package/skills/api-design/evals/evals.json +48 -0
- package/skills/api-design/references/rest-conventions.md +147 -0
- package/skills/api-design/templates/api-spec.md +156 -0
- package/skills/architecture-design/SKILL.md +86 -0
- package/skills/architecture-design/evals/evals.json +44 -0
- package/skills/architecture-design/references/clean-architecture.md +147 -0
- package/skills/architecture-design/references/component-principles.md +129 -0
- package/skills/architecture-design/references/principles.md +81 -0
- package/skills/architecture-design/references/solid-principles.md +106 -0
- package/skills/architecture-design/templates/adr.md +63 -0
- package/skills/architecture-documentation/SKILL.md +126 -0
- package/skills/architecture-documentation/evals/evals.json +44 -0
- package/skills/architecture-documentation/references/abstraction-levels.md +91 -0
- package/skills/architecture-documentation/references/diagram-tooling.md +141 -0
- package/skills/architecture-documentation/templates/architecture-doc.md +171 -0
- package/skills/bug-investigating/SKILL.md +133 -0
- package/skills/bug-investigating/evals/evals.json +56 -0
- package/skills/bug-investigating/references/common-bugs.md +62 -0
- package/skills/bug-investigating/references/debugging-patterns.md +94 -0
- package/skills/cicd-pipeline/SKILL.md +87 -0
- package/skills/cicd-pipeline/evals/evals.json +34 -0
- package/skills/cicd-pipeline/references/pipeline-patterns.md +206 -0
- package/skills/cicd-pipeline/templates/github-actions.md +206 -0
- package/skills/code-reviewing/SKILL.md +92 -0
- package/skills/code-reviewing/evals/evals.json +62 -0
- package/skills/code-reviewing/references/error-handling.md +108 -0
- package/skills/code-reviewing/references/review-checklist.md +144 -0
- package/skills/configuration-strategy/SKILL.md +109 -0
- package/skills/configuration-strategy/evals/evals.json +41 -0
- package/skills/configuration-strategy/references/config-patterns.md +161 -0
- package/skills/containerization/SKILL.md +90 -0
- package/skills/containerization/evals/evals.json +36 -0
- package/skills/containerization/references/dockerfile-patterns.md +168 -0
- package/skills/containerization/templates/dockerfile.md +154 -0
- package/skills/data-modeling/SKILL.md +83 -0
- package/skills/data-modeling/evals/evals.json +43 -0
- package/skills/data-modeling/references/conventions.md +57 -0
- package/skills/data-modeling/templates/schema.md +120 -0
- package/skills/dependency-impact-analysis/SKILL.md +113 -0
- package/skills/dependency-impact-analysis/evals/evals.json +41 -0
- package/skills/dependency-impact-analysis/references/impact-patterns.md +150 -0
- package/skills/dependency-management/SKILL.md +161 -0
- package/skills/dependency-management/evals/evals.json +48 -0
- package/skills/dependency-management/references/evaluation-checklist.md +127 -0
- package/skills/deployment-checklist/SKILL.md +132 -0
- package/skills/deployment-checklist/evals/evals.json +58 -0
- package/skills/deployment-checklist/references/pre-deploy-gates.md +91 -0
- package/skills/deployment-repo/SKILL.md +190 -0
- package/skills/deployment-repo/evals/evals.json +44 -0
- package/skills/deployment-repo/references/deployment-repo-patterns.md +258 -0
- package/skills/deployment-repo/references/version-compatibility.md +227 -0
- package/skills/deployment-repo/templates/deployment-repo-structure.md +226 -0
- package/skills/effort-estimation/SKILL.md +95 -0
- package/skills/effort-estimation/evals/evals.json +32 -0
- package/skills/effort-estimation/references/estimation-methods.md +154 -0
- package/skills/feature-planning/SKILL.md +84 -0
- package/skills/feature-planning/evals/evals.json +44 -0
- package/skills/feature-planning/templates/plan.md +55 -0
- package/skills/feature-planning/templates/task.md +26 -0
- package/skills/frontend-architecture/SKILL.md +154 -0
- package/skills/frontend-architecture/evals/evals.json +34 -0
- package/skills/frontend-architecture/references/component-patterns.md +264 -0
- package/skills/frontend-architecture/templates/folder-structure.md +203 -0
- package/skills/git-workflow/SKILL.md +127 -0
- package/skills/git-workflow/evals/evals.json +44 -0
- package/skills/git-workflow/references/conventions.md +142 -0
- package/skills/git-workflow/templates/pull-request.md +57 -0
- package/skills/gitops-delivery/SKILL.md +319 -0
- package/skills/gitops-delivery/evals/evals.json +44 -0
- package/skills/gitops-delivery/references/gitops-patterns.md +478 -0
- package/skills/gitops-delivery/templates/gitops-config.md +196 -0
- package/skills/incident-response/SKILL.md +130 -0
- package/skills/incident-response/evals/evals.json +55 -0
- package/skills/incident-response/references/communication-templates.md +134 -0
- package/skills/incident-response/references/severity-levels.md +77 -0
- package/skills/incident-response/templates/incident-timeline.md +57 -0
- package/skills/infrastructure-as-code/SKILL.md +86 -0
- package/skills/infrastructure-as-code/evals/evals.json +33 -0
- package/skills/infrastructure-as-code/references/iac-patterns.md +179 -0
- package/skills/infrastructure-as-code/templates/terraform-module.md +158 -0
- package/skills/metrics-and-okrs/SKILL.md +113 -0
- package/skills/metrics-and-okrs/evals/evals.json +33 -0
- package/skills/metrics-and-okrs/references/metric-catalog.md +90 -0
- package/skills/metrics-and-okrs/templates/okr-document.md +61 -0
- package/skills/ml-experiment-tracking/SKILL.md +96 -0
- package/skills/ml-experiment-tracking/evals/evals.json +32 -0
- package/skills/ml-experiment-tracking/references/tracking-tools.md +127 -0
- package/skills/ml-model-deployment/SKILL.md +106 -0
- package/skills/ml-model-deployment/evals/evals.json +34 -0
- package/skills/ml-model-deployment/references/serving-patterns.md +162 -0
- package/skills/ml-pipeline-design/SKILL.md +162 -0
- package/skills/ml-pipeline-design/evals/evals.json +34 -0
- package/skills/ml-pipeline-design/references/pipeline-components.md +174 -0
- package/skills/observability-design/SKILL.md +162 -0
- package/skills/observability-design/evals/evals.json +52 -0
- package/skills/observability-design/references/logging-patterns.md +229 -0
- package/skills/observability-design/references/slo-framework.md +151 -0
- package/skills/observability-design/templates/slo-document.md +80 -0
- package/skills/performance-optimization/SKILL.md +83 -0
- package/skills/performance-optimization/evals/evals.json +47 -0
- package/skills/performance-optimization/references/bottleneck-patterns.md +256 -0
- package/skills/performance-optimization/references/concurrency.md +101 -0
- package/skills/prd-writing/SKILL.md +109 -0
- package/skills/prd-writing/evals/evals.json +33 -0
- package/skills/prd-writing/references/prd-examples.md +132 -0
- package/skills/prd-writing/templates/prd.md +71 -0
- package/skills/prd-writing/templates/rfc.md +79 -0
- package/skills/project-documentation/SKILL.md +104 -0
- package/skills/project-documentation/evals/evals.json +48 -0
- package/skills/project-documentation/references/contributing-guide.md +100 -0
- package/skills/project-documentation/templates/changelog.md +59 -0
- package/skills/project-documentation/templates/readme.md +121 -0
- package/skills/project-proposal/SKILL.md +90 -0
- package/skills/project-proposal/evals/evals.json +31 -0
- package/skills/project-proposal/references/proposal-examples.md +140 -0
- package/skills/project-proposal/templates/proposal.md +76 -0
- package/skills/project-review/SKILL.md +111 -0
- package/skills/project-review/evals/evals.json +42 -0
- package/skills/refactoring/SKILL.md +90 -0
- package/skills/refactoring/evals/evals.json +44 -0
- package/skills/refactoring/references/transformations.md +132 -0
- package/skills/retrospective/SKILL.md +157 -0
- package/skills/retrospective/evals/evals.json +34 -0
- package/skills/retrospective/references/facilitation-guide.md +130 -0
- package/skills/retrospective/templates/post-mortem.md +121 -0
- package/skills/rollback-strategy/SKILL.md +116 -0
- package/skills/rollback-strategy/evals/evals.json +55 -0
- package/skills/rollback-strategy/references/rollback-patterns.md +125 -0
- package/skills/rollback-strategy/templates/rollback-plan.md +69 -0
- package/skills/security-audit/SKILL.md +146 -0
- package/skills/security-audit/evals/evals.json +66 -0
- package/skills/security-audit/references/owasp-top-10.md +167 -0
- package/skills/security-audit/templates/security-report.md +79 -0
- package/skills/skill-router/SKILL.md +171 -0
- package/skills/skill-router/evals/evals.json +39 -0
- package/skills/strategic-review/SKILL.md +106 -0
- package/skills/strategic-review/evals/evals.json +42 -0
- package/skills/strategic-review/templates/full-review-prompt.md +84 -0
- package/skills/tdd-workflow/SKILL.md +147 -0
- package/skills/tdd-workflow/evals/evals.json +58 -0
- package/skills/tdd-workflow/references/test-quality.md +71 -0
- package/skills/technical-debt-review/SKILL.md +113 -0
- package/skills/technical-debt-review/evals/evals.json +41 -0
- package/skills/technical-debt-review/references/debt-taxonomy.md +124 -0
- package/skills/technical-debt-review/templates/debt-audit.md +85 -0
- package/skills/test-data-strategy/SKILL.md +129 -0
- package/skills/test-data-strategy/evals/evals.json +49 -0
- package/skills/test-data-strategy/references/data-generation-patterns.md +341 -0
- package/skills/test-suite-design/SKILL.md +137 -0
- package/skills/test-suite-design/evals/evals.json +69 -0
- package/skills/test-suite-design/references/test-infrastructure.md +175 -0
- package/skills/test-suite-design/references/testing-pyramid.md +140 -0
- package/skills/ui-ux-design/SKILL.md +117 -0
- package/skills/ui-ux-design/evals/evals.json +35 -0
- package/skills/ui-ux-design/references/interaction-patterns.md +145 -0
- package/skills/ui-ux-design/templates/screen-spec.md +97 -0
- package/skills/verification-before-completion/SKILL.md +85 -0
- package/skills/verification-before-completion/evals/evals.json +53 -0
- package/skills/writing-skills/SKILL.md +87 -0
- package/skills/writing-skills/evals/evals.json +41 -0
- package/skills/writing-skills/references/pressure-testing.md +69 -0
- package/uninstall.mjs +182 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# API Specification Template
|
|
2
|
+
|
|
3
|
+
```markdown
|
|
4
|
+
# [Service Name] API Specification
|
|
5
|
+
|
|
6
|
+
**Version**: v1
|
|
7
|
+
**Base URL**: `https://api.example.com/api/v1`
|
|
8
|
+
**Authentication**: Bearer token (JWT)
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
[Brief description of what this API provides and who consumes it.]
|
|
13
|
+
|
|
14
|
+
## Authentication
|
|
15
|
+
|
|
16
|
+
All endpoints except those marked as **Public** require a valid JWT in the Authorization header:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
Authorization: Bearer <token>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Common Conventions
|
|
23
|
+
|
|
24
|
+
- All timestamps are ISO 8601 in UTC
|
|
25
|
+
- All IDs are [format: UUID/ULID/integer]
|
|
26
|
+
- Pagination uses cursor-based paging with `cursor` and `limit` parameters
|
|
27
|
+
- Errors follow the standard error response format
|
|
28
|
+
|
|
29
|
+
## Error Format
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"error": {
|
|
34
|
+
"code": "ERROR_CODE",
|
|
35
|
+
"message": "Human-readable description",
|
|
36
|
+
"details": []
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## [Resource Name]
|
|
44
|
+
|
|
45
|
+
### List [Resources]
|
|
46
|
+
|
|
47
|
+
`GET /[resources]`
|
|
48
|
+
|
|
49
|
+
**Authentication**: Required
|
|
50
|
+
**Authorization**: [roles/permissions]
|
|
51
|
+
|
|
52
|
+
**Query Parameters:**
|
|
53
|
+
|
|
54
|
+
| Parameter | Type | Required | Description |
|
|
55
|
+
|-----------|------|----------|-------------|
|
|
56
|
+
| `cursor` | string | No | Pagination cursor |
|
|
57
|
+
| `limit` | integer | No | Items per page (default: 20, max: 100) |
|
|
58
|
+
| `status` | string | No | Filter by status |
|
|
59
|
+
|
|
60
|
+
**Response**: `200 OK`
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"data": [
|
|
64
|
+
{
|
|
65
|
+
"id": "res_abc123",
|
|
66
|
+
"field": "value",
|
|
67
|
+
"created_at": "2025-03-05T14:30:00Z"
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
"pagination": {
|
|
71
|
+
"next_cursor": "eyJpZCI6MTAwfQ",
|
|
72
|
+
"has_more": true
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### Get [Resource]
|
|
80
|
+
|
|
81
|
+
`GET /[resources]/:id`
|
|
82
|
+
|
|
83
|
+
**Authentication**: Required
|
|
84
|
+
|
|
85
|
+
**Response**: `200 OK`
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"data": {
|
|
89
|
+
"id": "res_abc123",
|
|
90
|
+
"field": "value",
|
|
91
|
+
"created_at": "2025-03-05T14:30:00Z"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Errors**: `404 Not Found`
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
### Create [Resource]
|
|
101
|
+
|
|
102
|
+
`POST /[resources]`
|
|
103
|
+
|
|
104
|
+
**Authentication**: Required
|
|
105
|
+
**Authorization**: [roles/permissions]
|
|
106
|
+
|
|
107
|
+
**Request Body:**
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"field": "value",
|
|
111
|
+
"other_field": "value"
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
| Field | Type | Required | Validation |
|
|
116
|
+
|-------|------|----------|------------|
|
|
117
|
+
| `field` | string | Yes | Max 255 characters |
|
|
118
|
+
| `other_field` | string | No | Must be one of: [values] |
|
|
119
|
+
|
|
120
|
+
**Response**: `201 Created`
|
|
121
|
+
|
|
122
|
+
**Errors**: `400 Validation Error`, `409 Conflict`
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
### Update [Resource]
|
|
127
|
+
|
|
128
|
+
`PATCH /[resources]/:id`
|
|
129
|
+
|
|
130
|
+
**Authentication**: Required
|
|
131
|
+
**Authorization**: [Owner or Admin]
|
|
132
|
+
|
|
133
|
+
**Request Body:** (partial — only include fields to update)
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"field": "new value"
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Response**: `200 OK`
|
|
141
|
+
|
|
142
|
+
**Errors**: `400 Validation Error`, `404 Not Found`
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### Delete [Resource]
|
|
147
|
+
|
|
148
|
+
`DELETE /[resources]/:id`
|
|
149
|
+
|
|
150
|
+
**Authentication**: Required
|
|
151
|
+
**Authorization**: [Owner or Admin]
|
|
152
|
+
|
|
153
|
+
**Response**: `204 No Content`
|
|
154
|
+
|
|
155
|
+
**Errors**: `404 Not Found`
|
|
156
|
+
```
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: architecture-design
|
|
3
|
+
description: "Guide architectural and structural decisions using Architecture Decision Records (ADRs) — new services, pattern choices, database selection, component boundaries, state management, costly-to-reverse decisions. Triggers: how should I architect, which pattern, design decision, should I use X or Y, system design, ADR, component design, architectural trade-off."
|
|
4
|
+
model: opus
|
|
5
|
+
allowed-tools: Read, Grep, Glob, Write, Edit
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Architecture Design
|
|
9
|
+
|
|
10
|
+
Help the user make well-reasoned architectural decisions and document them in Architecture Decision Records (ADRs). Good architecture is about managing trade-offs explicitly, not finding perfect solutions.
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
### Step 1: Frame the Decision
|
|
15
|
+
|
|
16
|
+
Identify the exact decision to be made. A good architectural question is specific and scoped:
|
|
17
|
+
|
|
18
|
+
- **Too broad**: "How should I design the backend?"
|
|
19
|
+
- **Right scope**: "Should user authentication be a separate microservice or a module within the monolith?"
|
|
20
|
+
|
|
21
|
+
If the user's question is too broad, help narrow it by asking:
|
|
22
|
+
- What triggered this decision? (new feature, scaling issue, tech debt)
|
|
23
|
+
- What are the constraints? (team size, timeline, existing stack)
|
|
24
|
+
- What's the blast radius? (which parts of the system are affected)
|
|
25
|
+
|
|
26
|
+
### Step 2: Explore the Context
|
|
27
|
+
|
|
28
|
+
Understand the current state before proposing changes:
|
|
29
|
+
|
|
30
|
+
- **Current architecture**: What exists today? Read the codebase if available.
|
|
31
|
+
- **Quality attributes that matter**: Performance? Scalability? Developer experience? Maintainability? Deployment simplicity?
|
|
32
|
+
- **Team context**: Team size, expertise, on-call burden
|
|
33
|
+
- **Growth trajectory**: Expected scale in 6-12 months (not 5 years — YAGNI)
|
|
34
|
+
|
|
35
|
+
### Step 3: Generate Options
|
|
36
|
+
|
|
37
|
+
Present 2-4 viable options. For each option:
|
|
38
|
+
|
|
39
|
+
1. **Name it clearly** (e.g., "Separate Auth Service" vs "Auth Module in Monolith")
|
|
40
|
+
2. **Describe the approach** in 2-3 sentences
|
|
41
|
+
3. **Analyze trade-offs** against the quality attributes identified in Step 2
|
|
42
|
+
4. **Estimate complexity** (implementation effort, operational overhead)
|
|
43
|
+
5. **Identify reversibility** — how hard is it to change this decision later?
|
|
44
|
+
|
|
45
|
+
Avoid presenting a straw-man option just to make the preferred one look better.
|
|
46
|
+
|
|
47
|
+
### Step 4: Apply Design Principles
|
|
48
|
+
|
|
49
|
+
Evaluate each option through these lenses:
|
|
50
|
+
|
|
51
|
+
- **KISS**: Which option is simplest to implement and operate?
|
|
52
|
+
- **YAGNI**: Which avoids building for hypothetical future needs?
|
|
53
|
+
- **Functional Independence**: Which gives the cleanest boundaries and lowest coupling?
|
|
54
|
+
- **Separation of Concerns**: Which isolates responsibilities clearly?
|
|
55
|
+
- **DRY**: Which avoids duplication of logic or data?
|
|
56
|
+
- **SOLID**: Does the design respect Open/Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion? See [references/solid-principles.md](references/solid-principles.md).
|
|
57
|
+
- **Clean Architecture**: Does the dependency direction point inward? Are business rules protected from infrastructure details? See [references/clean-architecture.md](references/clean-architecture.md).
|
|
58
|
+
- **Component boundaries**: Are components cohesive (CCP, CRP) and acyclic (ADP)? Do dependencies flow toward stability (SDP)? See [references/component-principles.md](references/component-principles.md).
|
|
59
|
+
|
|
60
|
+
Document which principles favor which option. Conflict between principles is expected — that's why it's a decision, not a formula.
|
|
61
|
+
|
|
62
|
+
See [references/principles.md](references/principles.md) for deeper guidance on applying KISS, YAGNI, coupling, and separation of concerns to architecture decisions.
|
|
63
|
+
|
|
64
|
+
### Step 5: Make a Recommendation
|
|
65
|
+
|
|
66
|
+
State the recommended option clearly, with reasoning. Structure it as:
|
|
67
|
+
|
|
68
|
+
1. **Recommendation**: Option X
|
|
69
|
+
2. **Primary reason**: The most compelling argument (one sentence)
|
|
70
|
+
3. **Key trade-off accepted**: What you're giving up and why it's acceptable
|
|
71
|
+
4. **Conditions that would change this decision**: Future triggers to revisit
|
|
72
|
+
|
|
73
|
+
### Step 6: Document the ADR
|
|
74
|
+
|
|
75
|
+
Produce an ADR using the template at [templates/adr.md](templates/adr.md). Save it in the project's decision log (e.g., `docs/decisions/NNN-decision-title.md`).
|
|
76
|
+
|
|
77
|
+
ADRs are immutable records. If a decision is superseded, create a new ADR that references the old one — don't edit the original.
|
|
78
|
+
|
|
79
|
+
For visual architecture documentation (system diagrams, runtime flows, infrastructure topology), see the `architecture-documentation` skill.
|
|
80
|
+
|
|
81
|
+
## When to Split Decisions
|
|
82
|
+
|
|
83
|
+
If the analysis reveals multiple independent decisions bundled together, split them into separate ADRs. For example, "How should we handle caching?" might split into:
|
|
84
|
+
- ADR-001: Cache invalidation strategy
|
|
85
|
+
- ADR-002: Cache storage technology
|
|
86
|
+
- ADR-003: Cache warming approach
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "architecture-design",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "We're building a SaaS platform and need to decide whether to use a multi-tenant single database or database-per-tenant approach. We have about 50 customers now, expecting 500 in a year. It's a Django app on PostgreSQL. Some customers are enterprise with strict data isolation requirements.",
|
|
7
|
+
"expected_output": "A structured analysis with at least 3 options (shared DB with row-level security, schema-per-tenant, DB-per-tenant), trade-off analysis against quality attributes, a clear recommendation with rationale, and an ADR document.",
|
|
8
|
+
"assertions": [
|
|
9
|
+
"Presents at least 3 distinct options",
|
|
10
|
+
"Analyzes trade-offs for each option (not just pros/cons lists)",
|
|
11
|
+
"Considers the enterprise data isolation requirement explicitly",
|
|
12
|
+
"Applies KISS and YAGNI (doesn't over-engineer for 500 customers)",
|
|
13
|
+
"Makes a clear recommendation with primary reason stated",
|
|
14
|
+
"Includes revisit triggers for when to reconsider",
|
|
15
|
+
"Produces an ADR document saved to the filesystem"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": 2,
|
|
20
|
+
"prompt": "should we use graphql or rest for our new api? we're a team of 3",
|
|
21
|
+
"expected_output": "Should ask clarifying questions first (what kind of clients, data complexity, team's GraphQL experience), then produce a balanced analysis that considers team size heavily.",
|
|
22
|
+
"assertions": [
|
|
23
|
+
"Asks clarifying questions before recommending",
|
|
24
|
+
"Considers team size (3 devs) as a major constraint",
|
|
25
|
+
"Applies KISS principle favoring simplicity for small team",
|
|
26
|
+
"Does not present a straw-man option",
|
|
27
|
+
"Identifies reversibility of the decision"
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": 3,
|
|
32
|
+
"prompt": "Our monolithic Rails app is getting slow and hard to deploy. The CTO wants to move to microservices. I'm not sure it's the right call. We have 12 developers and the app has about 200K lines of code. What should we do?",
|
|
33
|
+
"expected_output": "Should explore whether the problem is actually about microservices or about other improvements. Present options including modular monolith, selective extraction, and full microservices. Should be skeptical of a full rewrite.",
|
|
34
|
+
"assertions": [
|
|
35
|
+
"Does not immediately agree with 'move to microservices'",
|
|
36
|
+
"Explores root causes of slowness and deployment pain",
|
|
37
|
+
"Presents modular monolith as a viable option",
|
|
38
|
+
"Analyzes the distributed monolith anti-pattern risk",
|
|
39
|
+
"Considers team size relative to service count",
|
|
40
|
+
"References functional independence principle"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Clean Architecture Reference
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
- The Dependency Rule
|
|
5
|
+
- The four layers
|
|
6
|
+
- Screaming Architecture
|
|
7
|
+
- Plugin Architecture
|
|
8
|
+
- The Main Component
|
|
9
|
+
- Humble Object Pattern
|
|
10
|
+
- Policy and Level
|
|
11
|
+
- Entities vs Use Cases
|
|
12
|
+
- Crossing boundaries
|
|
13
|
+
|
|
14
|
+
## The Dependency Rule
|
|
15
|
+
|
|
16
|
+
**Source code dependencies must point inward only.** Nothing in an inner circle can know anything about something in an outer circle — not a name, a type, a function, or even that an outer layer exists.
|
|
17
|
+
|
|
18
|
+
This is the foundational rule. Every other concept in Clean Architecture exists to enforce or support it. When dependencies point inward, the core business logic is protected from changes to UI, databases, frameworks, and delivery mechanisms.
|
|
19
|
+
|
|
20
|
+
Data can flow outward (a use case returns a result to a controller), but the source code dependency still points inward — the outer layer calls into the inner layer, not the reverse. When inner layers need to communicate outward, they define an interface that the outer layer implements (Dependency Inversion Principle).
|
|
21
|
+
|
|
22
|
+
## The Four Layers
|
|
23
|
+
|
|
24
|
+
From innermost to outermost:
|
|
25
|
+
|
|
26
|
+
### Layer 1: Entities
|
|
27
|
+
Enterprise-wide business rules — the most general, highest-level policies. Entities encapsulate the critical business logic that would exist even if there were no software system.
|
|
28
|
+
|
|
29
|
+
- Pure domain objects with behavior and validation
|
|
30
|
+
- No dependency on any framework, database, or delivery mechanism
|
|
31
|
+
- Reusable across applications (if the enterprise has multiple apps)
|
|
32
|
+
- Example: `Order` that enforces "cannot add items after checkout", `Money` that handles currency arithmetic
|
|
33
|
+
|
|
34
|
+
### Layer 2: Use Cases (Application Business Rules)
|
|
35
|
+
Application-specific business rules that orchestrate entities to achieve a goal. Each use case represents one thing the system does for a user or external system.
|
|
36
|
+
|
|
37
|
+
- Orchestrate the flow of data to and from entities
|
|
38
|
+
- Contain application logic: "when user places order, validate stock, calculate total, reserve inventory, send confirmation"
|
|
39
|
+
- Define input/output port interfaces (what data comes in, what goes out)
|
|
40
|
+
- Independent of UI, database, or external services
|
|
41
|
+
- Example: `PlaceOrderUseCase` that coordinates `Order`, `Inventory`, and `PaymentGateway` interfaces
|
|
42
|
+
|
|
43
|
+
### Layer 3: Interface Adapters
|
|
44
|
+
Convert data between the format used by use cases/entities and the format used by external agencies.
|
|
45
|
+
|
|
46
|
+
- **Controllers**: Receive external input (HTTP, CLI, events), convert to use case input format, invoke the use case
|
|
47
|
+
- **Presenters**: Take use case output, format it for the delivery mechanism (JSON, HTML, CLI output)
|
|
48
|
+
- **Gateways**: Implement repository/service interfaces defined by use cases, translate to database queries or API calls
|
|
49
|
+
- **DTOs**: Data transfer objects that cross the boundary — simple data structures, no business logic
|
|
50
|
+
|
|
51
|
+
### Layer 4: Frameworks & Drivers
|
|
52
|
+
The outermost layer — databases, web frameworks, UI frameworks, external APIs, file systems.
|
|
53
|
+
|
|
54
|
+
- Contains no business logic — only glue code
|
|
55
|
+
- Frameworks are kept at arm's length — they are tools, not the architecture
|
|
56
|
+
- This layer is where the "details" live: which database, which web framework, which messaging system
|
|
57
|
+
- Easiest to replace because nothing depends on it
|
|
58
|
+
|
|
59
|
+
## Screaming Architecture
|
|
60
|
+
|
|
61
|
+
**Your architecture should tell you what the system does, not what framework it uses.**
|
|
62
|
+
|
|
63
|
+
When you look at a project's top-level directory structure, it should scream "healthcare system" or "accounting application" — not "Rails app" or "Spring Boot project."
|
|
64
|
+
|
|
65
|
+
Signs of screaming architecture:
|
|
66
|
+
- Top-level directories named after domain concepts: `orders/`, `inventory/`, `payments/`
|
|
67
|
+
- Use cases are visible as first-class code artifacts, not buried inside controllers
|
|
68
|
+
- You can understand the system's purpose without knowing the technology stack
|
|
69
|
+
|
|
70
|
+
Signs of framework-dominated architecture:
|
|
71
|
+
- Top-level directories named `controllers/`, `models/`, `views/`, `services/`
|
|
72
|
+
- Business logic scattered across framework-specific classes
|
|
73
|
+
- Switching frameworks would require rewriting business logic
|
|
74
|
+
|
|
75
|
+
This doesn't mean you can't have a `controllers/` directory — but it should live inside a feature module, not the other way around.
|
|
76
|
+
|
|
77
|
+
## Plugin Architecture
|
|
78
|
+
|
|
79
|
+
**Frameworks, databases, and UI are plugins to the business rules — not the other way around.**
|
|
80
|
+
|
|
81
|
+
The business rules are the core. Everything else plugs into them. This means:
|
|
82
|
+
- The database is a plugin — you should be able to swap PostgreSQL for MongoDB without touching business logic
|
|
83
|
+
- The web framework is a plugin — you should be able to swap Express for Fastify without touching use cases
|
|
84
|
+
- The UI is a plugin — you should be able to add a CLI interface alongside the web UI without duplicating logic
|
|
85
|
+
|
|
86
|
+
This is achieved through interfaces defined by the inner layers and implemented by the outer layers (DIP).
|
|
87
|
+
|
|
88
|
+
## The Main Component
|
|
89
|
+
|
|
90
|
+
Every application has an entry point — `main()`, `app.ts`, `settings.py`. This is the "dirtiest" component in the system:
|
|
91
|
+
|
|
92
|
+
- It knows about everything: frameworks, databases, use cases, entities
|
|
93
|
+
- It wires all the dependencies together (composition root)
|
|
94
|
+
- It is a plugin to the application — the outermost detail
|
|
95
|
+
- It should contain no business logic — only wiring
|
|
96
|
+
|
|
97
|
+
The Main component is where dependency injection configuration lives. It creates concrete implementations and passes them to the layers that depend on abstractions.
|
|
98
|
+
|
|
99
|
+
## Humble Object Pattern
|
|
100
|
+
|
|
101
|
+
**Separate behaviors that are hard to test from behaviors that are easy to test.**
|
|
102
|
+
|
|
103
|
+
At every architectural boundary, you'll find code that's hard to test (UI rendering, database I/O, network calls) adjacent to code that's easy to test (data formatting, validation, business decisions). The Humble Object pattern splits them:
|
|
104
|
+
|
|
105
|
+
- **Humble part**: Kept as simple as possible. Does the hard-to-test thing (renders HTML, executes SQL) but contains no logic worth testing.
|
|
106
|
+
- **Testable part**: Contains all the decisions and logic. Receives and returns simple data structures.
|
|
107
|
+
|
|
108
|
+
Common applications:
|
|
109
|
+
- **Presenter / View**: The presenter formats data and makes decisions (testable). The view just renders what the presenter provides (humble).
|
|
110
|
+
- **Gateway / Database**: The gateway implementation executes queries (humble). The use case that calls the gateway interface contains the logic (testable).
|
|
111
|
+
- **Controller / Framework**: The framework routing is humble. The controller logic that processes input is testable.
|
|
112
|
+
|
|
113
|
+
## Policy and Level
|
|
114
|
+
|
|
115
|
+
Software is composed of policies at different levels. High-level policies (business rules) change rarely and for important reasons. Low-level policies (formatting, I/O, protocols) change frequently and for trivial reasons.
|
|
116
|
+
|
|
117
|
+
The architecture should protect high-level policies from changes to low-level details:
|
|
118
|
+
- Business rules should not change when you switch databases
|
|
119
|
+
- Domain logic should not change when you change the API response format
|
|
120
|
+
- Core calculations should not change when you add a new delivery channel
|
|
121
|
+
|
|
122
|
+
**Level** is determined by distance from inputs and outputs. The farther a policy is from I/O, the higher its level. Entities are the highest level; UI rendering and database queries are the lowest.
|
|
123
|
+
|
|
124
|
+
## Entities vs Use Cases
|
|
125
|
+
|
|
126
|
+
This distinction is often confused. The key difference:
|
|
127
|
+
|
|
128
|
+
**Entities** embody enterprise-wide business rules that exist independently of any application:
|
|
129
|
+
- "An order must have at least one line item"
|
|
130
|
+
- "Discount cannot exceed 50% of the item price"
|
|
131
|
+
- "A user's email must be unique"
|
|
132
|
+
|
|
133
|
+
**Use Cases** embody application-specific rules that orchestrate entities:
|
|
134
|
+
- "When a user places an order: validate stock, apply discount rules, calculate shipping, charge payment, send confirmation"
|
|
135
|
+
- "When an admin cancels an order: refund payment, restore stock, notify user"
|
|
136
|
+
|
|
137
|
+
Entities don't know about use cases. Use cases know about entities and direct them to enforce their rules.
|
|
138
|
+
|
|
139
|
+
## Crossing Boundaries
|
|
140
|
+
|
|
141
|
+
When data crosses an architectural boundary:
|
|
142
|
+
- Use simple data structures (DTOs, value objects) — not entity objects or framework objects
|
|
143
|
+
- The inner layer defines what it needs (input port) and what it returns (output port)
|
|
144
|
+
- The outer layer maps its own data structures to/from the boundary's format
|
|
145
|
+
- Never pass database rows or HTTP request objects into business logic
|
|
146
|
+
|
|
147
|
+
This keeps each layer independent and testable. The mapping code lives in the Interface Adapters layer.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Component Principles Reference
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
- Component cohesion (REP, CCP, CRP)
|
|
5
|
+
- Component coupling (ADP, SDP, SAP)
|
|
6
|
+
- The tension triangle
|
|
7
|
+
- Stability and abstractness metrics
|
|
8
|
+
|
|
9
|
+
Components are the units of deployment — JARs, gems, npm packages, Go modules, Python packages. These principles guide what goes into a component and how components relate to each other.
|
|
10
|
+
|
|
11
|
+
## Component Cohesion Principles
|
|
12
|
+
|
|
13
|
+
These three principles govern which classes belong together in a component. They pull in different directions — balancing them is a design judgment.
|
|
14
|
+
|
|
15
|
+
### Reuse/Release Equivalence Principle (REP)
|
|
16
|
+
|
|
17
|
+
**The granule of reuse is the granule of release.**
|
|
18
|
+
|
|
19
|
+
Classes and modules that are reused together should be released together, with a shared version number and release process. If you release a component, everything in it should make sense to a consumer who depends on it.
|
|
20
|
+
|
|
21
|
+
Violation signals:
|
|
22
|
+
- A package where consumers only use 20% of the classes and are forced to take the other 80%
|
|
23
|
+
- A "utils" package with unrelated utilities — date formatting, string helpers, HTTP clients, and logging all in one
|
|
24
|
+
- Version bumps that break consumers who don't use the changed code
|
|
25
|
+
|
|
26
|
+
### Common Closure Principle (CCP)
|
|
27
|
+
|
|
28
|
+
**Gather together classes that change for the same reasons and at the same time.**
|
|
29
|
+
|
|
30
|
+
This is SRP at the component level. A change in requirements should affect one component, not scatter across many. When classes change together, they belong together.
|
|
31
|
+
|
|
32
|
+
This minimizes the number of components that need to be redeployed when a requirement changes.
|
|
33
|
+
|
|
34
|
+
Violation signals:
|
|
35
|
+
- A single feature change requires modifying 5+ components
|
|
36
|
+
- Related classes are scattered across packages by technical layer rather than grouped by business capability
|
|
37
|
+
- Every PR touches the same set of "shared" packages
|
|
38
|
+
|
|
39
|
+
### Common Reuse Principle (CRP)
|
|
40
|
+
|
|
41
|
+
**Don't force users of a component to depend on things they don't need.**
|
|
42
|
+
|
|
43
|
+
If a consumer uses one class from a component, it implicitly depends on the entire component. If another class in that component changes, the consumer must revalidate and potentially redeploy — even though it doesn't use the changed class.
|
|
44
|
+
|
|
45
|
+
This is ISP at the component level.
|
|
46
|
+
|
|
47
|
+
Violation signals:
|
|
48
|
+
- Consumers frequently pinpoint specific files to import rather than using the component as a whole
|
|
49
|
+
- A change to an unused class in a dependency forces downstream rebuilds or version bumps
|
|
50
|
+
- "I only need the `parseDate` function but I have to install a 2MB package"
|
|
51
|
+
|
|
52
|
+
## The Tension Triangle
|
|
53
|
+
|
|
54
|
+
REP, CCP, and CRP pull in different directions:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
REP
|
|
58
|
+
/ \
|
|
59
|
+
CCP --- CRP
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- **REP + CCP** (group for reusers + group for changers): Tends toward large components — easy to release and change together, but consumers depend on more than they need (violates CRP)
|
|
63
|
+
- **CCP + CRP** (group for changers + split for consumers): Tends toward many small components — changes are localized and consumers only get what they need, but hard to manage releases (violates REP)
|
|
64
|
+
- **REP + CRP** (group for reusers + split for consumers): Tends toward well-packaged components, but changes scatter across many of them (violates CCP)
|
|
65
|
+
|
|
66
|
+
**Early in a project**, favor CCP — you want changes localized because requirements shift fast. **As the project matures and gains consumers**, shift toward REP and CRP — reusability and minimal dependency surface matter more.
|
|
67
|
+
|
|
68
|
+
## Component Coupling Principles
|
|
69
|
+
|
|
70
|
+
These three principles govern the dependency relationships between components.
|
|
71
|
+
|
|
72
|
+
### Acyclic Dependencies Principle (ADP)
|
|
73
|
+
|
|
74
|
+
**The dependency graph of components must have no cycles.**
|
|
75
|
+
|
|
76
|
+
Cycles create a "morning after" problem: you arrive to find your code broken because something you depend on changed, which depended on something you changed, creating an unresolvable build order.
|
|
77
|
+
|
|
78
|
+
With cycles:
|
|
79
|
+
- You cannot build or test components in isolation
|
|
80
|
+
- A change anywhere in the cycle potentially affects everything in the cycle
|
|
81
|
+
- Release order becomes ambiguous or impossible
|
|
82
|
+
|
|
83
|
+
How to break cycles:
|
|
84
|
+
1. **Apply DIP**: If A depends on B and B depends on A, have B depend on an interface defined by A (or introduce a new component for the shared abstraction)
|
|
85
|
+
2. **Extract a new component**: Move the shared dependency into its own component that both A and B depend on
|
|
86
|
+
3. **Merge the components**: If two components are so intertwined they form a cycle, they may actually be one component
|
|
87
|
+
|
|
88
|
+
### Stable Dependencies Principle (SDP)
|
|
89
|
+
|
|
90
|
+
**Depend in the direction of stability.**
|
|
91
|
+
|
|
92
|
+
A component's stability is measured by how hard it is to change. Components that many others depend on are stable (changing them has high cost). Components with few dependents are volatile (easy to change).
|
|
93
|
+
|
|
94
|
+
**Stability metric (I)**: `I = Fan-out / (Fan-in + Fan-out)`
|
|
95
|
+
- Fan-in: number of incoming dependencies (other components that depend on this one)
|
|
96
|
+
- Fan-out: number of outgoing dependencies (components this one depends on)
|
|
97
|
+
- I = 0: maximally stable (everyone depends on it, it depends on nothing)
|
|
98
|
+
- I = 1: maximally unstable (it depends on others, nobody depends on it)
|
|
99
|
+
|
|
100
|
+
The rule: a component should only depend on components with a lower I (more stable). Depending on something less stable than yourself means your component can be destabilized by volatile changes.
|
|
101
|
+
|
|
102
|
+
### Stable Abstractions Principle (SAP)
|
|
103
|
+
|
|
104
|
+
**A component should be as abstract as it is stable.**
|
|
105
|
+
|
|
106
|
+
Stable components (hard to change because many depend on them) should consist of abstractions — interfaces and abstract classes — so they can be extended without modification (OCP).
|
|
107
|
+
|
|
108
|
+
Volatile components (easy to change) should be concrete — they contain the implementation details that change frequently.
|
|
109
|
+
|
|
110
|
+
**Abstractness metric (A)**: `A = abstract classes and interfaces / total classes`
|
|
111
|
+
- A = 0: fully concrete (no abstractions)
|
|
112
|
+
- A = 1: fully abstract (only interfaces)
|
|
113
|
+
|
|
114
|
+
Plotting I against A gives the **Main Sequence** — the ideal diagonal where `I + A ≈ 1`:
|
|
115
|
+
- Components near (0,1): stable and abstract — good (e.g., interface packages)
|
|
116
|
+
- Components near (1,0): volatile and concrete — good (e.g., implementations, UI)
|
|
117
|
+
- Components near (0,0): stable and concrete — **Zone of Pain** (hard to change but contains implementation details)
|
|
118
|
+
- Components near (1,1): volatile and abstract — **Zone of Uselessness** (abstract but nobody depends on it)
|
|
119
|
+
|
|
120
|
+
## Applying These Principles
|
|
121
|
+
|
|
122
|
+
When designing component boundaries:
|
|
123
|
+
|
|
124
|
+
1. **Start with CCP** — group by business capability so changes are localized
|
|
125
|
+
2. **Check for cycles (ADP)** — if you find one, restructure using DIP or extraction
|
|
126
|
+
3. **Verify stability direction (SDP)** — volatile components should not be depended upon by stable ones
|
|
127
|
+
4. **Balance abstraction with stability (SAP)** — if a component is heavily depended upon, make it abstract
|
|
128
|
+
5. **As consumers appear, apply CRP** — split components so consumers only depend on what they use
|
|
129
|
+
6. **Version and release cohesive units (REP)** — everything in a release should make sense together
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Architecture Principles Reference
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
- KISS in architecture
|
|
5
|
+
- YAGNI in architecture
|
|
6
|
+
- Functional independence and coupling
|
|
7
|
+
- Separation of concerns
|
|
8
|
+
- DRY at the system level
|
|
9
|
+
- Common anti-patterns
|
|
10
|
+
|
|
11
|
+
## KISS in Architecture
|
|
12
|
+
|
|
13
|
+
Simplicity in architecture means fewer moving parts, fewer failure modes, and faster onboarding. When evaluating options:
|
|
14
|
+
|
|
15
|
+
- Prefer a monolith over microservices unless you have a concrete scaling or deployment bottleneck that a monolith cannot solve
|
|
16
|
+
- Prefer synchronous communication unless you need resilience to downstream failures
|
|
17
|
+
- Prefer a single database unless you have conflicting access patterns that provably degrade each other
|
|
18
|
+
- Prefer server-side rendering unless you need offline capability or real-time interactivity
|
|
19
|
+
|
|
20
|
+
The burden of proof is on complexity — if you can't articulate why the simpler approach fails, choose simple.
|
|
21
|
+
|
|
22
|
+
## YAGNI in Architecture
|
|
23
|
+
|
|
24
|
+
Build for today's known requirements plus 6 months of projected growth. Do not:
|
|
25
|
+
|
|
26
|
+
- Design for "millions of users" when you have hundreds
|
|
27
|
+
- Add a message queue because "we might need it"
|
|
28
|
+
- Create microservices because "we might scale the team"
|
|
29
|
+
- Abstract every boundary because "we might swap implementations"
|
|
30
|
+
|
|
31
|
+
Instead, identify the minimum viable architecture that meets current quality attributes. Document what triggers a redesign (e.g., "if request latency exceeds 200ms at P95, revisit the caching strategy").
|
|
32
|
+
|
|
33
|
+
## Functional Independence and Coupling
|
|
34
|
+
|
|
35
|
+
Measure coupling by asking: "If I change module A, how many other modules must also change?"
|
|
36
|
+
|
|
37
|
+
Coupling types (ordered from worst to best):
|
|
38
|
+
1. **Content coupling**: Module A directly modifies the internals of module B
|
|
39
|
+
2. **Common coupling**: Modules share global mutable state
|
|
40
|
+
3. **Control coupling**: Module A passes flags that dictate module B's behavior
|
|
41
|
+
4. **Stamp coupling**: Modules share composite data structures but only use parts
|
|
42
|
+
5. **Data coupling**: Modules share only the data they each need (best achievable)
|
|
43
|
+
|
|
44
|
+
At the architecture level, aim for data coupling between services/modules. Each component should have a well-defined interface and no knowledge of other components' internals.
|
|
45
|
+
|
|
46
|
+
## Separation of Concerns
|
|
47
|
+
|
|
48
|
+
Good boundaries emerge from asking "what changes together?":
|
|
49
|
+
|
|
50
|
+
- **Business rules** change when business requirements change
|
|
51
|
+
- **Data access** changes when storage technology changes
|
|
52
|
+
- **Presentation** changes when UX requirements change
|
|
53
|
+
- **Infrastructure** changes when deployment targets change
|
|
54
|
+
|
|
55
|
+
If a single change requires touching all four layers, your separation is leaking. Common signs:
|
|
56
|
+
- Business logic inside API controllers
|
|
57
|
+
- SQL queries inside domain models
|
|
58
|
+
- Formatting logic inside data access layers
|
|
59
|
+
- Environment-specific code outside configuration
|
|
60
|
+
|
|
61
|
+
## DRY at the System Level
|
|
62
|
+
|
|
63
|
+
DRY in architecture is about eliminating **knowledge duplication**, not code duplication. Two services can have similar code if they represent different business concepts that happen to look alike today.
|
|
64
|
+
|
|
65
|
+
Dangerous false DRY:
|
|
66
|
+
- Sharing a "common" library between services that evolve at different rates
|
|
67
|
+
- Creating a "generic" service that handles too many concerns
|
|
68
|
+
- Forcing different domains into a shared data model
|
|
69
|
+
|
|
70
|
+
Legitimate DRY:
|
|
71
|
+
- Centralizing authentication/authorization logic
|
|
72
|
+
- Shared API contracts (OpenAPI specs, protobuf definitions)
|
|
73
|
+
- Common infrastructure configuration (Terraform modules, Helm charts)
|
|
74
|
+
|
|
75
|
+
## Common Anti-patterns
|
|
76
|
+
|
|
77
|
+
- **Premature abstraction**: Creating interfaces and abstractions before you have two concrete implementations
|
|
78
|
+
- **Distributed monolith**: Microservices that must be deployed together and share a database
|
|
79
|
+
- **God service**: One service that everything depends on and that handles too many concerns
|
|
80
|
+
- **Speculative generality**: Building for flexibility nobody has asked for
|
|
81
|
+
- **Golden hammer**: Using the same pattern/technology for every problem
|