@comfanion/workflow 4.36.22 → 4.36.24
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/package.json +1 -1
- package/src/build-info.json +2 -2
- package/src/opencode/agents/analyst.md +12 -1
- package/src/opencode/agents/architect.md +67 -18
- package/src/opencode/agents/dev.md +13 -1
- package/src/opencode/agents/pm.md +12 -1
- package/src/opencode/plugins/file-indexer.ts +4 -5
- package/src/opencode/skills/unit-writing/SKILL.md +315 -106
- package/src/opencode/skills/unit-writing/template.md +7 -132
- package/src/opencode/skills/unit-writing/templates/data-model.md +57 -0
- package/src/opencode/skills/unit-writing/templates/entity.md +85 -0
- package/src/opencode/skills/unit-writing/templates/events-index.md +42 -0
- package/src/opencode/skills/unit-writing/templates/index.md +61 -0
package/package.json
CHANGED
package/src/build-info.json
CHANGED
|
@@ -34,6 +34,16 @@ permission:
|
|
|
34
34
|
<step n="3">Greet user by {user_name}, communicate in {communication_language}</step>
|
|
35
35
|
<step n="4">Understand user request and select appropriate skill</step>
|
|
36
36
|
<step n="5">Load .opencode/skills/{skill-name}/SKILL.md and follow instructions</step>
|
|
37
|
+
|
|
38
|
+
<search-first critical="MANDATORY - DO THIS BEFORE GLOB/GREP">
|
|
39
|
+
BEFORE using glob or grep, you MUST call search() first:
|
|
40
|
+
1. search({ query: "your topic", index: "docs" }) - for documentation
|
|
41
|
+
2. THEN use glob/grep if you need specific files
|
|
42
|
+
|
|
43
|
+
Example: Looking for existing requirements?
|
|
44
|
+
✅ CORRECT: search({ query: "user requirements authentication", index: "docs" })
|
|
45
|
+
❌ WRONG: glob("**/*requirements*.md") without search first
|
|
46
|
+
</search-first>
|
|
37
47
|
|
|
38
48
|
<rules>
|
|
39
49
|
<r>ALWAYS communicate in {communication_language}</r>
|
|
@@ -43,7 +53,8 @@ permission:
|
|
|
43
53
|
<r>Always validate requirements against SMART criteria</r>
|
|
44
54
|
<r>Never assume - always ask clarifying questions</r>
|
|
45
55
|
<r>Find and use `**/project-context.md` as source of truth if exists</r>
|
|
46
|
-
<r
|
|
56
|
+
<r critical="MANDATORY">🔍 SEARCH FIRST: You MUST call search() BEFORE glob/grep when exploring.
|
|
57
|
+
search({ query: "topic", index: "docs" }) → THEN glob if needed</r>
|
|
47
58
|
</rules>
|
|
48
59
|
</activation>
|
|
49
60
|
|
|
@@ -45,6 +45,18 @@ permission:
|
|
|
45
45
|
<step n="3">Greet user by {user_name}, communicate in {communication_language}</step>
|
|
46
46
|
<step n="4">Understand user request and select appropriate skill</step>
|
|
47
47
|
<step n="5">Load .opencode/skills/{skill-name}/SKILL.md and follow instructions</step>
|
|
48
|
+
<step n="6">ALWAYS follow <workflow> before creating/modifying files</step>
|
|
49
|
+
|
|
50
|
+
<search-first critical="MANDATORY - DO THIS BEFORE GLOB/GREP">
|
|
51
|
+
BEFORE using glob or grep, you MUST call search() first:
|
|
52
|
+
1. search({ query: "your topic", index: "docs" }) - for documentation
|
|
53
|
+
2. search({ query: "your topic", index: "code" }) - for source code
|
|
54
|
+
3. THEN use glob/grep if you need specific files
|
|
55
|
+
|
|
56
|
+
Example: Looking for database schema?
|
|
57
|
+
✅ CORRECT: search({ query: "database schema users teams", index: "docs" })
|
|
58
|
+
❌ WRONG: glob("**/*schema*.md") without search first
|
|
59
|
+
</search-first>
|
|
48
60
|
|
|
49
61
|
<rules>
|
|
50
62
|
<r>ALWAYS communicate in {communication_language}</r>
|
|
@@ -56,13 +68,45 @@ permission:
|
|
|
56
68
|
<r>User journeys drive technical decisions</r>
|
|
57
69
|
<r>Each doc file < 2000 lines (RAG-friendly)</r>
|
|
58
70
|
<r>Find and use `**/project-context.md` and `CLAUDE.md` as source of truth</r>
|
|
59
|
-
<r critical="
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
- glob/grep ONLY for exact filenames or literal strings</r>
|
|
71
|
+
<r critical="MANDATORY">🔍 SEARCH FIRST: You MUST call search() BEFORE glob/grep when exploring.
|
|
72
|
+
search({ query: "topic", index: "docs" }) → THEN glob if needed</r>
|
|
73
|
+
<r critical="MANDATORY">📋 NEVER create/modify files without user confirmation. Follow <workflow>.</r>
|
|
63
74
|
</rules>
|
|
64
75
|
</activation>
|
|
65
76
|
|
|
77
|
+
<workflow critical="MANDATORY - FOLLOW FOR EVERY TASK">
|
|
78
|
+
<phase name="1. Discovery">
|
|
79
|
+
<action>Search for related documents (search → then glob/grep if needed)</action>
|
|
80
|
+
<action>Read existing architecture, PRD, related modules</action>
|
|
81
|
+
<action>Identify what needs to be created/updated</action>
|
|
82
|
+
</phase>
|
|
83
|
+
|
|
84
|
+
<phase name="2. Planning">
|
|
85
|
+
<action>Create tasklist with todowrite()</action>
|
|
86
|
+
<action>Present plan to user with specific files/changes</action>
|
|
87
|
+
<action>Ask for confirmation with question() tool</action>
|
|
88
|
+
<action>WAIT for user approval before proceeding</action>
|
|
89
|
+
</phase>
|
|
90
|
+
|
|
91
|
+
<phase name="3. Execution">
|
|
92
|
+
<action>Work through tasklist sequentially</action>
|
|
93
|
+
<action>Mark tasks in_progress → completed</action>
|
|
94
|
+
<action>If uncertain about something — ask, don't assume</action>
|
|
95
|
+
</phase>
|
|
96
|
+
|
|
97
|
+
<phase name="4. Review">
|
|
98
|
+
<action>Summarize what was done</action>
|
|
99
|
+
<action>Ask if user wants to review or adjust</action>
|
|
100
|
+
</phase>
|
|
101
|
+
|
|
102
|
+
<never-do>
|
|
103
|
+
- Start creating files before user confirms the plan
|
|
104
|
+
- Skip the tasklist for complex work
|
|
105
|
+
- Assume what user wants without asking
|
|
106
|
+
- Create all files at once without progress updates
|
|
107
|
+
</never-do>
|
|
108
|
+
</workflow>
|
|
109
|
+
|
|
66
110
|
<persona>
|
|
67
111
|
<role>System Architect + Technical Design Leader</role>
|
|
68
112
|
<identity>Senior architect with expertise in distributed systems, cloud infrastructure, API design. DDD and hexagonal architecture expert.</identity>
|
|
@@ -81,7 +125,7 @@ permission:
|
|
|
81
125
|
<skill name="architecture-validation">NFR compliance, dependency analysis, security</skill>
|
|
82
126
|
<skill name="adr-writing">Decision record format, context, consequences</skill>
|
|
83
127
|
<skill name="coding-standards">Code patterns, naming conventions, best practices</skill>
|
|
84
|
-
<skill name="unit-writing">
|
|
128
|
+
<skill name="unit-writing">Document modules, domains, services, entities with folder-based structure</skill>
|
|
85
129
|
</skills>
|
|
86
130
|
|
|
87
131
|
<design-principles>
|
|
@@ -93,14 +137,17 @@ permission:
|
|
|
93
137
|
6. Observability First - Design for debugging and monitoring
|
|
94
138
|
</design-principles>
|
|
95
139
|
|
|
96
|
-
<
|
|
97
|
-
docs/
|
|
98
|
-
├──
|
|
99
|
-
├──
|
|
100
|
-
├──
|
|
101
|
-
├──
|
|
102
|
-
└──
|
|
103
|
-
|
|
140
|
+
<documentation-structure hint="For unit-writing skill">
|
|
141
|
+
docs/architecture/
|
|
142
|
+
├── modules/{name}/ # Bounded contexts
|
|
143
|
+
│ ├── index.md
|
|
144
|
+
│ ├── data-model.md
|
|
145
|
+
│ ├── services/{name}/ # Services inside module
|
|
146
|
+
│ └── domains/{name}/ # Domains inside module
|
|
147
|
+
├── services/{name}/ # Standalone services
|
|
148
|
+
└── domains/{name}/ # Standalone domains
|
|
149
|
+
└── entities/{name}.md # Entities inside domain
|
|
150
|
+
</documentation-structure>
|
|
104
151
|
|
|
105
152
|
<lsp-architecture hint="Use LSP for architecture analysis - requires OPENCODE_EXPERIMENTAL_LSP_TOOL=true">
|
|
106
153
|
<use-case name="Module boundaries">
|
|
@@ -123,13 +170,13 @@ permission:
|
|
|
123
170
|
|
|
124
171
|
<codesearch-architecture hint="Semantic search with MULTI-INDEX for architecture analysis">
|
|
125
172
|
<check>codeindex({ action: "list" }) → See all indexes (code, docs, config)</check>
|
|
126
|
-
|
|
173
|
+
|
|
127
174
|
<indexes hint="Use different indexes for different architecture analysis">
|
|
128
175
|
<index name="code">Source code - patterns, implementations, boundaries</index>
|
|
129
176
|
<index name="docs">Documentation - ADRs, design docs, architecture decisions</index>
|
|
130
177
|
<index name="config">Configuration - infrastructure settings, feature flags</index>
|
|
131
178
|
</indexes>
|
|
132
|
-
|
|
179
|
+
|
|
133
180
|
<use-cases>
|
|
134
181
|
<use-case name="Discover patterns" index="code">
|
|
135
182
|
codesearch({ query: "repository pattern implementation", index: "code" })
|
|
@@ -157,7 +204,7 @@ permission:
|
|
|
157
204
|
codesearch({ query: "feature flags", index: "config" })
|
|
158
205
|
</use-case>
|
|
159
206
|
</use-cases>
|
|
160
|
-
|
|
207
|
+
|
|
161
208
|
<architecture-exploration-flow>
|
|
162
209
|
1. codeindex({ action: "list" }) → Check available indexes
|
|
163
210
|
2. codesearch({ query: "architecture overview", index: "docs" }) → Read existing docs
|
|
@@ -167,7 +214,7 @@ permission:
|
|
|
167
214
|
6. codesearch({ query: "infrastructure config", index: "config" }) → See settings
|
|
168
215
|
7. lsp for detailed analysis of key files
|
|
169
216
|
</architecture-exploration-flow>
|
|
170
|
-
|
|
217
|
+
|
|
171
218
|
<cross-index-analysis hint="Combine indexes for full picture">
|
|
172
219
|
- Code + Docs: "How is authentication implemented?" (code) + "Why this approach?" (docs)
|
|
173
220
|
- Code + Config: "Database usage patterns" (code) + "Connection settings" (config)
|
|
@@ -194,5 +241,7 @@ permission:
|
|
|
194
241
|
**My Output:**
|
|
195
242
|
- `docs/architecture.md`
|
|
196
243
|
- `docs/architecture/adr/*.md`
|
|
197
|
-
- `docs/
|
|
244
|
+
- `docs/architecture/modules/` — bounded contexts
|
|
245
|
+
- `docs/architecture/services/` — standalone services
|
|
246
|
+
- `docs/architecture/domains/` — domains
|
|
198
247
|
- `docs/coding-standards/`
|
|
@@ -37,6 +37,17 @@ permission:
|
|
|
37
37
|
<step n="3">Greet user by {user_name}, communicate in {communication_language}</step>
|
|
38
38
|
<step n="4">Understand user request and select appropriate skill</step>
|
|
39
39
|
<step n="5">Load .opencode/skills/{skill-name}/SKILL.md and follow instructions</step>
|
|
40
|
+
|
|
41
|
+
<search-first critical="MANDATORY - DO THIS BEFORE GLOB/GREP">
|
|
42
|
+
BEFORE using glob or grep, you MUST call search() first:
|
|
43
|
+
1. search({ query: "your topic", index: "code" }) - for source code patterns
|
|
44
|
+
2. search({ query: "your topic", index: "docs" }) - for documentation
|
|
45
|
+
3. THEN use glob/grep if you need specific files
|
|
46
|
+
|
|
47
|
+
Example: Looking for similar implementation?
|
|
48
|
+
✅ CORRECT: search({ query: "user repository CRUD", index: "code" })
|
|
49
|
+
❌ WRONG: glob("**/*user*.go") without search first
|
|
50
|
+
</search-first>
|
|
40
51
|
|
|
41
52
|
<rules>
|
|
42
53
|
<r>ALWAYS communicate in {communication_language}</r>
|
|
@@ -48,7 +59,8 @@ permission:
|
|
|
48
59
|
<r>All existing tests must pass 100% before story is ready for review</r>
|
|
49
60
|
<r>NEVER lie about tests being written or passing</r>
|
|
50
61
|
<r>Find and use `**/project-context.md` and `CLAUDE.md` as source of truth</r>
|
|
51
|
-
<r
|
|
62
|
+
<r critical="MANDATORY">🔍 SEARCH FIRST: Call search() BEFORE glob when exploring codebase.
|
|
63
|
+
search({ query: "feature pattern", index: "code" }) → THEN glob if needed</r>
|
|
52
64
|
</rules>
|
|
53
65
|
|
|
54
66
|
<dev-story-workflow hint="When executing /dev-story command" critical="FOLLOW THIS EXACTLY">
|
|
@@ -42,6 +42,16 @@ permission:
|
|
|
42
42
|
<step n="3">Greet user by {user_name}, communicate in {communication_language}</step>
|
|
43
43
|
<step n="4">Understand user request and select appropriate skill</step>
|
|
44
44
|
<step n="5">Load .opencode/skills/{skill-name}/SKILL.md and follow instructions</step>
|
|
45
|
+
|
|
46
|
+
<search-first critical="MANDATORY - DO THIS BEFORE GLOB/GREP">
|
|
47
|
+
BEFORE using glob or grep, you MUST call search() first:
|
|
48
|
+
1. search({ query: "your topic", index: "docs" }) - for PRD, architecture, requirements
|
|
49
|
+
2. THEN use glob/grep if you need specific files
|
|
50
|
+
|
|
51
|
+
Example: Looking for existing stories?
|
|
52
|
+
✅ CORRECT: search({ query: "user authentication stories", index: "docs" })
|
|
53
|
+
❌ WRONG: glob("**/*story*.md") without search first
|
|
54
|
+
</search-first>
|
|
45
55
|
|
|
46
56
|
<rules>
|
|
47
57
|
<r>ALWAYS communicate in {communication_language}</r>
|
|
@@ -53,7 +63,8 @@ permission:
|
|
|
53
63
|
<r>NEVER create stories without acceptance criteria</r>
|
|
54
64
|
<r critical="true">BEFORE writing epic/story: USE SEMANTIC SEARCH (see before-epic-story)</r>
|
|
55
65
|
<r>Find and use `**/project-context.md` as source of truth if exists</r>
|
|
56
|
-
<r
|
|
66
|
+
<r critical="MANDATORY">🔍 SEARCH FIRST: You MUST call search() BEFORE glob/grep when exploring.
|
|
67
|
+
search({ query: "topic", index: "docs" }) → THEN glob if needed</r>
|
|
57
68
|
</rules>
|
|
58
69
|
|
|
59
70
|
<before-epic-story critical="MANDATORY">
|
|
@@ -366,13 +366,12 @@ async function processPendingFiles(projectRoot: string, config: VectorizerConfig
|
|
|
366
366
|
try {
|
|
367
367
|
const wasIndexed = await indexer.indexSingleFile(filePath)
|
|
368
368
|
if (wasIndexed) {
|
|
369
|
-
|
|
370
|
-
debug(`Reindexed: ${path.relative(projectRoot, filePath)} -> ${indexName}`)
|
|
369
|
+
log(`Reindexed: ${path.relative(projectRoot, filePath)} → ${indexName}`)
|
|
371
370
|
} else {
|
|
372
|
-
|
|
371
|
+
logFile(`Skipped (unchanged): ${path.relative(projectRoot, filePath)}`)
|
|
373
372
|
}
|
|
374
373
|
} catch (e) {
|
|
375
|
-
|
|
374
|
+
log(`Error reindexing ${path.relative(projectRoot, filePath)}: ${(e as Error).message}`)
|
|
376
375
|
}
|
|
377
376
|
}
|
|
378
377
|
|
|
@@ -478,7 +477,7 @@ export const FileIndexerPlugin: Plugin = async ({ directory, client }) => {
|
|
|
478
477
|
const props = (event as any).properties || {}
|
|
479
478
|
const filePath = props.file || props.path || props.filePath
|
|
480
479
|
if (filePath) {
|
|
481
|
-
|
|
480
|
+
log(`Event: ${event.type} → ${filePath}`)
|
|
482
481
|
queueFileForIndexing(filePath)
|
|
483
482
|
}
|
|
484
483
|
}
|
|
@@ -1,185 +1,394 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: unit-writing
|
|
3
|
-
description: How to document modules, domains,
|
|
3
|
+
description: How to document modules, domains, services, and entities with structured folder-based approach
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: opencode
|
|
6
6
|
metadata:
|
|
7
7
|
domain: documentation
|
|
8
|
-
artifacts: docs/architecture/
|
|
8
|
+
artifacts: docs/architecture/{modules,services,domains}/
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Unit Writing Skill
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Overview
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
- **Module** - Large bounded context (e.g., `catalog`, `billing`)
|
|
17
|
-
- **Domain** - Medium business area (e.g., `Order`, `Payment`)
|
|
18
|
-
- **Entity** - Small data object (e.g., `User`, `Task`, `Product`)
|
|
19
|
-
- **Service** - Medium component (e.g., `NotificationService`)
|
|
20
|
-
- **Feature** - Varies (e.g., `Search`, `Import`)
|
|
15
|
+
Documentation follows a **folder-based structure** organized by type: modules, services, domains. Agent determines the appropriate type based on what is being documented.
|
|
21
16
|
|
|
22
|
-
|
|
17
|
+
**Core Principles:**
|
|
18
|
+
- Each file focuses on one concern
|
|
19
|
+
- Files stay under 500 lines (RAG-friendly)
|
|
20
|
+
- Agent decides the type — no rigid rules
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
## When to Use
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
Use this skill to document any logical piece of the system:
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
| Type | When to Use | Example |
|
|
27
|
+
|------|-------------|---------|
|
|
28
|
+
| `module` | Deployable bounded context, largest scope | `catalog`, `auth`, `billing` |
|
|
29
|
+
| `domain` | Business concept grouping within module | `Order`, `Payment`, `Identity` |
|
|
30
|
+
| `service` | Stateless component with clear API | `NotificationService`, `CorrelationEngine` |
|
|
31
|
+
| `entity` | Core data object with business rules | `User`, `Product`, `Invoice` |
|
|
32
|
+
| `feature` | Cross-cutting capability | `Search`, `Import`, `Export` |
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
id: {{ID}}
|
|
32
|
-
type: module | domain | entity | service | feature
|
|
33
|
-
status: draft | approved
|
|
34
|
-
```
|
|
34
|
+
### Hierarchy
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
Components can be nested when logical:
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
| Parent | Can contain |
|
|
39
|
+
|--------|-------------|
|
|
40
|
+
| `module` | services, domains |
|
|
41
|
+
| `service` | domains, entities |
|
|
42
|
+
| `domain` | entities |
|
|
43
|
+
| `entity` | — (leaf node) |
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
Agent decides based on project context — no strict rules.
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|--------|---------|
|
|
48
|
-
| **Owns** | Data and behavior this unit controls |
|
|
49
|
-
| **Uses** | → Unit: `dependency` |
|
|
50
|
-
| **Provides** | What others can use from this unit |
|
|
47
|
+
### Documentation Depth by Type
|
|
51
48
|
|
|
52
|
-
|
|
49
|
+
| Type | Location | Required Files | Optional |
|
|
50
|
+
|------|----------|----------------|----------|
|
|
51
|
+
| `module` | `modules/{name}/` | index, data-model | api/, events/, services/, domains/ |
|
|
52
|
+
| `service` | `services/{name}/` OR `modules/{m}/services/{name}/` | index | api/, data-model |
|
|
53
|
+
| `domain` | `domains/{name}/` OR inside module/service | index, data-model | entities/ |
|
|
54
|
+
| `entity` | inside domain | {entity}.md | — |
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
| name | string | required, max 200 | Display name |
|
|
56
|
+
**When to use separate folder vs inline:**
|
|
57
|
+
- **Separate folder** — has own API, events, or multiple child units
|
|
58
|
+
- **Single file** — simple entity, no children, < 200 lines
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
**Don't create units for:**
|
|
61
|
+
- Simple value objects (document inline in parent)
|
|
62
|
+
- Internal implementation details
|
|
63
|
+
- DTOs, request/response objects
|
|
60
64
|
|
|
61
|
-
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Folder Structure
|
|
68
|
+
|
|
69
|
+
Documentation organized under `docs/architecture/`:
|
|
62
70
|
|
|
63
71
|
```
|
|
64
|
-
|
|
65
|
-
|
|
72
|
+
docs/architecture/
|
|
73
|
+
├── modules/ # Bounded contexts
|
|
74
|
+
│ └── {module}/
|
|
75
|
+
│ ├── index.md
|
|
76
|
+
│ ├── data-model.md
|
|
77
|
+
│ ├── api/
|
|
78
|
+
│ ├── events/
|
|
79
|
+
│ ├── services/ # Services INSIDE module
|
|
80
|
+
│ │ └── {service}/
|
|
81
|
+
│ └── domains/ # Domains INSIDE module
|
|
82
|
+
│ └── {domain}/
|
|
83
|
+
│
|
|
84
|
+
├── services/ # Standalone services (outside modules)
|
|
85
|
+
│ └── {service}/
|
|
86
|
+
│ ├── index.md
|
|
87
|
+
│ └── api/
|
|
88
|
+
│
|
|
89
|
+
└── domains/ # Standalone domains (rare)
|
|
90
|
+
└── {domain}/
|
|
66
91
|
```
|
|
67
92
|
|
|
68
|
-
|
|
69
|
-
|----------|--------|------|-------------|
|
|
70
|
-
| assignee | → Unit: `User` | N:1 | Task assigned to user |
|
|
93
|
+
### Placement rules
|
|
71
94
|
|
|
72
|
-
|
|
95
|
+
| Component | Standalone | Inside module |
|
|
96
|
+
|-----------|------------|---------------|
|
|
97
|
+
| service | `services/{name}/` | `modules/{m}/services/{name}/` |
|
|
98
|
+
| domain | `domains/{name}/` | `modules/{m}/domains/{name}/` |
|
|
99
|
+
| entity | — | always inside domain |
|
|
73
100
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
101
|
+
Agent decides based on:
|
|
102
|
+
- **Standalone service** — independent, used by multiple modules
|
|
103
|
+
- **Service inside module** — belongs to one bounded context
|
|
77
104
|
|
|
78
|
-
|
|
105
|
+
### File Purposes
|
|
79
106
|
|
|
80
|
-
|
|
107
|
+
| File | Purpose | Max Lines |
|
|
108
|
+
|------|---------|-----------|
|
|
109
|
+
| `index.md` | Overview, boundaries, navigation, key decisions | ~150 |
|
|
110
|
+
| `data-model.md` | Database schema, relations, constraints, migrations | ~400 |
|
|
111
|
+
| `api/*.yaml` | OpenAPI specs for each resource | ~300 each |
|
|
112
|
+
| `events/index.md` | Event flow overview, topic mapping | ~200 |
|
|
113
|
+
| `events/*.avsc` | Individual event schemas | ~100 each |
|
|
81
114
|
|
|
82
|
-
|
|
83
|
-
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Required Files
|
|
118
|
+
|
|
119
|
+
### 1. index.md (Overview)
|
|
120
|
+
|
|
121
|
+
The main entry point for the unit. Contains:
|
|
122
|
+
- Unit metadata (YAML frontmatter)
|
|
123
|
+
- Overview paragraph
|
|
124
|
+
- Boundaries table (owns/uses/provides)
|
|
125
|
+
- Architecture diagram
|
|
126
|
+
- Document navigation
|
|
127
|
+
- Key decisions/ADRs
|
|
128
|
+
|
|
129
|
+
**Template:** See `@.opencode/skills/unit-writing/templates/index.md`
|
|
130
|
+
|
|
131
|
+
```yaml
|
|
132
|
+
# index.md frontmatter
|
|
133
|
+
---
|
|
134
|
+
id: MOD-COLLABORATION
|
|
135
|
+
type: module
|
|
136
|
+
status: draft | approved
|
|
137
|
+
version: "1.0"
|
|
138
|
+
created: 2026-01-24
|
|
139
|
+
---
|
|
84
140
|
```
|
|
85
141
|
|
|
86
|
-
|
|
87
|
-
|-------|-------------|----------------|
|
|
142
|
+
**Boundaries Table Format:**
|
|
88
143
|
|
|
89
|
-
|
|
144
|
+
| Aspect | Details |
|
|
145
|
+
|--------|---------|
|
|
146
|
+
| **Owns** | meetings, channels, focus_blocks (tables + behavior) |
|
|
147
|
+
| **Uses** | → Unit: `identity` (contributor resolution) |
|
|
148
|
+
| **Uses** | → Unit: `teams` (team attribution) |
|
|
149
|
+
| **Provides** | Collaboration metrics API, Team health signals |
|
|
150
|
+
|
|
151
|
+
### 2. data-model.md (Database Schema)
|
|
152
|
+
|
|
153
|
+
Complete database schema documentation:
|
|
154
|
+
- Entity Relationship Diagram (ASCII/Mermaid)
|
|
155
|
+
- Table definitions (SQL or structured tables)
|
|
156
|
+
- Indexes and constraints
|
|
157
|
+
- Migration strategy (if applicable)
|
|
158
|
+
|
|
159
|
+
**Structure:**
|
|
160
|
+
1. Overview (design principles)
|
|
161
|
+
2. ERD diagram
|
|
162
|
+
3. Core tables (with full SQL or field tables)
|
|
163
|
+
4. Supporting tables
|
|
164
|
+
5. Indexes
|
|
165
|
+
6. Views/Aggregates (if any)
|
|
166
|
+
7. Migration notes
|
|
167
|
+
|
|
168
|
+
**Example header:**
|
|
169
|
+
```markdown
|
|
170
|
+
# Collaboration Data Model
|
|
90
171
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
172
|
+
**Version:** 1.0
|
|
173
|
+
**Date:** 2026-01-24
|
|
174
|
+
**Status:** Active
|
|
94
175
|
|
|
95
|
-
|
|
176
|
+
## 1. Design Principles
|
|
96
177
|
|
|
178
|
+
| Principle | Description |
|
|
179
|
+
|-----------|-------------|
|
|
180
|
+
| **Single Source of Truth** | PostgreSQL primary, Redis for cache |
|
|
181
|
+
| **SCD2 History** | Time-scoped team membership |
|
|
97
182
|
```
|
|
98
|
-
|
|
99
|
-
|
|
183
|
+
|
|
184
|
+
### 3. events/index.md (Events Overview)
|
|
185
|
+
|
|
186
|
+
Overview of all events the unit produces/consumes:
|
|
187
|
+
- Event flow diagram
|
|
188
|
+
- Topic naming convention
|
|
189
|
+
- Event types table
|
|
190
|
+
- Schema file references
|
|
191
|
+
|
|
192
|
+
**Structure:**
|
|
193
|
+
```markdown
|
|
194
|
+
# {Unit} Events
|
|
195
|
+
|
|
196
|
+
## Overview
|
|
197
|
+
Brief description of event-driven patterns.
|
|
198
|
+
|
|
199
|
+
## Event Flow
|
|
200
|
+
ASCII/Mermaid diagram showing producers/consumers.
|
|
201
|
+
|
|
202
|
+
## Topics
|
|
203
|
+
|
|
204
|
+
| Topic | Events | Partition Key | Direction |
|
|
205
|
+
|-------|--------|---------------|-----------|
|
|
206
|
+
| `events.teams.canonical` | meeting_* | tenant_id | inbound |
|
|
207
|
+
|
|
208
|
+
## Schema Files
|
|
209
|
+
|
|
210
|
+
| Schema | Description |
|
|
211
|
+
|--------|-------------|
|
|
212
|
+
| `meeting-scheduled.avsc` | New meeting created |
|
|
100
213
|
```
|
|
101
214
|
|
|
102
|
-
|
|
215
|
+
### 4. api/*.yaml (OpenAPI Specs)
|
|
103
216
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
217
|
+
One OpenAPI file per resource or logical grouping:
|
|
218
|
+
- `meetings.yaml` - Meeting endpoints
|
|
219
|
+
- `focus-time.yaml` - Focus time endpoints
|
|
220
|
+
- `graph.yaml` - Collaboration graph endpoints
|
|
221
|
+
|
|
222
|
+
Follow OpenAPI 3.1 format.
|
|
223
|
+
|
|
224
|
+
---
|
|
111
225
|
|
|
112
226
|
## Naming Conventions
|
|
113
227
|
|
|
114
|
-
###
|
|
228
|
+
### Folder Names
|
|
115
229
|
|
|
116
230
|
```
|
|
117
|
-
|
|
231
|
+
kebab-case, lowercase
|
|
118
232
|
|
|
119
233
|
Examples:
|
|
120
|
-
-
|
|
121
|
-
-
|
|
122
|
-
-
|
|
234
|
+
- modules/billing/
|
|
235
|
+
- services/notification/
|
|
236
|
+
- domains/subscription/
|
|
123
237
|
```
|
|
124
238
|
|
|
125
|
-
###
|
|
239
|
+
### File Names
|
|
126
240
|
|
|
127
241
|
```
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
-
|
|
132
|
-
- ENT-TASK
|
|
133
|
-
- SVC-NOTIFICATION
|
|
242
|
+
index.md # Entry point (always)
|
|
243
|
+
data-model.md # Database schema
|
|
244
|
+
{resource}.yaml # API specs by resource
|
|
245
|
+
{event-type}.avsc # Event schemas by type
|
|
134
246
|
```
|
|
135
247
|
|
|
248
|
+
---
|
|
249
|
+
|
|
136
250
|
## Reference Format
|
|
137
251
|
|
|
138
|
-
|
|
252
|
+
Reference other components with relative paths:
|
|
139
253
|
|
|
140
254
|
```markdown
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
→ Unit: `NotificationService`
|
|
255
|
+
| Uses | [identity](../domains/identity/) (contributor resolution) |
|
|
256
|
+
| Uses | [teams](../modules/teams/) (team attribution) |
|
|
144
257
|
```
|
|
145
258
|
|
|
146
|
-
|
|
259
|
+
Or with `→` shorthand:
|
|
147
260
|
```markdown
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
261
|
+
→ modules/billing
|
|
262
|
+
→ services/notification
|
|
263
|
+
→ domains/subscription/data-model.md#plans
|
|
151
264
|
```
|
|
152
265
|
|
|
153
|
-
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Creating Documentation
|
|
269
|
+
|
|
270
|
+
### Step 1: Determine type
|
|
271
|
+
|
|
272
|
+
Agent analyzes what is being documented:
|
|
273
|
+
- Has own deployment/bounded context? → `modules/`
|
|
274
|
+
- Stateless with clear API? → `services/`
|
|
275
|
+
- Business logic grouping? → `domains/`
|
|
276
|
+
|
|
277
|
+
### Step 2: Create folder
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
mkdir -p docs/architecture/{type}/{name}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Step 3: Start with index.md
|
|
284
|
+
|
|
285
|
+
Create `index.md` with:
|
|
286
|
+
1. Overview paragraph
|
|
287
|
+
2. Boundaries table (owns/uses/provides)
|
|
288
|
+
3. Architecture diagram (if complex)
|
|
289
|
+
4. Navigation to other files
|
|
290
|
+
|
|
291
|
+
### Step 4: Add supporting files as needed
|
|
154
292
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
| Internal implementation detail | No |
|
|
293
|
+
- `data-model.md` — if has database
|
|
294
|
+
- `api/*.yaml` — if has REST/gRPC API
|
|
295
|
+
- `events/` — if event-driven
|
|
296
|
+
- `entities/*.md` — for leaf entities
|
|
297
|
+
|
|
298
|
+
---
|
|
162
299
|
|
|
163
300
|
## Validation Checklist
|
|
164
301
|
|
|
165
|
-
|
|
302
|
+
### index.md
|
|
303
|
+
- [ ] Has YAML frontmatter (id, type, status, version)
|
|
166
304
|
- [ ] Overview explains single responsibility
|
|
167
|
-
- [ ] Boundaries
|
|
168
|
-
- [ ]
|
|
169
|
-
- [ ]
|
|
170
|
-
- [ ]
|
|
171
|
-
|
|
172
|
-
-
|
|
173
|
-
- [ ]
|
|
305
|
+
- [ ] Boundaries table complete (owns/uses/provides)
|
|
306
|
+
- [ ] Architecture diagram present
|
|
307
|
+
- [ ] Navigation links to other files
|
|
308
|
+
- [ ] References to related units
|
|
309
|
+
|
|
310
|
+
### data-model.md
|
|
311
|
+
- [ ] ERD diagram present
|
|
312
|
+
- [ ] All tables documented
|
|
313
|
+
- [ ] Constraints and indexes listed
|
|
314
|
+
- [ ] Follows project DB conventions
|
|
315
|
+
|
|
316
|
+
### events/
|
|
317
|
+
- [ ] index.md with topic mapping
|
|
318
|
+
- [ ] Individual schema files for each event
|
|
319
|
+
- [ ] Event flow diagram
|
|
320
|
+
|
|
321
|
+
### api/
|
|
322
|
+
- [ ] OpenAPI 3.1 format
|
|
323
|
+
- [ ] Consistent naming
|
|
324
|
+
- [ ] Request/response examples
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Example
|
|
329
|
+
|
|
330
|
+
```
|
|
331
|
+
docs/architecture/
|
|
332
|
+
├── modules/
|
|
333
|
+
│ └── billing/ # Module
|
|
334
|
+
│ ├── index.md
|
|
335
|
+
│ ├── data-model.md
|
|
336
|
+
│ ├── services/
|
|
337
|
+
│ │ └── payment-gateway/ # Service INSIDE module
|
|
338
|
+
│ │ ├── index.md
|
|
339
|
+
│ │ └── api/
|
|
340
|
+
│ └── domains/
|
|
341
|
+
│ └── subscription/ # Domain INSIDE module
|
|
342
|
+
│ ├── index.md
|
|
343
|
+
│ └── entities/
|
|
344
|
+
│ └── plan.md
|
|
345
|
+
│
|
|
346
|
+
└── services/
|
|
347
|
+
└── notification/ # Standalone service
|
|
348
|
+
├── index.md
|
|
349
|
+
└── api/
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
**Key patterns:**
|
|
353
|
+
1. `payment-gateway` is inside `billing` — it belongs to that module
|
|
354
|
+
2. `notification` is standalone — used by multiple modules
|
|
355
|
+
3. Each component has `index.md` as entry point
|
|
356
|
+
4. Entities are leaf nodes (single files inside domain)
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## Anti-Patterns
|
|
361
|
+
|
|
362
|
+
❌ **DON'T:**
|
|
363
|
+
- Create 500+ line monolithic files
|
|
364
|
+
- Mix data model with API with events in one file
|
|
365
|
+
- Embed full SQL schemas in index.md
|
|
366
|
+
- Force everything into rigid structure
|
|
367
|
+
|
|
368
|
+
✅ **DO:**
|
|
369
|
+
- Keep files focused and under 500 lines
|
|
370
|
+
- Separate concerns (data model, API, events)
|
|
371
|
+
- Let agent decide appropriate structure
|
|
372
|
+
- Use relative paths for references
|
|
373
|
+
|
|
374
|
+
---
|
|
174
375
|
|
|
175
376
|
## Output
|
|
176
377
|
|
|
177
|
-
|
|
378
|
+
```
|
|
379
|
+
docs/architecture/
|
|
380
|
+
├── modules/{name}/ # Bounded contexts
|
|
381
|
+
│ ├── services/{name}/ # Services inside module
|
|
382
|
+
│ └── domains/{name}/ # Domains inside module
|
|
383
|
+
├── services/{name}/ # Standalone services
|
|
384
|
+
└── domains/{name}/ # Standalone domains
|
|
385
|
+
```
|
|
178
386
|
|
|
179
|
-
|
|
387
|
+
Agent decides placement based on component relationships.
|
|
180
388
|
|
|
181
389
|
## Related Skills
|
|
182
390
|
|
|
183
|
-
- `architecture-design` -
|
|
391
|
+
- `architecture-design` - Creates units during architecture phase
|
|
184
392
|
- `story-writing` - Tasks reference units
|
|
185
393
|
- `epic-writing` - Epics affect units
|
|
394
|
+
- `adr-writing` - ADRs may be linked from unit index
|
|
@@ -1,136 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DEPRECATED
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
id: {{ID}}
|
|
5
|
-
type: module | domain | entity | service | feature
|
|
6
|
-
status: draft | approved
|
|
7
|
-
```
|
|
3
|
+
This file is deprecated. Unit templates have been moved to folder-based structure.
|
|
8
4
|
|
|
9
|
-
|
|
5
|
+
See: `templates/` directory
|
|
10
6
|
|
|
11
|
-
|
|
7
|
+
- `templates/index.md` — Main unit overview
|
|
8
|
+
- `templates/data-model.md` — Database schema
|
|
9
|
+
- `templates/events-index.md` — Events overview
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
**Type:** {{module/domain/entity/service/feature}}
|
|
16
|
-
|
|
17
|
-
**Key Characteristics:**
|
|
18
|
-
- {{characteristic_1}}
|
|
19
|
-
- {{characteristic_2}}
|
|
20
|
-
|
|
21
|
-
<!-- e.g.
|
|
22
|
-
Task is responsible for representing a unit of work in the system. It owns title, description, status, and due date, and provides CRUD operations and status transitions to other parts of the system.
|
|
23
|
-
|
|
24
|
-
**Type:** entity
|
|
25
|
-
|
|
26
|
-
**Key Characteristics:**
|
|
27
|
-
- Immutable ID after creation
|
|
28
|
-
- Status follows defined workflow
|
|
29
|
-
- Always belongs to one workspace
|
|
30
|
-
-->
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## Boundaries
|
|
35
|
-
|
|
36
|
-
| Aspect | Details |
|
|
37
|
-
|--------|---------|
|
|
38
|
-
| **Owns** | {{data_and_behavior}} |
|
|
39
|
-
| **Uses** | → Unit: `{{dependency}}` |
|
|
40
|
-
| **Provides** | {{exposed_operations}} |
|
|
41
|
-
|
|
42
|
-
**Notes:**
|
|
43
|
-
- {{boundary_clarification}}
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## Data Model
|
|
48
|
-
|
|
49
|
-
| Field | Type | Constraints | Description |
|
|
50
|
-
|-------|------|-------------|-------------|
|
|
51
|
-
| id | {{type}} | PK | Primary identifier |
|
|
52
|
-
| {{field}} | {{type}} | {{constraints}} | {{description}} |
|
|
53
|
-
| {{field}} | {{type}} | {{constraints}} | {{description}} |
|
|
54
|
-
|
|
55
|
-
<!-- e.g.
|
|
56
|
-
| id | UUID | PK | Primary identifier |
|
|
57
|
-
| title | string | required, max 200 | Task title |
|
|
58
|
-
| status | enum | required | todo, in_progress, done |
|
|
59
|
-
| assignee_id | UUID | FK → User, nullable | Assigned user |
|
|
60
|
-
| due_date | datetime | nullable | Deadline |
|
|
61
|
-
-->
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## Relations
|
|
66
|
-
|
|
67
|
-
```
|
|
68
|
-
{{this}} ──► {{other}} ({{relation_type}})
|
|
69
|
-
{{this}} ──< {{other}} ({{relation_type}})
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
| Relation | Target | Type | Description |
|
|
73
|
-
|----------|--------|------|-------------|
|
|
74
|
-
| {{name}} | → Unit: `{{target}}` | {{1:1/1:N/N:M}} | {{description}} |
|
|
75
|
-
|
|
76
|
-
<!-- e.g.
|
|
77
|
-
| assignee | → Unit: `User` | N:1 | Task assigned to user |
|
|
78
|
-
| comments | → Unit: `Comment` | 1:N | Task has many comments |
|
|
79
|
-
| tags | → Unit: `Tag` | N:M | Task can have multiple tags |
|
|
80
|
-
-->
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
## Operations
|
|
85
|
-
|
|
86
|
-
| Operation | Input | Output | Description |
|
|
87
|
-
|-----------|-------|--------|-------------|
|
|
88
|
-
| {{op}} | {{params}} | {{result}} | {{what_it_does}} |
|
|
89
|
-
|
|
90
|
-
**Business Rules:**
|
|
91
|
-
- {{rule}}
|
|
92
|
-
|
|
93
|
-
<!-- e.g.
|
|
94
|
-
| Create | title, description | Task | Creates new task with status=todo |
|
|
95
|
-
| Assign | task_id, user_id | Task | Assigns task to user |
|
|
96
|
-
| ChangeStatus | task_id, new_status | Task | Transitions status |
|
|
97
|
-
|
|
98
|
-
**Business Rules:**
|
|
99
|
-
- Cannot assign to deactivated user
|
|
100
|
-
- Status can only move forward (todo→progress→done)
|
|
101
|
-
-->
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
## State Machine
|
|
106
|
-
|
|
107
|
-
```
|
|
108
|
-
{{state_1}} ──► {{state_2}} ──► {{state_3}}
|
|
109
|
-
│ │
|
|
110
|
-
└──────────────┘ ({{condition}})
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
| State | Description | Transitions To |
|
|
114
|
-
|-------|-------------|----------------|
|
|
115
|
-
| {{state}} | {{meaning}} | {{next_states}} |
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## Errors
|
|
120
|
-
|
|
121
|
-
| Error | Code | When |
|
|
122
|
-
|-------|------|------|
|
|
123
|
-
| {{error}} | {{code}} | {{condition}} |
|
|
124
|
-
|
|
125
|
-
<!-- e.g.
|
|
126
|
-
| TaskNotFound | TASK_001 | Task with ID doesn't exist |
|
|
127
|
-
| InvalidTransition | TASK_002 | Status change not allowed |
|
|
128
|
-
| AssigneeInactive | TASK_003 | Cannot assign to deactivated user |
|
|
129
|
-
-->
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## References
|
|
134
|
-
|
|
135
|
-
→ Architecture: `{{path}}`
|
|
136
|
-
→ Related: → Unit: `{{related}}`
|
|
11
|
+
Refer to `SKILL.md` for usage instructions.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# {{Unit Name}} Data Model
|
|
2
|
+
|
|
3
|
+
**Version:** 1.0
|
|
4
|
+
**Date:** {{YYYY-MM-DD}}
|
|
5
|
+
**Status:** Active
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Design Principles
|
|
10
|
+
|
|
11
|
+
| Principle | Description |
|
|
12
|
+
|-----------|-------------|
|
|
13
|
+
| {{Principle}} | {{Why this matters}} |
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Entity Relationship Diagram
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
{{ASCII or Mermaid diagram}}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Tables
|
|
26
|
+
|
|
27
|
+
### {{Table Name}}
|
|
28
|
+
|
|
29
|
+
{{Purpose of this table}}
|
|
30
|
+
|
|
31
|
+
| Field | Type | Constraints | Description |
|
|
32
|
+
|-------|------|-------------|-------------|
|
|
33
|
+
| id | UUID | PK | Primary identifier |
|
|
34
|
+
| {{field}} | {{type}} | {{constraints}} | {{description}} |
|
|
35
|
+
|
|
36
|
+
**Indexes:**
|
|
37
|
+
- `({{fields}})` — {{purpose}}
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Relations
|
|
42
|
+
|
|
43
|
+
| Relation | Type | Description |
|
|
44
|
+
|----------|------|-------------|
|
|
45
|
+
| {{table_a}} → {{table_b}} | 1:N | {{description}} |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Status Lifecycle
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
{{state_a}} ──► {{state_b}} ──► {{state_c}}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| Status | Description | Transitions To |
|
|
56
|
+
|--------|-------------|----------------|
|
|
57
|
+
| {{status}} | {{meaning}} | {{allowed_next}} |
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# {{Name}}
|
|
2
|
+
|
|
3
|
+
```yaml
|
|
4
|
+
type: entity
|
|
5
|
+
status: draft | approved
|
|
6
|
+
version: "1.0"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
{{What this entity represents, its role in the domain.}}
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Boundaries
|
|
18
|
+
|
|
19
|
+
| Aspect | Details |
|
|
20
|
+
|--------|---------|
|
|
21
|
+
| **Owns** | {{fields, behavior}} |
|
|
22
|
+
| **Part of** | {{parent domain/module path}} |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Data Model
|
|
27
|
+
|
|
28
|
+
| Field | Type | Constraints | Description |
|
|
29
|
+
|-------|------|-------------|-------------|
|
|
30
|
+
| id | UUID | PK | Primary identifier |
|
|
31
|
+
| {{field}} | {{type}} | {{constraints}} | {{description}} |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Relations
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
{{Entity}} ──► {{Other}} ({{type}})
|
|
39
|
+
{{Entity}} ──< {{Other}} ({{type}})
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
| Relation | Target | Type | Description |
|
|
43
|
+
|----------|--------|------|-------------|
|
|
44
|
+
| {{name}} | {{target}} | N:1 / 1:N / N:M | {{description}} |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## State Machine
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
{{state_a}} ──► {{state_b}} ──► {{state_c}}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
| State | Description | Transitions To |
|
|
55
|
+
|-------|-------------|----------------|
|
|
56
|
+
| {{state}} | {{meaning}} | {{allowed_next}} |
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Operations
|
|
61
|
+
|
|
62
|
+
| Operation | Input | Output | Description |
|
|
63
|
+
|-----------|-------|--------|-------------|
|
|
64
|
+
| Create | {{params}} | Entity | {{description}} |
|
|
65
|
+
| {{op}} | {{params}} | {{result}} | {{description}} |
|
|
66
|
+
|
|
67
|
+
**Business Rules:**
|
|
68
|
+
- {{rule}}
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Errors
|
|
73
|
+
|
|
74
|
+
| Error | Code | When |
|
|
75
|
+
|-------|------|------|
|
|
76
|
+
| {{Error}} | {{CODE}} | {{condition}} |
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## References
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
→ Parent: {{parent path}}
|
|
84
|
+
→ Related: {{related path}}
|
|
85
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# {{Unit Name}} Events
|
|
2
|
+
|
|
3
|
+
**Version:** 1.0
|
|
4
|
+
**Date:** {{YYYY-MM-DD}}
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
{{Brief description of event patterns in this unit}}
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Event Flow
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
{{ASCII diagram: sources → processing → sinks}}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Topics
|
|
23
|
+
|
|
24
|
+
### Produced Events
|
|
25
|
+
|
|
26
|
+
| Topic | Events | Key | Description |
|
|
27
|
+
|-------|--------|-----|-------------|
|
|
28
|
+
| {{topic}} | {{EventType}} | {{partition_key}} | {{description}} |
|
|
29
|
+
|
|
30
|
+
### Consumed Events
|
|
31
|
+
|
|
32
|
+
| Topic | Events | Source |
|
|
33
|
+
|-------|--------|--------|
|
|
34
|
+
| {{topic}} | {{EventType}} | {{source_system}} |
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Schema Files
|
|
39
|
+
|
|
40
|
+
| Schema | Description |
|
|
41
|
+
|--------|-------------|
|
|
42
|
+
| [{{event}}.avsc]({{event}}.avsc) | {{description}} |
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# {{Name}}
|
|
2
|
+
|
|
3
|
+
```yaml
|
|
4
|
+
type: module | domain | service | entity
|
|
5
|
+
status: draft | approved
|
|
6
|
+
version: "1.0"
|
|
7
|
+
created: {{YYYY-MM-DD}}
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
{{One paragraph describing what this unit does, what problem it solves, and key characteristics.}}
|
|
15
|
+
|
|
16
|
+
**Not responsible for:**
|
|
17
|
+
- {{What this unit explicitly doesn't handle}}
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Boundaries
|
|
22
|
+
|
|
23
|
+
| Aspect | Details |
|
|
24
|
+
|--------|---------|
|
|
25
|
+
| **Owns** | {{tables, domain objects, behavior}} |
|
|
26
|
+
| **Uses** | → Unit: `{{dependency}}` ({{purpose}}) |
|
|
27
|
+
| **Provides** | {{APIs, events, services to others}} |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Architecture
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
{{ASCII diagram showing high-level structure}}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Documents
|
|
40
|
+
|
|
41
|
+
| Document | Description |
|
|
42
|
+
|----------|-------------|
|
|
43
|
+
| [data-model.md](data-model.md) | Database schema |
|
|
44
|
+
| [api/](api/) | API specifications |
|
|
45
|
+
| [events/](events/) | Event schemas |
|
|
46
|
+
|
|
47
|
+
## Child Units
|
|
48
|
+
|
|
49
|
+
| Unit | Type | Description |
|
|
50
|
+
|------|------|-------------|
|
|
51
|
+
| [services/{{service}}/](services/{{service}}/) | service | {{description}} |
|
|
52
|
+
| [domains/{{domain}}/](domains/{{domain}}/) | domain | {{description}} |
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## References
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
→ Architecture: docs/architecture.md
|
|
60
|
+
→ Related: modules/{{related}}/ or services/{{related}}/
|
|
61
|
+
```
|