agent-workflow-kit-cli 1.3.2 → 1.3.4
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/dist/cli/commands/add.js +3 -1
- package/dist/cli/commands/doctor.js +145 -47
- package/dist/cli/commands/init.js +6 -0
- package/dist/core/analyzer.js +70 -0
- package/dist/core/detector.js +22 -0
- package/package.json +1 -1
- package/templates/common/AGENTS.md.hbs +4 -0
- package/templates/common/GLOBAL_RULES.md +101 -0
- package/templates/devops/AGENTS.md.hbs +32 -0
- package/templates/devops/skills/devops/SKILL.md +477 -0
- package/templates/diagram/AGENTS.md.hbs +30 -0
- package/templates/diagram/skills/drawio-diagram/SKILL.md +427 -0
- package/templates/dotnet/AGENTS.md.hbs +38 -34
- package/templates/dotnet/rules/api-structure.md +15 -15
- package/templates/dotnet/rules/csharp-style.md +17 -17
- package/templates/dotnet/rules/dependency-injection.md +12 -12
- package/templates/dotnet/rules/error-handling-validation.md +15 -15
- package/templates/dotnet/skills/dotnet-controller/SKILL.md +16 -16
- package/templates/express/AGENTS.md.hbs +37 -33
- package/templates/express/rules/error-handling.md +18 -18
- package/templates/express/rules/express-style.md +19 -19
- package/templates/express/rules/router-controller.md +16 -16
- package/templates/express/skills/express-endpoint/SKILL.md +14 -14
- package/templates/fastapi/AGENTS.md.hbs +25 -3
- package/templates/fastapi/rules/api-testing.md +24 -0
- package/templates/fastapi/rules/database-async.md +26 -0
- package/templates/golang/AGENTS.md.hbs +42 -0
- package/templates/golang/rules/concurrency.md +71 -0
- package/templates/golang/rules/error-handling.md +42 -0
- package/templates/golang/rules/golang-style.md +24 -0
- package/templates/golang/rules/project-layout.md +39 -0
- package/templates/golang/skills/golang-db/SKILL.md +27 -0
- package/templates/golang/skills/golang-feature/SKILL.md +42 -0
- package/templates/nestjs/AGENTS.md.hbs +33 -29
- package/templates/nestjs/rules/module-architecture.md +14 -14
- package/templates/nestjs/rules/nestjs-style.md +12 -12
- package/templates/nestjs/rules/validation-errors.md +15 -15
- package/templates/nestjs/skills/nestjs-module/SKILL.md +15 -15
- package/templates/next-js/AGENTS.md.hbs +39 -35
- package/templates/next-js/rules/data-fetching-mutations.md +17 -17
- package/templates/next-js/rules/next-style.md +17 -17
- package/templates/next-js/rules/seo-metadata.md +18 -18
- package/templates/next-js/rules/server-client-components.md +17 -17
- package/templates/next-js/skills/next-feature/SKILL.md +16 -16
- package/templates/rust/AGENTS.md.hbs +41 -0
- package/templates/rust/rules/error-handling.md +36 -0
- package/templates/rust/rules/memory-concurrency.md +47 -0
- package/templates/rust/rules/project-layout.md +49 -0
- package/templates/rust/rules/rust-style.md +26 -0
- package/templates/rust/skills/rust-db/SKILL.md +27 -0
- package/templates/rust/skills/rust-feature/SKILL.md +34 -0
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: drawio-diagram
|
|
3
|
+
description: Analyze source code to generate precise Draw.io XML templates for 10 architecture and system diagram types
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Follow this process to generate native, valid Draw.io XML files representing the codebase architecture or requested system design.
|
|
7
|
+
|
|
8
|
+
Inputs:
|
|
9
|
+
- targetDiagramType: One of `system-overview`, `sequence`, `class`, `context`, `use-case`, `erd`, `peter-chen`, `package`, `workflow`, `state`
|
|
10
|
+
- scopeDescription: Specific system module, workflow, or architecture logic to visualize
|
|
11
|
+
- customFormatting: Optional formatting settings (defaults to monochrome)
|
|
12
|
+
|
|
13
|
+
Steps:
|
|
14
|
+
1. **Analyze System Codebase & Logic:**
|
|
15
|
+
- Scan the relevant directories or design specifications.
|
|
16
|
+
- For sequence, class, package, and entity relationship diagrams, retrieve actual class definitions, dependencies, database entities, and method signatures from the workspace.
|
|
17
|
+
|
|
18
|
+
2. **Formulate the Graph Structure:**
|
|
19
|
+
- Establish unique, static string/numeric IDs for all nodes (e.g., `id="node-1"`) and parent groupings.
|
|
20
|
+
- Compute clear, non-overlapping grid layout coordinates (`x`, `y`, `width`, `height`) for all shapes.
|
|
21
|
+
- Restrict colors strictly to monochrome style:
|
|
22
|
+
- `fillColor=#ffffff` (White fill)
|
|
23
|
+
- `strokeColor=#000000` (Black border/line)
|
|
24
|
+
- `fontColor=#000000` (Black text)
|
|
25
|
+
|
|
26
|
+
3. **Verify Node & Arrow Syntax for Selected Diagram Type:**
|
|
27
|
+
Apply the specific Draw.io style mappings defined in the rules below.
|
|
28
|
+
|
|
29
|
+
4. **Output Code Block:**
|
|
30
|
+
Wrap the complete, uncompressed Draw.io XML inside a code block (`xml`) so the user can copy and paste it into Draw.io's XML/SVG editor, or save as a `.drawio` file.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 🏛️ Draw.io XML Syntax Rules by Diagram Type
|
|
35
|
+
|
|
36
|
+
### 1. System Overview Diagram
|
|
37
|
+
* **Containers (Subsystems/Layers):** Represent layers using group swimlanes or dashed rectangles:
|
|
38
|
+
`style="swimlane;html=1;childLayout=stackLayout;horizontal=1;startSize=30;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;whiteSpace=wrap;"`
|
|
39
|
+
* **Components:** In-container elements:
|
|
40
|
+
`style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;"`
|
|
41
|
+
* **Connections:** Directed communication links with protocol labels:
|
|
42
|
+
`style="endArrow=classic;html=1;strokeColor=#000000;fontColor=#000000;"`
|
|
43
|
+
* **XML Template:**
|
|
44
|
+
```xml
|
|
45
|
+
<mxfile host="Electron" version="21.0.0">
|
|
46
|
+
<diagram id="diag-overview" name="System Overview">
|
|
47
|
+
<mxGraphModel dx="1000" dy="1000" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100">
|
|
48
|
+
<root>
|
|
49
|
+
<mxCell id="0" />
|
|
50
|
+
<mxCell id="1" parent="0" />
|
|
51
|
+
<mxCell id="layer-ui" value="Presentation Layer (Frontend)" style="swimlane;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;whiteSpace=wrap;" vertex="1" parent="1">
|
|
52
|
+
<mxGeometry x="100" y="80" width="650" height="150" as="geometry" />
|
|
53
|
+
</mxCell>
|
|
54
|
+
<mxCell id="node-spa" value="Single Page Application
(React / TypeScript)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="layer-ui">
|
|
55
|
+
<mxGeometry x="240" y="50" width="170" height="60" as="geometry" />
|
|
56
|
+
</mxCell>
|
|
57
|
+
<mxCell id="layer-api" value="Application Layer (Backend)" style="swimlane;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;whiteSpace=wrap;" vertex="1" parent="1">
|
|
58
|
+
<mxGeometry x="100" y="300" width="650" height="150" as="geometry" />
|
|
59
|
+
</mxCell>
|
|
60
|
+
<mxCell id="node-api-gw" value="REST API Gateway" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="layer-api">
|
|
61
|
+
<mxGeometry x="240" y="50" width="170" height="60" as="geometry" />
|
|
62
|
+
</mxCell>
|
|
63
|
+
<mxCell id="edge-http" value="HTTPS / JSON" style="endArrow=classic;html=1;strokeColor=#000000;fontColor=#000000;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="node-spa" target="node-api-gw">
|
|
64
|
+
<mxGeometry relative="1" as="geometry" />
|
|
65
|
+
</mxCell>
|
|
66
|
+
</root>
|
|
67
|
+
</mxGraphModel>
|
|
68
|
+
</diagram>
|
|
69
|
+
</mxfile>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
### 2. Sequence Diagram
|
|
75
|
+
* **Lifelines:** Vertical dashed lines extending from participants:
|
|
76
|
+
`style="shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;outlineConnect=0;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;dashed=1;"`
|
|
77
|
+
* **Activation Bars:** Small vertical overlays mapping message durations:
|
|
78
|
+
`style="html=1;points=[];fillColor=#ffffff;strokeColor=#000000;"`
|
|
79
|
+
* **Participant Naming:** Standard colon representation: `instance:Class` or `:Class` (e.g. `orderController:OrderController`).
|
|
80
|
+
* **Communication Edges:**
|
|
81
|
+
- Synchronous Message: `style="endArrow=block;html=1;strokeColor=#000000;fontColor=#000000;"`
|
|
82
|
+
- Return/Response Message: `style="endArrow=open;dashed=1;html=1;strokeColor=#000000;fontColor=#000000;"`
|
|
83
|
+
- Asynchronous Message: `style="endArrow=open;html=1;strokeColor=#000000;fontColor=#000000;"`
|
|
84
|
+
* **XML Template:**
|
|
85
|
+
```xml
|
|
86
|
+
<mxfile host="Electron" version="21.0.0">
|
|
87
|
+
<diagram id="diag-seq" name="Sequence Flow">
|
|
88
|
+
<mxGraphModel dx="1000" dy="1000" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100">
|
|
89
|
+
<root>
|
|
90
|
+
<mxCell id="0" />
|
|
91
|
+
<mxCell id="1" parent="0" />
|
|
92
|
+
<mxCell id="life-client" value="client:Client" style="shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;outlineConnect=0;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="1">
|
|
93
|
+
<mxGeometry x="100" y="80" width="100" height="300" as="geometry" />
|
|
94
|
+
</mxCell>
|
|
95
|
+
<mxCell id="act-client" value="" style="html=1;points=[];fillColor=#ffffff;strokeColor=#000000;" vertex="1" parent="life-client">
|
|
96
|
+
<mxGeometry x="45" y="70" width="10" height="150" as="geometry" />
|
|
97
|
+
</mxCell>
|
|
98
|
+
<mxCell id="life-controller" value="orderController:OrderController" style="shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;outlineConnect=0;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="1">
|
|
99
|
+
<mxGeometry x="320" y="80" width="180" height="300" as="geometry" />
|
|
100
|
+
</mxCell>
|
|
101
|
+
<mxCell id="act-controller" value="" style="html=1;points=[];fillColor=#ffffff;strokeColor=#000000;" vertex="1" parent="life-controller">
|
|
102
|
+
<mxGeometry x="85" y="80" width="10" height="100" as="geometry" />
|
|
103
|
+
</mxCell>
|
|
104
|
+
<mxCell id="msg-create" value="createOrder(details)" style="endArrow=block;html=1;strokeColor=#000000;fontColor=#000000;entryX=0;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="act-client" target="act-controller">
|
|
105
|
+
<mxGeometry relative="1" as="geometry">
|
|
106
|
+
<mxPoint x="160" y="160" as="sourcePoint" />
|
|
107
|
+
</mxGeometry>
|
|
108
|
+
</mxCell>
|
|
109
|
+
<mxCell id="msg-resp" value="OrderCreatedResponse" style="endArrow=open;dashed=1;html=1;strokeColor=#000000;fontColor=#000000;exitX=0;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.66;" edge="1" parent="1" source="act-controller" target="act-client">
|
|
110
|
+
<mxGeometry relative="1" as="geometry">
|
|
111
|
+
<mxPoint x="240" y="260" as="sourcePoint" />
|
|
112
|
+
</mxGeometry>
|
|
113
|
+
</mxCell>
|
|
114
|
+
</root>
|
|
115
|
+
</mxGraphModel>
|
|
116
|
+
</diagram>
|
|
117
|
+
</mxfile>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
### 3. Class Diagram
|
|
123
|
+
* **Compartmentalized Class Box:** Partition fields and operations:
|
|
124
|
+
`style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;"`
|
|
125
|
+
* **Access Modifiers:** Prefix members with `+` (public), `-` (private), `#` (protected), `~` (package).
|
|
126
|
+
* **Relationship Arrows:**
|
|
127
|
+
- Inheritance (Generalization): Solid line, open triangle: `style="endArrow=block;endFill=0;html=1;strokeColor=#000000;"`
|
|
128
|
+
- Implementation (Realization): Dashed line, open triangle: `style="endArrow=block;endFill=0;dashed=1;html=1;strokeColor=#000000;"`
|
|
129
|
+
- Association: Solid line, open arrowhead: `style="endArrow=open;endSize=12;html=1;strokeColor=#000000;"`
|
|
130
|
+
- Dependency: Dashed line, open arrowhead: `style="endArrow=open;dashed=1;html=1;strokeColor=#000000;"`
|
|
131
|
+
- Composition: Solid line, filled diamond: `style="endArrow=diamond;endFill=1;endSize=14;html=1;strokeColor=#000000;"`
|
|
132
|
+
- Aggregation: Solid line, empty diamond: `style="endArrow=diamond;endFill=0;endSize=14;html=1;strokeColor=#000000;"`
|
|
133
|
+
* **XML Template:**
|
|
134
|
+
```xml
|
|
135
|
+
<mxfile host="Electron" version="21.0.0">
|
|
136
|
+
<diagram id="diag-class" name="Class Diagram">
|
|
137
|
+
<mxGraphModel dx="1000" dy="1000" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100">
|
|
138
|
+
<root>
|
|
139
|
+
<mxCell id="0" />
|
|
140
|
+
<mxCell id="1" parent="0" />
|
|
141
|
+
<mxCell id="class-payment" value="PaymentService" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="1">
|
|
142
|
+
<mxGeometry x="100" y="100" width="180" height="114" as="geometry" />
|
|
143
|
+
</mxCell>
|
|
144
|
+
<mxCell id="fields-payment" value="- client: HttpClient
- apiKey: String" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[];portConstraint=eastwest;" vertex="1" parent="class-payment">
|
|
145
|
+
<mxGeometry y="26" width="180" height="38" as="geometry" />
|
|
146
|
+
</mxCell>
|
|
147
|
+
<mxCell id="divider" value="" style="line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[];portConstraint=eastwest;strokeColor=#000000;" vertex="1" parent="class-payment">
|
|
148
|
+
<mxGeometry y="64" width="180" height="10" as="geometry" />
|
|
149
|
+
</mxCell>
|
|
150
|
+
<mxCell id="methods-payment" value="+ process(Order): boolean" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[];portConstraint=eastwest;" vertex="1" parent="class-payment">
|
|
151
|
+
<mxGeometry y="74" width="180" height="40" as="geometry" />
|
|
152
|
+
</mxCell>
|
|
153
|
+
</root>
|
|
154
|
+
</mxGraphModel>
|
|
155
|
+
</diagram>
|
|
156
|
+
</mxfile>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
### 4. Context Diagram
|
|
162
|
+
* **Central System Boundary:** Draw a rounded rect or large central ellipse:
|
|
163
|
+
`style="ellipse;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;strokeWidth=2;"`
|
|
164
|
+
* **External Entities:** Peripheral rectangles:
|
|
165
|
+
`style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;"`
|
|
166
|
+
* **Communication Rules:** Tectonic flows cannot connect external entities directly; they must connect entities to the central system only.
|
|
167
|
+
* **XML Template:**
|
|
168
|
+
```xml
|
|
169
|
+
<mxfile host="Electron" version="21.0.0">
|
|
170
|
+
<diagram id="diag-context" name="System Context">
|
|
171
|
+
<mxGraphModel dx="1000" dy="1000" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100">
|
|
172
|
+
<root>
|
|
173
|
+
<mxCell id="0" />
|
|
174
|
+
<mxCell id="1" parent="0" />
|
|
175
|
+
<mxCell id="node-system" value="E-Commerce System
(Central Boundary)" style="ellipse;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;strokeWidth=2;" vertex="1" parent="1">
|
|
176
|
+
<mxGeometry x="320" y="200" width="180" height="120" as="geometry" />
|
|
177
|
+
</mxCell>
|
|
178
|
+
<mxCell id="node-user" value="Customer" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="1">
|
|
179
|
+
<mxGeometry x="80" y="230" width="120" height="60" as="geometry" />
|
|
180
|
+
</mxCell>
|
|
181
|
+
<mxCell id="edge-order" value="Submits Order" style="endArrow=classic;html=1;strokeColor=#000000;fontColor=#000000;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="node-user" target="node-system">
|
|
182
|
+
<mxGeometry relative="1" as="geometry" />
|
|
183
|
+
</mxCell>
|
|
184
|
+
</root>
|
|
185
|
+
</mxGraphModel>
|
|
186
|
+
</diagram>
|
|
187
|
+
</mxfile>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
### 5. Use Case Diagram
|
|
193
|
+
* **Actors:** Standard stick figures:
|
|
194
|
+
`style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;"`
|
|
195
|
+
* **System Boundary:** High-contrast rectangle grouping all use cases:
|
|
196
|
+
`style="shape=rectangle;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#000000;fontColor=#000000;verticalAlign=top;align=left;spacingLeft=10;spacingTop=10;"`
|
|
197
|
+
* **Use Cases:** Horizontal ovals inside the boundary:
|
|
198
|
+
`style="ellipse;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;"`
|
|
199
|
+
* **Relations:**
|
|
200
|
+
- Simple Association: Plain line: `style="endArrow=none;html=1;strokeColor=#000000;"`
|
|
201
|
+
- `<<include>>` / `<<extend>>`: Dashed line with open arrow pointing to the referenced use case: `style="endArrow=open;dashed=1;html=1;strokeColor=#000000;fontColor=#000000;"`
|
|
202
|
+
* **XML Template:**
|
|
203
|
+
```xml
|
|
204
|
+
<mxfile host="Electron" version="21.0.0">
|
|
205
|
+
<diagram id="diag-usecase" name="Use Case Diagram">
|
|
206
|
+
<mxGraphModel dx="1000" dy="1000" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100">
|
|
207
|
+
<root>
|
|
208
|
+
<mxCell id="0" />
|
|
209
|
+
<mxCell id="1" parent="0" />
|
|
210
|
+
<mxCell id="system-boundary" value="Order Processing System" style="shape=rectangle;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#000000;fontColor=#000000;verticalAlign=top;align=left;spacingLeft=10;spacingTop=10;" vertex="1" parent="1">
|
|
211
|
+
<mxGeometry x="250" y="80" width="350" height="300" as="geometry" />
|
|
212
|
+
</mxCell>
|
|
213
|
+
<mxCell id="usecase-checkout" value="Checkout Order" style="ellipse;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="system-boundary">
|
|
214
|
+
<mxGeometry x="80" y="60" width="180" height="60" as="geometry" />
|
|
215
|
+
</mxCell>
|
|
216
|
+
<mxCell id="usecase-discount" value="Apply Coupon" style="ellipse;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="system-boundary">
|
|
217
|
+
<mxGeometry x="80" y="180" width="180" height="60" as="geometry" />
|
|
218
|
+
</mxCell>
|
|
219
|
+
<mxCell id="actor-user" value="Customer" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="1">
|
|
220
|
+
<mxGeometry x="80" y="160" width="40" height="80" as="geometry" />
|
|
221
|
+
</mxCell>
|
|
222
|
+
<mxCell id="edge-assoc" value="" style="endArrow=none;html=1;strokeColor=#000000;exitX=0.5;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=1;entryX=0;entryY=0.5;" edge="1" parent="1" source="actor-user" target="usecase-checkout">
|
|
223
|
+
<mxGeometry relative="1" as="geometry" />
|
|
224
|
+
</mxCell>
|
|
225
|
+
<mxCell id="edge-extend" value="<<extend>>" style="endArrow=open;dashed=1;html=1;strokeColor=#000000;fontColor=#000000;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="usecase-discount" target="usecase-checkout">
|
|
226
|
+
<mxGeometry relative="1" as="geometry" />
|
|
227
|
+
</mxCell>
|
|
228
|
+
</root>
|
|
229
|
+
</mxGraphModel>
|
|
230
|
+
</diagram>
|
|
231
|
+
</mxfile>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
### 6. Entity Relationship Diagram (ERD)
|
|
237
|
+
* **ERD Tables:** Entity tables showing columns:
|
|
238
|
+
`style="shape=mxgraph.er.table;html=1;childLayout=tableLayout;horizontal=1;startSize=26;resizeParent=1;resizeParentMax=0;resizeLast=0;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;"`
|
|
239
|
+
* **Rows & Key Markers:** Use a tabular layout to display fields, marking `PK` / `FK` in the left cells.
|
|
240
|
+
* **Crow's Foot Edges:**
|
|
241
|
+
- One-to-many relationship: `style="endArrow=ERoneToMany;startArrow=ERmandOne;strokeColor=#000000;"` or `ERmanyToOne`.
|
|
242
|
+
- Zero-to-many relationship: `style="endArrow=ERzeroToMany;startArrow=ERmandOne;strokeColor=#000000;"`
|
|
243
|
+
* **XML Template:**
|
|
244
|
+
```xml
|
|
245
|
+
<mxfile host="Electron" version="21.0.0">
|
|
246
|
+
<diagram id="diag-erd" name="Entity Relationship">
|
|
247
|
+
<mxGraphModel dx="1000" dy="1000" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100">
|
|
248
|
+
<root>
|
|
249
|
+
<mxCell id="0" />
|
|
250
|
+
<mxCell id="1" parent="0" />
|
|
251
|
+
<mxCell id="tbl-customer" value="customer" style="shape=mxgraph.er.table;html=1;childLayout=tableLayout;horizontal=1;startSize=26;resizeParent=1;resizeParentMax=0;resizeLast=0;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="1">
|
|
252
|
+
<mxGeometry x="100" y="100" width="180" height="98" as="geometry" />
|
|
253
|
+
</mxCell>
|
|
254
|
+
<mxCell id="row-cus-pk" style="shape=mxgraph.er.row;html=1;portConstraint=eastwest;" vertex="1" parent="tbl-customer">
|
|
255
|
+
<mxGeometry y="26" width="180" height="24" as="geometry" />
|
|
256
|
+
</mxCell>
|
|
257
|
+
<mxCell id="cell-pk" value="PK" style="shape=mxgraph.er.cell;html=1;align=center;" vertex="1" parent="row-cus-pk">
|
|
258
|
+
<mxGeometry width="30" height="24" as="geometry" />
|
|
259
|
+
</mxCell>
|
|
260
|
+
<mxCell id="cell-id" value="id : integer" style="shape=mxgraph.er.cell;html=1;align=left;" vertex="1" parent="row-cus-pk">
|
|
261
|
+
<mxGeometry x="30" width="150" height="24" as="geometry" />
|
|
262
|
+
</mxCell>
|
|
263
|
+
<mxCell id="row-cus-name" style="shape=mxgraph.er.row;html=1;portConstraint=eastwest;" vertex="1" parent="tbl-customer">
|
|
264
|
+
<mxGeometry y="50" width="180" height="24" as="geometry" />
|
|
265
|
+
</mxCell>
|
|
266
|
+
<mxCell id="cell-name-lbl" value="" style="shape=mxgraph.er.cell;html=1;align=center;" vertex="1" parent="row-cus-name">
|
|
267
|
+
<mxGeometry width="30" height="24" as="geometry" />
|
|
268
|
+
</mxCell>
|
|
269
|
+
<mxCell id="cell-name" value="name : varchar(100)" style="shape=mxgraph.er.cell;html=1;align=left;" vertex="1" parent="row-cus-name">
|
|
270
|
+
<mxGeometry x="30" width="150" height="24" as="geometry" />
|
|
271
|
+
</mxCell>
|
|
272
|
+
</root>
|
|
273
|
+
</mxGraphModel>
|
|
274
|
+
</diagram>
|
|
275
|
+
</mxfile>
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
### 7. Conceptual Diagram (Peter Chen Notation)
|
|
281
|
+
* **Entities:** Regular rectangles:
|
|
282
|
+
`style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;"`
|
|
283
|
+
* **Attributes:** Ellipses:
|
|
284
|
+
`style="ellipse;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;"` (Primary key titles must have underlined text).
|
|
285
|
+
* **Relationships:** Central diamonds:
|
|
286
|
+
`style="rhombus;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;"`
|
|
287
|
+
* **Cardinality Labels:** Simple lines with numeric/alphanumeric labels (e.g. `1`, `N`, `M` labels near the connectors).
|
|
288
|
+
* **XML Template:**
|
|
289
|
+
```xml
|
|
290
|
+
<mxfile host="Electron" version="21.0.0">
|
|
291
|
+
<diagram id="diag-peterchen" name="Peter Chen Conceptual">
|
|
292
|
+
<mxGraphModel dx="1000" dy="1000" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100">
|
|
293
|
+
<root>
|
|
294
|
+
<mxCell id="0" />
|
|
295
|
+
<mxCell id="1" parent="0" />
|
|
296
|
+
<mxCell id="ent-customer" value="Customer" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="1">
|
|
297
|
+
<mxGeometry x="100" y="200" width="120" height="50" as="geometry" />
|
|
298
|
+
</mxCell>
|
|
299
|
+
<mxCell id="rel-buys" value="Buys" style="rhombus;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="1">
|
|
300
|
+
<mxGeometry x="360" y="185" width="100" height="80" as="geometry" />
|
|
301
|
+
</mxCell>
|
|
302
|
+
<mxCell id="ent-product" value="Product" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="1">
|
|
303
|
+
<mxGeometry x="600" y="200" width="120" height="50" as="geometry" />
|
|
304
|
+
</mxCell>
|
|
305
|
+
<mxCell id="attr-id" value="<u>CustomerID</u>" style="ellipse;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="1">
|
|
306
|
+
<mxGeometry x="110" y="80" width="100" height="50" as="geometry" />
|
|
307
|
+
</mxCell>
|
|
308
|
+
<mxCell id="edge-ent1" value="1" style="endArrow=none;html=1;strokeColor=#000000;fontColor=#000000;exitX=1;exitY=0.5;entryX=0;entryY=0.5;" edge="1" parent="1" source="ent-customer" target="rel-buys">
|
|
309
|
+
<mxGeometry relative="1" as="geometry" />
|
|
310
|
+
</mxCell>
|
|
311
|
+
<mxCell id="edge-ent2" value="N" style="endArrow=none;html=1;strokeColor=#000000;fontColor=#000000;exitX=1;exitY=0.5;entryX=0;entryY=0.5;" edge="1" parent="1" source="rel-buys" target="ent-product">
|
|
312
|
+
<mxGeometry relative="1" as="geometry" />
|
|
313
|
+
</mxCell>
|
|
314
|
+
<mxCell id="edge-attr" value="" style="endArrow=none;html=1;strokeColor=#000000;exitX=0.5;exitY=1;entryX=0.5;entryY=0;" edge="1" parent="1" source="attr-id" target="ent-customer">
|
|
315
|
+
<mxGeometry relative="1" as="geometry" />
|
|
316
|
+
</mxCell>
|
|
317
|
+
</root>
|
|
318
|
+
</mxGraphModel>
|
|
319
|
+
</diagram>
|
|
320
|
+
</mxfile>
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
### 8. Package Diagram
|
|
326
|
+
* **Folder Shapes:** Package components:
|
|
327
|
+
`style="shape=folder;fontStyle=1;spacingLeft=10;tabWidth=40;tabHeight=14;tabPosition=left;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;whiteSpace=wrap;"`
|
|
328
|
+
* **Package Relations:** Dashed line dependency connectors:
|
|
329
|
+
`style="endArrow=open;dashed=1;html=1;strokeColor=#000000;fontColor=#000000;"` (labeled `<<import>>` or `<<access>>`).
|
|
330
|
+
* **XML Template:**
|
|
331
|
+
```xml
|
|
332
|
+
<mxfile host="Electron" version="21.0.0">
|
|
333
|
+
<diagram id="diag-package" name="Package Dependencies">
|
|
334
|
+
<mxGraphModel dx="1000" dy="1000" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100">
|
|
335
|
+
<root>
|
|
336
|
+
<mxCell id="0" />
|
|
337
|
+
<mxCell id="1" parent="0" />
|
|
338
|
+
<mxCell id="pkg-controller" value="controllers" style="shape=folder;fontStyle=1;spacingLeft=10;tabWidth=40;tabHeight=14;tabPosition=left;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;whiteSpace=wrap;" vertex="1" parent="1">
|
|
339
|
+
<mxGeometry x="100" y="100" width="150" height="80" as="geometry" />
|
|
340
|
+
</mxCell>
|
|
341
|
+
<mxCell id="pkg-service" value="services" style="shape=folder;fontStyle=1;spacingLeft=10;tabWidth=40;tabHeight=14;tabPosition=left;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;whiteSpace=wrap;" vertex="1" parent="1">
|
|
342
|
+
<mxGeometry x="100" y="260" width="150" height="80" as="geometry" />
|
|
343
|
+
</mxCell>
|
|
344
|
+
<mxCell id="edge-dep" value="<<import>>" style="endArrow=open;dashed=1;html=1;strokeColor=#000000;fontColor=#000000;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="pkg-controller" target="pkg-service">
|
|
345
|
+
<mxGeometry relative="1" as="geometry" />
|
|
346
|
+
</mxCell>
|
|
347
|
+
</root>
|
|
348
|
+
</mxGraphModel>
|
|
349
|
+
</diagram>
|
|
350
|
+
</mxfile>
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
### 9. Workflow Diagram
|
|
356
|
+
* **Swimlanes (Executor Partitioning):** Organise flows via pools/lanes:
|
|
357
|
+
`style="swimlane;html=1;horizontal=0;startSize=30;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;"`
|
|
358
|
+
Ensure there are at least two distinct swimlanes to clearly separate the User (Actor/Role) and the System.
|
|
359
|
+
* **Nodes:**
|
|
360
|
+
- Start Node: Solid black circle: `style="ellipse;fillColor=#000000;strokeColor=#000000;html=1;"`
|
|
361
|
+
- End Node: Double circle: `style="doubleEllipse;fillColor=#000000;strokeColor=#000000;html=1;"`
|
|
362
|
+
- Activities: Rounded rectangles: `style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;"`
|
|
363
|
+
- Decisions: Diamond: `style="rhombus;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;"`
|
|
364
|
+
* **XML Template:**
|
|
365
|
+
```xml
|
|
366
|
+
<mxfile host="Electron" version="21.0.0">
|
|
367
|
+
<diagram id="diag-workflow" name="Process Workflow">
|
|
368
|
+
<mxGraphModel dx="1000" dy="1000" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100">
|
|
369
|
+
<root>
|
|
370
|
+
<mxCell id="0" />
|
|
371
|
+
<mxCell id="1" parent="0" />
|
|
372
|
+
<mxCell id="swim-user" value="User Role" style="swimlane;html=1;horizontal=0;startSize=30;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="1">
|
|
373
|
+
<mxGeometry x="80" y="80" width="680" height="150" as="geometry" />
|
|
374
|
+
</mxCell>
|
|
375
|
+
<mxCell id="flow-start" value="" style="ellipse;fillColor=#000000;strokeColor=#000000;html=1;" vertex="1" parent="swim-user">
|
|
376
|
+
<mxGeometry x="60" y="60" width="30" height="30" as="geometry" />
|
|
377
|
+
</mxCell>
|
|
378
|
+
<mxCell id="act-input" value="Fill Form" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="swim-user">
|
|
379
|
+
<mxGeometry x="160" y="45" width="120" height="60" as="geometry" />
|
|
380
|
+
</mxCell>
|
|
381
|
+
<mxCell id="swim-system" value="System" style="swimlane;html=1;horizontal=0;startSize=30;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="1">
|
|
382
|
+
<mxGeometry x="80" y="230" width="680" height="150" as="geometry" />
|
|
383
|
+
</mxCell>
|
|
384
|
+
<mxCell id="act-validate" value="Validate Input" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="swim-system">
|
|
385
|
+
<mxGeometry x="160" y="45" width="120" height="60" as="geometry" />
|
|
386
|
+
</mxCell>
|
|
387
|
+
<mxCell id="edge-start" value="" style="endArrow=classic;html=1;strokeColor=#000000;" edge="1" parent="1" source="flow-start" target="act-input">
|
|
388
|
+
<mxGeometry relative="1" as="geometry" />
|
|
389
|
+
</mxCell>
|
|
390
|
+
<mxCell id="edge-submit" value="Submit Form" style="endArrow=classic;html=1;strokeColor=#000000;fontColor=#000000;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="act-input" target="act-validate">
|
|
391
|
+
<mxGeometry relative="1" as="geometry" />
|
|
392
|
+
</mxCell>
|
|
393
|
+
</root>
|
|
394
|
+
</mxGraphModel>
|
|
395
|
+
</diagram>
|
|
396
|
+
</mxfile>
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
### 10. State Diagram
|
|
402
|
+
* **States:** Rounded rectangles representing operational states:
|
|
403
|
+
`style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;"`
|
|
404
|
+
* **Transitional Events:** Direct paths labeled with `Trigger [Guard] / Action` context:
|
|
405
|
+
`style="endArrow=classic;html=1;strokeColor=#000000;fontColor=#000000;"`
|
|
406
|
+
* **XML Template:**
|
|
407
|
+
```xml
|
|
408
|
+
<mxfile host="Electron" version="21.0.0">
|
|
409
|
+
<diagram id="diag-state" name="State Transition">
|
|
410
|
+
<mxGraphModel dx="1000" dy="1000" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100">
|
|
411
|
+
<root>
|
|
412
|
+
<mxCell id="0" />
|
|
413
|
+
<mxCell id="1" parent="0" />
|
|
414
|
+
<mxCell id="state-draft" value="DRAFT" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="1">
|
|
415
|
+
<mxGeometry x="100" y="200" width="120" height="50" as="geometry" />
|
|
416
|
+
</mxCell>
|
|
417
|
+
<mxCell id="state-pending" value="PENDING_APPROVAL" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;fontColor=#000000;" vertex="1" parent="1">
|
|
418
|
+
<mxGeometry x="380" y="200" width="140" height="50" as="geometry" />
|
|
419
|
+
</mxCell>
|
|
420
|
+
<mxCell id="edge-trans" value="submit [allFieldsFilled]" style="endArrow=classic;html=1;strokeColor=#000000;fontColor=#000000;exitX=1;exitY=0.5;entryX=0;entryY=0.5;" edge="1" parent="1" source="state-draft" target="state-pending">
|
|
421
|
+
<mxGeometry relative="1" as="geometry" />
|
|
422
|
+
</mxCell>
|
|
423
|
+
</root>
|
|
424
|
+
</mxGraphModel>
|
|
425
|
+
</diagram>
|
|
426
|
+
</mxfile>
|
|
427
|
+
```
|
|
@@ -1,53 +1,57 @@
|
|
|
1
|
-
## 🗺️
|
|
1
|
+
## 🗺️ .NET (C#) Development Guide
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
- **
|
|
5
|
-
-
|
|
6
|
-
- **
|
|
3
|
+
This project is a .NET (C#) application configured as follows:
|
|
4
|
+
- **Solution Name:** `{{solutionName}}`
|
|
5
|
+
- **.NET Version:** `net{{dotnetVersion}}`
|
|
6
|
+
- **Application Projects:**
|
|
7
7
|
{{#each projectNames}}
|
|
8
8
|
- `{{this}}`
|
|
9
9
|
{{/each}}
|
|
10
|
-
- **
|
|
10
|
+
- **Test Projects:**
|
|
11
11
|
{{#each testProjects}}
|
|
12
12
|
- `{{this}}`
|
|
13
13
|
{{/each}}
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
-
### 🔄
|
|
18
|
-
|
|
19
|
-
1. **
|
|
20
|
-
2. **
|
|
21
|
-
3. **
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
4. **Quản lý Thư viện:** Thêm các gói NuGet mới qua lệnh: `dotnet add package [tên_gói]`.
|
|
17
|
+
### 🔄 Agent Development Lifecycle
|
|
18
|
+
The AI Agent must execute all .NET tasks following this structured 5-stage lifecycle:
|
|
19
|
+
1. **Design & Code:** Implement business logic adhering to Clean Architecture / Onion Architecture principles. Maintain Core Logic in decoupled Application/Domain layers. Verify layering boundaries in `@api-structure.md`.
|
|
20
|
+
2. **Comprehensive Testing:** Write unit tests for Services using xUnit and Moq.
|
|
21
|
+
3. **Troubleshooting & Debugging:** When debugging dependency resolution issues or validation faults, inspect service lifetime setups.
|
|
22
|
+
4. **Code Quality & Review:** Perform self-review using `@error-handling-validation.md` (for FluentValidation and global exception middleware) and `@dependency-injection.md`. Check styling rules in `@csharp-style.md`.
|
|
23
|
+
5. **Production Readiness:** Verify compilation and execute all unit/integration tests before finalizing changes.
|
|
25
24
|
|
|
26
25
|
---
|
|
27
26
|
|
|
28
|
-
### 🏗️
|
|
29
|
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
27
|
+
### 🏗️ Template Blueprint
|
|
28
|
+
Refer to the detailed rules below:
|
|
29
|
+
- C# coding style, PascalCase, camelCase, and Interface prefixes: `@csharp-style.md`
|
|
30
|
+
- Dependency Injection lifetimes (Transient, Scoped, Singleton) registration: `@dependency-injection.md`
|
|
31
|
+
- API Controller responsibilities and execution dispatch: `@api-structure.md`
|
|
32
|
+
- FluentValidation setups and centralized exception handling middleware: `@error-handling-validation.md`
|
|
33
|
+
- Scaffolding a new API Controller, DTO, and Request Validator: `@dotnet-controller`
|
|
35
34
|
|
|
36
35
|
---
|
|
37
36
|
|
|
38
|
-
### 🏛️
|
|
37
|
+
### 🏛️ Strict Development Rules
|
|
39
38
|
|
|
40
|
-
#### 1.
|
|
41
|
-
|
|
42
|
-
- **Domain:**
|
|
43
|
-
- **Application:**
|
|
44
|
-
- **Infrastructure:**
|
|
45
|
-
- **Presentation (API):**
|
|
39
|
+
#### 1. Clean Architecture Layers
|
|
40
|
+
Strictly separate concerns across application boundaries:
|
|
41
|
+
- **Domain:** Houses Entities, Value Objects, and core Domain Logic. Must remain free of external package references.
|
|
42
|
+
- **Application:** Houses Interfaces, DTOs, and Use Cases (Services/Queries/Commands). Depends only on the Domain layer.
|
|
43
|
+
- **Infrastructure:** Houses Data Access (EF Core DbContext) and External Integrations. Depends on the Application layer.
|
|
44
|
+
- **Presentation (API):** Houses Controllers, Filters, and Middlewares. The entrypoint of the execution runtime.
|
|
46
45
|
|
|
47
|
-
#### 2.
|
|
48
|
-
-
|
|
49
|
-
-
|
|
46
|
+
#### 2. Dependency Injection (DI) Registration
|
|
47
|
+
- Inject all downstream services using constructor parameters via interfaces.
|
|
48
|
+
- Never use the Service Locator pattern (e.g., manually resolving dependencies at runtime using `IServiceProvider`).
|
|
50
49
|
|
|
51
|
-
#### 3.
|
|
52
|
-
-
|
|
53
|
-
-
|
|
50
|
+
#### 3. Validation with FluentValidation
|
|
51
|
+
- Validate all incoming request DTOs using validators inheriting from FluentValidation's `AbstractValidator<T>`.
|
|
52
|
+
- Do not write manual validation statements scattered across Controller methods.
|
|
53
|
+
|
|
54
|
+
### 🧪 Verification & Testing
|
|
55
|
+
Before completing a task, run the following verification pipeline:
|
|
56
|
+
- **Build Check:** `dotnet build`
|
|
57
|
+
- **Test Execution:** `dotnet test`
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Presentation Layer Structure (API Controllers)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This document defines the structure and responsibilities of API Controllers inside the Presentation layer of a .NET application.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## 🏛️
|
|
8
|
-
API Controller
|
|
9
|
-
1.
|
|
10
|
-
2.
|
|
11
|
-
3.
|
|
12
|
-
4.
|
|
7
|
+
## 🏛️ API Controller Responsibilities
|
|
8
|
+
An API Controller is responsible for:
|
|
9
|
+
1. Receiving incoming HTTP requests from clients.
|
|
10
|
+
2. Mapping URL parameters, query strings, or request bodies into target request DTOs.
|
|
11
|
+
3. Delegating request processing to the Application layer (Services/Queries/Commands).
|
|
12
|
+
4. Receiving results and responding to the client using appropriate HTTP status codes (e.g., `200 OK`, `201 Created`, `400 Bad Request`, `404 Not Found`).
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
## 🚦
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
19
|
-
- **
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
- **
|
|
16
|
+
## 🚦 Development Rules
|
|
17
|
+
- **Thin Controllers:** Controllers must not contain business logic, algorithmic calculations, or direct database queries. 100% of this logic must reside in the Application layer.
|
|
18
|
+
- **Do Not Inject DbContext into Controllers:** Keep `DbContext` encapsulated within the Infrastructure / Repository layers. The Presentation layer must never access `DbContext` directly.
|
|
19
|
+
- **Use DTOs Instead of Domain Entities:**
|
|
20
|
+
- Never accept raw Domain Entities as Controller input parameters.
|
|
21
|
+
- Never return raw Domain Entities directly to the client to prevent exposing the database schema or triggering cyclic reference errors. Always map records to DTO (Data Transfer Object) classes.
|
|
22
|
+
- **Explicit Route Declarations:** Use attribute routing to clearly declare HTTP methods and endpoints:
|
|
23
23
|
```csharp
|
|
24
24
|
[ApiController]
|
|
25
25
|
[Route("api/v1/[controller]")]
|