@drunkcoding/dknet-implementation-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/.claude-plugin/marketplace.json +22 -0
- package/.claude-plugin/plugin.json +38 -0
- package/LICENSE +21 -0
- package/README.md +261 -0
- package/agents/dknet-architect.md +49 -0
- package/agents/dknet-bdd-engineer.md +62 -0
- package/agents/dknet-implementer.md +75 -0
- package/package.json +52 -0
- package/plugin.json +26 -0
- package/skills/README.md +47 -0
- package/skills/dknet-auth-and-ownership/SKILL.md +418 -0
- package/skills/dknet-bdd-tests/SKILL.md +355 -0
- package/skills/dknet-bdd-tests/checklist.md +39 -0
- package/skills/dknet-crud/SKILL.md +483 -0
- package/skills/dknet-ddd-principles/SKILL.md +87 -0
- package/skills/dknet-docs/SKILL.md +296 -0
- package/skills/dknet-docs/checklist.md +58 -0
- package/skills/dknet-docs/templates/README-template.md +68 -0
- package/skills/dknet-docs/templates/api-reference-template.md +275 -0
- package/skills/dknet-docs/templates/architecture-template.md +166 -0
- package/skills/dknet-docs/templates/data-model-template.md +99 -0
- package/skills/dknet-docs/templates/events-template.md +155 -0
- package/skills/dknet-dto-mapping/SKILL.md +278 -0
- package/skills/dknet-efcore-config/SKILL.md +379 -0
- package/skills/dknet-endpoint/SKILL.md +458 -0
- package/skills/dknet-entity/SKILL.md +483 -0
- package/skills/dknet-feature/SKILL.md +139 -0
- package/skills/dknet-feature-lifecycle/SKILL.md +144 -0
- package/skills/dknet-feature-remove/SKILL.md +131 -0
- package/skills/dknet-messaging-events/SKILL.md +395 -0
- package/skills/dknet-package-adoption/SKILL.md +252 -0
- package/skills/dknet-platform-config/SKILL.md +342 -0
- package/skills/dknet-project-structure/SKILL.md +148 -0
- package/skills/dknet-queries-specs/SKILL.md +330 -0
- package/skills/dknet-scaffold/SKILL.md +209 -0
- package/skills/dknet-unit-tests/SKILL.md +382 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dknet-docs
|
|
3
|
+
description: Generate structured technical documentation and Mermaid architecture diagrams for completed features. Use this when documenting implemented features with README, architecture diagrams, and API references. Invoke as `/dknet-docs <Feature>` to scaffold it for a feature.
|
|
4
|
+
metadata:
|
|
5
|
+
kind: workflow
|
|
6
|
+
arguments: "<Feature>"
|
|
7
|
+
allowed-tools: Read, Grep, Glob, Edit, Write, Bash
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Usage: `/dknet-docs <Feature>`
|
|
11
|
+
|
|
12
|
+
# Skill: Feature Documentation with Diagrams
|
|
13
|
+
|
|
14
|
+
**Duration**: 30–60 minutes | **Difficulty**: Beginner | **Category**: Documentation & Knowledge Management
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Overview
|
|
19
|
+
|
|
20
|
+
**When to use this skill**: After completing a feature (Domain Modeling → CRUD Operations → API Endpoints). Document it so any developer can understand, maintain, and extend the feature without digging through code.
|
|
21
|
+
|
|
22
|
+
**What you'll create**: Five structured markdown documents under `docs/features/<feature-name>/`:
|
|
23
|
+
|
|
24
|
+
| File | Purpose |
|
|
25
|
+
|------|---------|
|
|
26
|
+
| `README.md` | Overview, purpose, usage summary |
|
|
27
|
+
| `architecture.md` | Vertical slice diagram, component responsibilities, data flow |
|
|
28
|
+
| `api-reference.md` | All endpoints with request/response examples and curl commands |
|
|
29
|
+
| `data-model.md` | Entity diagram, properties, constraints, relationships |
|
|
30
|
+
| `events.md` | Domain events catalog with publishers and subscribers |
|
|
31
|
+
|
|
32
|
+
**Diagram tool**: All diagrams use **Mermaid.js** — rendered natively in GitHub, VS Code Preview, and most wikis. No extra tools required.
|
|
33
|
+
|
|
34
|
+
**Real examples already in this repo**: this skill is about documenting a *new* feature you just
|
|
35
|
+
built, not about the two worked samples that ship with the template — but those samples
|
|
36
|
+
(`ManualSample/PurchaseOrder` and `AutomatedSample/Product`) are the best current reference for what
|
|
37
|
+
"good enough to hand to another developer" looks like in this codebase. Skim their code before
|
|
38
|
+
writing your own docs — they show the level of detail and the "what does the developer give up"
|
|
39
|
+
framing this repo expects, even though the samples themselves don't ship their own per-feature docs
|
|
40
|
+
in the five-document structure below.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Prerequisites: Do You Know This?
|
|
45
|
+
|
|
46
|
+
- [ ] Feature is implemented (Domain Entity, CRUD handlers, endpoints)
|
|
47
|
+
- [ ] Comfortable writing markdown
|
|
48
|
+
- [ ] Can read C# class definitions and extract relevant info
|
|
49
|
+
- [ ] Know what API endpoints were created (HTTP method, route, request/response)
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Inputs Checklist
|
|
54
|
+
|
|
55
|
+
Collect this before you start:
|
|
56
|
+
|
|
57
|
+
- [ ] **Feature name** (e.g., `PurchaseOrder`, `Product`, `Invoices`)
|
|
58
|
+
- [ ] **Purpose**: What business problem does it solve? (1–2 sentences)
|
|
59
|
+
- [ ] **Entity properties**: All fields with types and constraints
|
|
60
|
+
- [ ] **Entity relationships**: Foreign keys and navigation properties
|
|
61
|
+
- [ ] **API endpoints**: HTTP method, route, request/response shape
|
|
62
|
+
- [ ] **Domain events**: Names, publishers, subscribers
|
|
63
|
+
- [ ] **Business rules**: Validation, uniqueness, state transitions
|
|
64
|
+
- [ ] **Status/State model**: Does the entity have status fields? What are the transitions?
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Step-by-Step Workflow
|
|
69
|
+
|
|
70
|
+
### Step 1: Create the Feature Docs Folder
|
|
71
|
+
|
|
72
|
+
**Convention**: All feature docs must live in `docs/features/<feature-name>/`.
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
mkdir -p docs/features/purchase-orders
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Naming convention**:
|
|
79
|
+
- Folder name: `kebab-case` (e.g., `purchase-orders`, `order-management`)
|
|
80
|
+
- File names: lowercase with hyphens (e.g., `api-reference.md`, `data-model.md`)
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
### Step 2: Write README.md (Overview)
|
|
85
|
+
|
|
86
|
+
**What you're doing**: A self-contained landing page that answers: *what is this feature, why does it exist, and how do I use it?*
|
|
87
|
+
|
|
88
|
+
**Target audience**: Any developer new to the feature (including your future self).
|
|
89
|
+
|
|
90
|
+
Copy `templates/README-template.md` from this skill's folder and fill it in — What Is This?, Why Does It Exist?, Quick Start, Key Concepts, Feature Map, Related Documentation.
|
|
91
|
+
|
|
92
|
+
Example Quick Start entry (from the `PurchaseOrder` sample):
|
|
93
|
+
|
|
94
|
+
```http
|
|
95
|
+
POST /v1/purchase-orders
|
|
96
|
+
Content-Type: application/json
|
|
97
|
+
Authorization: Bearer {token}
|
|
98
|
+
X-Idempotency-Key: 6e6f4d3c-1b7e-4c7a-9f1d-8a2b5c6d7e01
|
|
99
|
+
|
|
100
|
+
{
|
|
101
|
+
"customerName": "Acme Pte Ltd",
|
|
102
|
+
"amount": 1250.00
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
### Step 3: Write architecture.md (Diagrams + Data Flow)
|
|
109
|
+
|
|
110
|
+
**What you're doing**: Show how the feature is structured across layers with a vertical slice diagram. Use Mermaid for all diagrams.
|
|
111
|
+
|
|
112
|
+
**Five diagrams to include**:
|
|
113
|
+
|
|
114
|
+
1. **Vertical Slice Overview** — All layers and their responsibilities
|
|
115
|
+
2. **Request Sequence Diagram** — How a POST (create) flows through the system
|
|
116
|
+
3. **Component Diagram** — Classes/files and their relationships
|
|
117
|
+
4. **State Diagram** — Status transitions (if entity has status field)
|
|
118
|
+
5. **Event Flow Diagram** — Domain events and consumers
|
|
119
|
+
|
|
120
|
+
Copy `templates/architecture-template.md` from this skill's folder and fill it in — Vertical Slice Overview, Sequence Diagram, Component Diagram, Status State Machine, Event Flow, Layer Responsibilities. Document only the transitions actual handler code performs in the State Machine — don't document an enum member as reachable just because it exists.
|
|
121
|
+
|
|
122
|
+
Example Vertical Slice Overview diagram (from the `PurchaseOrder` sample):
|
|
123
|
+
|
|
124
|
+
```mermaid
|
|
125
|
+
graph TD
|
|
126
|
+
Client["Client / Browser"]
|
|
127
|
+
subgraph API["Minimal.Api"]
|
|
128
|
+
EP["PurchaseOrderV1Endpoint.cs"]
|
|
129
|
+
end
|
|
130
|
+
subgraph AppServices["Minimal.AppServices"]
|
|
131
|
+
HDL["Command Handlers"]
|
|
132
|
+
end
|
|
133
|
+
subgraph Domains["Minimal.Domains"]
|
|
134
|
+
ENT["PurchaseOrder (AggregateRoot)"]
|
|
135
|
+
end
|
|
136
|
+
DB[("PostgreSQL")]
|
|
137
|
+
Client -->|HTTP| EP --> HDL --> ENT --> DB
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
### Step 4: Write api-reference.md (Endpoint Reference)
|
|
143
|
+
|
|
144
|
+
**What you're doing**: Full endpoint documentation with curl examples, request/response schemas, and error codes.
|
|
145
|
+
|
|
146
|
+
Copy `templates/api-reference-template.md` from this skill's folder and fill it in — Endpoints Summary table, one section per endpoint (query params/request body, response, error table, curl example), Common Error Response Format. Note the pagination-defaults gotcha: a hand-written list query's `pageIndex`/`pageSize` defaults differ from the generated `MapGetList` route's contract (`pageNumber`/`pageSize` default 1/1000, configurable ceiling via `DKNet:ListQuery`, plus `fromDate`/`toDate` windowing) — document whichever contract this feature's route actually uses. Also document the standard error format: `result.Response()` (`DKNet.AspCore.Extensions.Responses`) converts a failed `FluentResults` result into `ProblemDetails` with messages under an `errors` array; a `NotFoundError` produces the same shape with `status: 404`.
|
|
147
|
+
|
|
148
|
+
Example endpoint entry (from the `PurchaseOrder` sample):
|
|
149
|
+
|
|
150
|
+
```markdown
|
|
151
|
+
## POST /v1/purchase-orders
|
|
152
|
+
|
|
153
|
+
Creates a new purchase order. **Requires** an idempotency key header.
|
|
154
|
+
|
|
155
|
+
| Field | Type | Required | Rules |
|
|
156
|
+
|-------|------|----------|-------|
|
|
157
|
+
| `customerName` | string | ✓ | 1–200 characters |
|
|
158
|
+
| `amount` | decimal | ✓ | Must be greater than 0 |
|
|
159
|
+
|
|
160
|
+
**Response** `201 Created` — a `PurchaseOrderDto` with `status: "Placed"`.
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
### Step 5: Write data-model.md (Entity Diagram)
|
|
166
|
+
|
|
167
|
+
**What you're doing**: Document the entity schema, constraints, relationships, and EF Core mapping config.
|
|
168
|
+
|
|
169
|
+
Copy `templates/data-model-template.md` from this skill's folder and fill it in — Entity Relationship Diagram, Properties table, EF Core Mapping Configuration (table/schema, indexes, enum storage, seed data), Validation Rules.
|
|
170
|
+
|
|
171
|
+
Example ER diagram (from the `PurchaseOrder` sample):
|
|
172
|
+
|
|
173
|
+
```mermaid
|
|
174
|
+
erDiagram
|
|
175
|
+
PURCHASE_ORDER {
|
|
176
|
+
uniqueidentifier Id PK "Auto-generated GUID"
|
|
177
|
+
nvarchar(200) CustomerName "Not null, indexed"
|
|
178
|
+
decimal_18_2 Amount "Not null"
|
|
179
|
+
nvarchar Status "Draft / Placed / Cancelled"
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
### Step 6: Write events.md (Domain Events Catalog)
|
|
186
|
+
|
|
187
|
+
**What you're doing**: Catalog all domain events published and consumed by this feature so other teams know how to subscribe.
|
|
188
|
+
|
|
189
|
+
Copy `templates/events-template.md` from this skill's folder and fill it in — Events Published (per event: publisher, payload, subscribers table, example handler usage), Events Consumed, Event Bus Configuration, Event Flow diagram.
|
|
190
|
+
|
|
191
|
+
Example event entry (from the `PurchaseOrder` sample):
|
|
192
|
+
|
|
193
|
+
```csharp
|
|
194
|
+
public sealed record PurchaseOrderCreatedEvent(Guid Id, string CustomerName, decimal Amount);
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
| Subscriber | Bus | Action |
|
|
198
|
+
|-----------|-----|--------|
|
|
199
|
+
| `PurchaseOrderCreatedEventHandler` | In-Memory | Logs at Information level |
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Document Naming Conventions
|
|
204
|
+
|
|
205
|
+
| Document | File Name | Description |
|
|
206
|
+
|----------|-----------|-------------|
|
|
207
|
+
| Overview + quick start | `README.md` | Always required |
|
|
208
|
+
| Architecture + diagrams | `architecture.md` | Required when using vertical slices |
|
|
209
|
+
| API endpoint reference | `api-reference.md` | Required for any REST-exposed feature |
|
|
210
|
+
| Entity + data model | `data-model.md` | Required for any persisted entity |
|
|
211
|
+
| Domain events | `events.md` | Required when events are published/consumed |
|
|
212
|
+
| Configuration guide | `configuration.md` | Optional — for features with settings/flags |
|
|
213
|
+
| ADR (decision records) | `decisions/adr-001-*.md` | Optional — when major tradeoffs were made |
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Mermaid Diagram Types Reference
|
|
218
|
+
|
|
219
|
+
Use appropriate Mermaid diagram types for different aspects:
|
|
220
|
+
|
|
221
|
+
| Diagram type | Mermaid keyword | When to use |
|
|
222
|
+
|-------------|-----------------|-------------|
|
|
223
|
+
| Component flow | `graph TD` / `graph LR` | Overview of layers, event flows |
|
|
224
|
+
| Request sequence | `sequenceDiagram` | How a specific API call flows step-by-step |
|
|
225
|
+
| Entity classes | `classDiagram` | Class relationships and properties |
|
|
226
|
+
| Entity-Relation | `erDiagram` | Database table structure |
|
|
227
|
+
| State machine | `stateDiagram-v2` | Status transitions |
|
|
228
|
+
| Timeline | `timeline` | Feature evolution, release history |
|
|
229
|
+
|
|
230
|
+
**All Mermaid diagrams are fenced code blocks**:
|
|
231
|
+
|
|
232
|
+
````md
|
|
233
|
+
```mermaid
|
|
234
|
+
graph TD
|
|
235
|
+
A --> B
|
|
236
|
+
```
|
|
237
|
+
````
|
|
238
|
+
|
|
239
|
+
They render automatically on GitHub, GitLab, VS Code (Markdown Preview), Docusaurus, and most modern wikis.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Feature Docs Folder Structure
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
docs/
|
|
247
|
+
└── features/
|
|
248
|
+
└── purchase-orders/ ← kebab-case folder name
|
|
249
|
+
├── README.md ← Overview (START HERE)
|
|
250
|
+
├── architecture.md ← Diagrams + vertical slice
|
|
251
|
+
├── api-reference.md ← Endpoints + examples + curl
|
|
252
|
+
├── data-model.md ← Entity diagram + constraints
|
|
253
|
+
├── events.md ← Domain events + subscribers
|
|
254
|
+
└── decisions/ ← Optional ADRs
|
|
255
|
+
└── adr-001-idempotency-key-strategy.md
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
# Workflow: `/dknet-docs`
|
|
261
|
+
|
|
262
|
+
The procedure an agent follows when invoked with arguments. The reference sections above are the rules it applies.
|
|
263
|
+
|
|
264
|
+
You are producing authoritative feature documentation for a vertical slice that is already implemented and tested.
|
|
265
|
+
|
|
266
|
+
### Required reading
|
|
267
|
+
|
|
268
|
+
1. The reference sections above
|
|
269
|
+
2. this skill's `templates/` folder` (README, architecture, data-model, events, api-reference templates).
|
|
270
|
+
3. The two shipped sample slices (`ManualSample/PurchaseOrder`, `AutomatedSample/Product`) — document against the code, and use their existing feature docs (if the solution kept them) for shape and voice.
|
|
271
|
+
|
|
272
|
+
### Steps
|
|
273
|
+
|
|
274
|
+
1. Inspect the implemented slice to harvest facts: entity properties, mapper indexes, request/response DTOs, validator rules, endpoint routes, event names, test coverage.
|
|
275
|
+
Determine which flow the slice uses (a `[CrudCreate]` on the entity means the automated flow) and
|
|
276
|
+
document it explicitly — a reader cannot tell from the route table alone, and the two flows differ
|
|
277
|
+
in behavior a consumer will hit:
|
|
278
|
+
- whether the create route is idempotent (`X-Idempotency-Key`),
|
|
279
|
+
- whether validation is enforced (it is **not** on generated routes — say so plainly rather than
|
|
280
|
+
listing a `[Range]` as if it returns `400`),
|
|
281
|
+
- how the acting user is attributed (`[FromClaim]` vs `DataOwnerHook`).
|
|
282
|
+
For automated slices, read event names off the compiled assembly, not off a guess at the
|
|
283
|
+
composition rule.
|
|
284
|
+
2. Render the four required artifacts under `docs/features/<feature>/` (or `docs/<feature>/` if the slice is template-internal):
|
|
285
|
+
- `README.md` (feature overview + quick links)
|
|
286
|
+
- `architecture.md` (Mermaid diagrams: layer flow, sequence for Create, ER snippet)
|
|
287
|
+
- `data-model.md`
|
|
288
|
+
- `api-reference.md`
|
|
289
|
+
3. Cross-link from `docs/features/README.md` (or whichever index file lists features).
|
|
290
|
+
4. Verify all referenced files exist and Mermaid blocks render (no stray fences).
|
|
291
|
+
|
|
292
|
+
### Constraints
|
|
293
|
+
|
|
294
|
+
- Do not invent fields, validators, events, or endpoints — only document what's in the code.
|
|
295
|
+
- Use the templates in the skill folder verbatim where they fit; deviations need a one-line note.
|
|
296
|
+
- No hand-wavey language ("flexible", "robust", "scalable") — describe what the code actually does.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Quick Validation Checklist: Feature Documentation
|
|
2
|
+
|
|
3
|
+
## Folder Structure
|
|
4
|
+
- [ ] Feature docs folder created at `docs/features/<feature-name>/` (kebab-case)
|
|
5
|
+
- [ ] All 5 required documents are present
|
|
6
|
+
|
|
7
|
+
## README.md (Overview)
|
|
8
|
+
- [ ] Explains **what** the feature does (1-2 sentences)
|
|
9
|
+
- [ ] Explains **why** it exists (business value, problem solved)
|
|
10
|
+
- [ ] Contains quick-start code example (at minimum one HTTP example)
|
|
11
|
+
- [ ] Lists all key concepts in a table
|
|
12
|
+
- [ ] Contains a **Feature Map** table linking to source files across layers
|
|
13
|
+
- [ ] Links to all other docs (architecture, api-reference, data-model, events)
|
|
14
|
+
|
|
15
|
+
## architecture.md (Diagrams)
|
|
16
|
+
- [ ] **Vertical Slice Diagram** (`graph TD`) shows all layers (Api → AppServices → Domains → Infra)
|
|
17
|
+
- [ ] **Sequence Diagram** shows the full request flow for at least one write operation (e.g., Create)
|
|
18
|
+
- [ ] **Component Diagram** (`classDiagram`) shows key classes and their relationships
|
|
19
|
+
- [ ] **State Diagram** (`stateDiagram-v2`) present if entity has status/state (e.g. `PurchaseOrder`'s `Draft`/`Placed`/`Cancelled`)
|
|
20
|
+
- [ ] **Event Flow Diagram** shows publishers and subscribers
|
|
21
|
+
- [ ] All diagrams use Mermaid (render in GitHub natively)
|
|
22
|
+
- [ ] Layer responsibilities table lists each layer's role in this specific feature
|
|
23
|
+
|
|
24
|
+
## api-reference.md (Endpoint Reference)
|
|
25
|
+
- [ ] Summary table lists ALL endpoints (Method / Path / Description / Auth)
|
|
26
|
+
- [ ] Each endpoint has: description, request body or params, response body example (JSON)
|
|
27
|
+
- [ ] Request field tables show: field name, type, required flag, validation rules
|
|
28
|
+
- [ ] Each endpoint has at least one `curl` example that can be copy-pasted
|
|
29
|
+
- [ ] Error response table lists all possible error status codes and reasons
|
|
30
|
+
- [ ] Common `ProblemDetails` error format documented at end
|
|
31
|
+
- [ ] Custom action endpoints beyond plain CRUD (e.g. `PurchaseOrder`'s `POST {id}/cancel`) documented
|
|
32
|
+
- [ ] GET list endpoint documents all query parameters (pagination, sorting, filtering)
|
|
33
|
+
|
|
34
|
+
## data-model.md (Data Model)
|
|
35
|
+
- [ ] `erDiagram` (Mermaid ER diagram) shows all columns with types and constraints
|
|
36
|
+
- [ ] Properties table lists every field with C# type, DB column name, and constraints
|
|
37
|
+
- [ ] Unique indexes documented
|
|
38
|
+
- [ ] EF Core mapping notes (table name, schema, global query filters)
|
|
39
|
+
- [ ] Validation rules table (field → rule → enforcement mechanism)
|
|
40
|
+
- [ ] Related entities shown if any foreign key relationships exist
|
|
41
|
+
|
|
42
|
+
## events.md (Domain Events)
|
|
43
|
+
- [ ] Each published event documented with: name, publisher, payload (record definition)
|
|
44
|
+
- [ ] Payload property table (name, type, description)
|
|
45
|
+
- [ ] Known subscribers table (handler class name, bus type, action description)
|
|
46
|
+
- [ ] Code example showing how to subscribe to the event
|
|
47
|
+
- [ ] "Events Consumed" section present (or explicitly states "none")
|
|
48
|
+
- [ ] Event bus configuration documented (In-Memory vs Azure Service Bus conditions)
|
|
49
|
+
- [ ] Mermaid event flow diagram showing publish and subscribe flow
|
|
50
|
+
|
|
51
|
+
## Quality Standards
|
|
52
|
+
- [ ] All file names are lowercase with hyphens (`api-reference.md`, not `ApiReference.md`)
|
|
53
|
+
- [ ] Folder name uses kebab-case (`purchase-orders`, not `PurchaseOrders`)
|
|
54
|
+
- [ ] All internal links work (relative links between docs)
|
|
55
|
+
- [ ] No broken Mermaid diagrams (test by opening in VS Code Preview or GitHub)
|
|
56
|
+
- [ ] JSON examples are valid (check with a formatter)
|
|
57
|
+
- [ ] All source file paths in the Feature Map table are correct and files exist
|
|
58
|
+
- [ ] No placeholder text left (e.g., `{todo}`, `replace this`, etc.)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# {FeatureName}
|
|
2
|
+
|
|
3
|
+
> {One sentence: what this feature manages/does.}
|
|
4
|
+
|
|
5
|
+
## What Is This?
|
|
6
|
+
|
|
7
|
+
{2–4 sentences describing the feature. What entity does it manage? What lifecycle does it support?
|
|
8
|
+
What key behaviors does it provide? Who are the consumers of this feature?}
|
|
9
|
+
|
|
10
|
+
## Why Does It Exist?
|
|
11
|
+
|
|
12
|
+
{The business problem this feature solves. List 2–4 bullet points explaining:
|
|
13
|
+
- What it enables
|
|
14
|
+
- What compliance or workflow it supports
|
|
15
|
+
- How it relates to other features}
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
### {Most common operation, e.g., Create a {Entity}}
|
|
20
|
+
|
|
21
|
+
```http
|
|
22
|
+
POST /api/v1/{feature-route}
|
|
23
|
+
Content-Type: application/json
|
|
24
|
+
Authorization: Bearer {token}
|
|
25
|
+
|
|
26
|
+
{
|
|
27
|
+
"field1": "value",
|
|
28
|
+
"field2": "value"
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Get a {Entity}
|
|
33
|
+
|
|
34
|
+
```http
|
|
35
|
+
GET /api/v1/{feature-route}/{id}
|
|
36
|
+
Authorization: Bearer {token}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Key Concepts
|
|
40
|
+
|
|
41
|
+
| Concept | Description |
|
|
42
|
+
|---------|-------------|
|
|
43
|
+
| **{ConceptName}** | {Brief explanation of what it is and why it matters} |
|
|
44
|
+
| **{ConceptName}** | {Brief explanation} |
|
|
45
|
+
| **Status** | Lifecycle state: `{State1} → {State2} / {State3}` |
|
|
46
|
+
| **Soft Delete** | Records are never hard-deleted; `IsDeleted = true` marks them inactive |
|
|
47
|
+
|
|
48
|
+
## Feature Map
|
|
49
|
+
|
|
50
|
+
> Source files for this feature across all layers.
|
|
51
|
+
|
|
52
|
+
| Layer | Path |
|
|
53
|
+
|-------|------|
|
|
54
|
+
| Domain Entity | `ApiEndpoints/Minimal.Domains/Features/{EntityFolder}/Entities/{EntityName}.cs` |
|
|
55
|
+
| EF Core Mapper | `ApiEndpoints/Minimal.Infra/Features/{EntityFolder}/Mappers/{EntityName}Mapper.cs` |
|
|
56
|
+
| Create Handler | `ApiEndpoints/Minimal.AppServices/{FeatureFolder}/V1/Actions/Create.cs` |
|
|
57
|
+
| Update Handler | `ApiEndpoints/Minimal.AppServices/{FeatureFolder}/V1/Actions/Update.cs` |
|
|
58
|
+
| Delete Handler | `ApiEndpoints/Minimal.AppServices/{FeatureFolder}/V1/Actions/Delete.cs` |
|
|
59
|
+
| Domain Events | `ApiEndpoints/Minimal.AppServices/{FeatureFolder}/V1/Events/` |
|
|
60
|
+
| Query Specs | `ApiEndpoints/Minimal.AppServices/{FeatureFolder}/V1/Specs/` |
|
|
61
|
+
| API Endpoints | `ApiEndpoints/Minimal.Api/ApiEndpoints/{EntityName}V1Endpoints.cs` |
|
|
62
|
+
|
|
63
|
+
## Related Documentation
|
|
64
|
+
|
|
65
|
+
- [Architecture](./architecture.md)
|
|
66
|
+
- [API Reference](./api-reference.md)
|
|
67
|
+
- [Data Model](./data-model.md)
|
|
68
|
+
- [Domain Events](./events.md)
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# {FeatureName} — API Reference
|
|
2
|
+
|
|
3
|
+
**Base Path**: `/api/v1/{feature-route}`
|
|
4
|
+
**Auth**: Bearer token required on all endpoints
|
|
5
|
+
**Content-Type**: `application/json`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Endpoints Summary
|
|
10
|
+
|
|
11
|
+
| Method | Path | Description | Auth |
|
|
12
|
+
|--------|------|-------------|------|
|
|
13
|
+
| `GET` | `/` | List {entities} (paginated) | ✓ |
|
|
14
|
+
| `GET` | `/{id}` | Get {entity} by ID | ✓ |
|
|
15
|
+
| `POST` | `/` | Create new {entity} | ✓ |
|
|
16
|
+
| `PUT` | `/{id}` | Update {entity} | ✓ |
|
|
17
|
+
| `DELETE` | `/{id}` | Soft-delete {entity} | ✓ |
|
|
18
|
+
| `PATCH` | `/{id}/approve` | Approve pending {entity} | ✓ Admin |
|
|
19
|
+
| `PATCH` | `/{id}/reject` | Reject pending {entity} | ✓ Admin |
|
|
20
|
+
|
|
21
|
+
> Remove rows that don't apply. Add custom actions as needed.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## GET /api/v1/{feature-route}
|
|
26
|
+
|
|
27
|
+
Returns a paginated list of {entities}.
|
|
28
|
+
|
|
29
|
+
**Query Parameters**
|
|
30
|
+
|
|
31
|
+
| Parameter | Type | Default | Description |
|
|
32
|
+
|-----------|------|---------|-------------|
|
|
33
|
+
| `pageNumber` | int | 1 | Page number (1-based) |
|
|
34
|
+
| `pageSize` | int | 1000 | Items per page (max 1000, clamped not rejected) |
|
|
35
|
+
| `search` | string | — | Filter by name or key fields |
|
|
36
|
+
| `sortBy` | string | `CreatedAt` | Field to sort by |
|
|
37
|
+
| `sortDirection` | string | `desc` | `asc` or `desc` |
|
|
38
|
+
| `fromDate` | ISO-8601 | — | Inclusive lower bound on when a record was last active |
|
|
39
|
+
| `toDate` | ISO-8601 | — | Inclusive upper bound on when a record was last active. Naming neither bound windows an audited listing to the last three months, not all history |
|
|
40
|
+
|
|
41
|
+
> The paging values above are the built-in defaults of `DKNet.AspCore.Extensions`' `MapGetList`, and a
|
|
42
|
+
> host can override them through `ListQueryOptions` (section `DKNet:ListQuery`). Check them against
|
|
43
|
+
> what your project configures. The full contract is in the `dknet-queries-specs` skill.
|
|
44
|
+
|
|
45
|
+
**Response** `200 OK`
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"items": [
|
|
50
|
+
{
|
|
51
|
+
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
|
|
52
|
+
"field1": "value",
|
|
53
|
+
"field2": "value",
|
|
54
|
+
"status": "Pending",
|
|
55
|
+
"createdAt": "2025-01-15T10:30:00Z",
|
|
56
|
+
"updatedAt": "2025-01-20T14:00:00Z"
|
|
57
|
+
}
|
|
58
|
+
],
|
|
59
|
+
"pageNumber": 1,
|
|
60
|
+
"pageSize": 10,
|
|
61
|
+
"totalCount": 100,
|
|
62
|
+
"totalPages": 10
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**curl Example**
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
curl -X GET "https://api.example.com/api/v1/{feature-route}?pageSize=10" \
|
|
70
|
+
-H "Authorization: Bearer {token}"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## GET /api/v1/{feature-route}/{id}
|
|
76
|
+
|
|
77
|
+
Returns a single {entity} by ID.
|
|
78
|
+
|
|
79
|
+
**Route Parameters**
|
|
80
|
+
|
|
81
|
+
| Parameter | Type | Description |
|
|
82
|
+
|-----------|------|-------------|
|
|
83
|
+
| `id` | `Guid` | The {entity} unique identifier |
|
|
84
|
+
|
|
85
|
+
**Response** `200 OK`
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
|
|
90
|
+
"field1": "value",
|
|
91
|
+
"field2": "value",
|
|
92
|
+
"status": "Pending",
|
|
93
|
+
"createdAt": "2025-01-15T10:30:00Z",
|
|
94
|
+
"updatedAt": "2025-01-20T14:00:00Z"
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Error Responses**
|
|
99
|
+
|
|
100
|
+
| Status | Reason |
|
|
101
|
+
|--------|--------|
|
|
102
|
+
| `404 Not Found` | No {entity} with this ID |
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## POST /api/v1/{feature-route}
|
|
107
|
+
|
|
108
|
+
Creates a new {entity}.
|
|
109
|
+
|
|
110
|
+
**Request Body**
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"field1": "value",
|
|
115
|
+
"field2": "value"
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
| Field | Type | Required | Rules |
|
|
120
|
+
|-------|------|----------|-------|
|
|
121
|
+
| `field1` | string | ✓ | {constraints, e.g., 2–150 characters} |
|
|
122
|
+
| `field2` | string | ✓ | {constraints, e.g., valid email, unique} |
|
|
123
|
+
| `field3` | string | — | {optional field rules} |
|
|
124
|
+
|
|
125
|
+
**Response** `201 Created`
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
|
|
130
|
+
"field1": "value",
|
|
131
|
+
"field2": "value",
|
|
132
|
+
"status": "Pending",
|
|
133
|
+
"createdAt": "2025-01-15T10:30:00Z",
|
|
134
|
+
"updatedAt": "2025-01-15T10:30:00Z"
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Error Responses**
|
|
139
|
+
|
|
140
|
+
| Status | Reason |
|
|
141
|
+
|--------|--------|
|
|
142
|
+
| `400 Bad Request` | Validation failure |
|
|
143
|
+
| `409 Conflict` | Duplicate value in unique field |
|
|
144
|
+
|
|
145
|
+
**curl Example**
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
curl -X POST "https://api.example.com/api/v1/{feature-route}" \
|
|
149
|
+
-H "Authorization: Bearer {token}" \
|
|
150
|
+
-H "Content-Type: application/json" \
|
|
151
|
+
-d '{"field1":"value","field2":"value"}'
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## PUT /api/v1/{feature-route}/{id}
|
|
157
|
+
|
|
158
|
+
Updates an existing {entity}. All fields are optional — only non-null fields are updated.
|
|
159
|
+
|
|
160
|
+
**Request Body**
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"field1": "updated value"
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
| Field | Type | Required | Rules |
|
|
169
|
+
|-------|------|----------|-------|
|
|
170
|
+
| `field1` | string | — | {constraints}; if null, current value preserved |
|
|
171
|
+
| `field2` | string | — | {constraints}; if null, current value preserved |
|
|
172
|
+
|
|
173
|
+
**Response** `200 OK` — Returns updated `{EntityName}Dto`.
|
|
174
|
+
|
|
175
|
+
**Error Responses**
|
|
176
|
+
|
|
177
|
+
| Status | Reason |
|
|
178
|
+
|--------|--------|
|
|
179
|
+
| `400 Bad Request` | All fields null (nothing to update) |
|
|
180
|
+
| `404 Not Found` | {Entity} not found |
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## DELETE /api/v1/{feature-route}/{id}
|
|
185
|
+
|
|
186
|
+
Soft-deletes the {entity}. The record is preserved with `IsDeleted = true`.
|
|
187
|
+
|
|
188
|
+
**Response** `204 No Content`
|
|
189
|
+
|
|
190
|
+
**Error Responses**
|
|
191
|
+
|
|
192
|
+
| Status | Reason |
|
|
193
|
+
|--------|--------|
|
|
194
|
+
| `404 Not Found` | {Entity} not found |
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## PATCH /api/v1/{feature-route}/{id}/approve
|
|
199
|
+
|
|
200
|
+
Approves a pending {entity}. Updates status to `Approved`.
|
|
201
|
+
|
|
202
|
+
> Remove this section if there is no approval workflow.
|
|
203
|
+
|
|
204
|
+
**Request Body**
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"reason": "Manually verified"
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
| Field | Type | Required | Rules |
|
|
213
|
+
|-------|------|----------|-------|
|
|
214
|
+
| `reason` | string | — | Optional audit comment; max 500 chars |
|
|
215
|
+
|
|
216
|
+
**Response** `200 OK` — Returns updated `{EntityName}Dto`.
|
|
217
|
+
|
|
218
|
+
**Error Responses**
|
|
219
|
+
|
|
220
|
+
| Status | Reason |
|
|
221
|
+
|--------|--------|
|
|
222
|
+
| `400 Bad Request` | {Entity} is not in Pending state |
|
|
223
|
+
| `404 Not Found` | {Entity} not found |
|
|
224
|
+
| `403 Forbidden` | User does not have Admin role |
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## PATCH /api/v1/{feature-route}/{id}/reject
|
|
229
|
+
|
|
230
|
+
Rejects a pending {entity}. Reason is **required** for audit trail.
|
|
231
|
+
|
|
232
|
+
> Remove this section if there is no rejection workflow.
|
|
233
|
+
|
|
234
|
+
**Request Body**
|
|
235
|
+
|
|
236
|
+
```json
|
|
237
|
+
{
|
|
238
|
+
"reason": "Identity documents not provided"
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
| Field | Type | Required | Rules |
|
|
243
|
+
|-------|------|----------|-------|
|
|
244
|
+
| `reason` | string | ✓ | Required; 1–500 characters |
|
|
245
|
+
|
|
246
|
+
**Response** `200 OK` — Returns updated `{EntityName}Dto`.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Common Error Response Format
|
|
251
|
+
|
|
252
|
+
All errors return `ProblemDetails`:
|
|
253
|
+
|
|
254
|
+
```json
|
|
255
|
+
{
|
|
256
|
+
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
|
|
257
|
+
"title": "Validation Error",
|
|
258
|
+
"status": 400,
|
|
259
|
+
"detail": "One or more validation errors occurred.",
|
|
260
|
+
"errors": {
|
|
261
|
+
"field1": ["Field1 is required"],
|
|
262
|
+
"field2": ["Field2 format is invalid"]
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
| Status | Meaning |
|
|
268
|
+
|--------|---------|
|
|
269
|
+
| `400` | Validation or business rule failure |
|
|
270
|
+
| `401` | Missing or invalid Bearer token |
|
|
271
|
+
| `403` | Insufficient permissions (role missing) |
|
|
272
|
+
| `404` | Resource not found |
|
|
273
|
+
| `409` | Conflict (duplicate unique field) |
|
|
274
|
+
| `429` | Rate limit exceeded |
|
|
275
|
+
| `500` | Internal server error |
|