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.
Files changed (51) hide show
  1. package/dist/cli/commands/add.js +3 -1
  2. package/dist/cli/commands/doctor.js +145 -47
  3. package/dist/cli/commands/init.js +6 -0
  4. package/dist/core/analyzer.js +70 -0
  5. package/dist/core/detector.js +22 -0
  6. package/package.json +1 -1
  7. package/templates/common/AGENTS.md.hbs +4 -0
  8. package/templates/common/GLOBAL_RULES.md +101 -0
  9. package/templates/devops/AGENTS.md.hbs +32 -0
  10. package/templates/devops/skills/devops/SKILL.md +477 -0
  11. package/templates/diagram/AGENTS.md.hbs +30 -0
  12. package/templates/diagram/skills/drawio-diagram/SKILL.md +427 -0
  13. package/templates/dotnet/AGENTS.md.hbs +38 -34
  14. package/templates/dotnet/rules/api-structure.md +15 -15
  15. package/templates/dotnet/rules/csharp-style.md +17 -17
  16. package/templates/dotnet/rules/dependency-injection.md +12 -12
  17. package/templates/dotnet/rules/error-handling-validation.md +15 -15
  18. package/templates/dotnet/skills/dotnet-controller/SKILL.md +16 -16
  19. package/templates/express/AGENTS.md.hbs +37 -33
  20. package/templates/express/rules/error-handling.md +18 -18
  21. package/templates/express/rules/express-style.md +19 -19
  22. package/templates/express/rules/router-controller.md +16 -16
  23. package/templates/express/skills/express-endpoint/SKILL.md +14 -14
  24. package/templates/fastapi/AGENTS.md.hbs +25 -3
  25. package/templates/fastapi/rules/api-testing.md +24 -0
  26. package/templates/fastapi/rules/database-async.md +26 -0
  27. package/templates/golang/AGENTS.md.hbs +42 -0
  28. package/templates/golang/rules/concurrency.md +71 -0
  29. package/templates/golang/rules/error-handling.md +42 -0
  30. package/templates/golang/rules/golang-style.md +24 -0
  31. package/templates/golang/rules/project-layout.md +39 -0
  32. package/templates/golang/skills/golang-db/SKILL.md +27 -0
  33. package/templates/golang/skills/golang-feature/SKILL.md +42 -0
  34. package/templates/nestjs/AGENTS.md.hbs +33 -29
  35. package/templates/nestjs/rules/module-architecture.md +14 -14
  36. package/templates/nestjs/rules/nestjs-style.md +12 -12
  37. package/templates/nestjs/rules/validation-errors.md +15 -15
  38. package/templates/nestjs/skills/nestjs-module/SKILL.md +15 -15
  39. package/templates/next-js/AGENTS.md.hbs +39 -35
  40. package/templates/next-js/rules/data-fetching-mutations.md +17 -17
  41. package/templates/next-js/rules/next-style.md +17 -17
  42. package/templates/next-js/rules/seo-metadata.md +18 -18
  43. package/templates/next-js/rules/server-client-components.md +17 -17
  44. package/templates/next-js/skills/next-feature/SKILL.md +16 -16
  45. package/templates/rust/AGENTS.md.hbs +41 -0
  46. package/templates/rust/rules/error-handling.md +36 -0
  47. package/templates/rust/rules/memory-concurrency.md +47 -0
  48. package/templates/rust/rules/project-layout.md +49 -0
  49. package/templates/rust/rules/rust-style.md +26 -0
  50. package/templates/rust/skills/rust-db/SKILL.md +27 -0
  51. 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&#xa;(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&#xa;- 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&#xa;(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="&lt;&lt;extend&gt;&gt;" 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="&lt;u&gt;CustomerID&lt;/u&gt;" 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="&lt;&lt;import&gt;&gt;" 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
- ## 🗺️ Hướng Dẫn Phát Triển .NET (C#)
1
+ ## 🗺️ .NET (C#) Development Guide
2
2
 
3
- Dự án này một ứng dụng .NET (C#), được tổ chức và cấu hình như sau:
4
- - **Tên Solution:** `{{solutionName}}`
5
- - **Phiên bản .NET:** `net{{dotnetVersion}}`
6
- - **Các dự án thành phần:**
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
- - **Các dự án kiểm thử (Test Projects):**
10
+ - **Test Projects:**
11
11
  {{#each testProjects}}
12
12
  - `{{this}}`
13
13
  {{/each}}
14
14
 
15
15
  ---
16
16
 
17
- ### 🔄 Vòng Đời Phát Triển Tác Nhân (Agent Development Lifecycle)
18
- Tác nhân AI phải thực hiện tất cả các nhiệm vụ .NET theo quy trình 5 bước sau:
19
- 1. **Thiết kế & Lập trình:** Triển khai các lớp nghiệp vụ tuân thủ cấu trúc Clean Architecture / Onion Architecture. Đặt Core Logic trong Application/Domain layer độc lập.
20
- 2. **Kiểm thử Toàn diện:** Viết unit test cho các Service sử dụng xUnit Moq.
21
- 3. **Chất lượng Mã nguồn:** Chạy các lệnh kiểm tra lỗi pháp kiểu dữ liệu:
22
- - Chạy Build kiểm tra: `dotnet build`
23
- - Chạy Kiểm thử: `dotnet test`
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
- ### 🏗️ Kiến Trúc Hệ Thống Bản Mẫu (Template Blueprint)
29
- Vui lòng tham khảo các tài liệu quy tắc chi tiết dưới đây:
30
- - Quy ước coding style chuẩn C#, PascalCase, camelCase tiền tố Interface: `@csharp-style.md`
31
- - Quy định đăng ký và sử dụng Dependency Injection (Transient, Scoped, Singleton): `@dependency-injection.md`
32
- - Phân định trách nhiệm API Controller điều phối luồng xử lý: `@api-structure.md`
33
- - Cấu hình FluentValidation middleware xử ngoại lệ tập trung: `@error-handling-validation.md`
34
- - Quy trình từng bước sinh mới API Controller, DTO, Request Validator: `@SKILL.md`
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
- ### 🏛️ Quy Tắc Phát Triển Nghiêm Ngặt
37
+ ### 🏛️ Strict Development Rules
39
38
 
40
- #### 1. Kiến Trúc Sạch (Clean Architecture)
41
- Phân tách ràng các tầng trách nhiệm:
42
- - **Domain:** Chứa Entities, Value Objects, Domain Logic. Tuyệt đối không phụ thuộc vào bất kỳ thư viện ngoài nào.
43
- - **Application:** Chứa Interfaces, DTOs, Use Cases (Services/Queries/Commands). Chỉ phụ thuộc vào Domain layer.
44
- - **Infrastructure:** Chứa Data Access (EF Core), External Services. Phụ thuộc vào Application layer.
45
- - **Presentation (API):** Chứa Controllers, Middlewares. Điểm khởi chạy của ứng dụng.
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. Đăng Ký Dependency Injection (DI)
48
- - Sử dụng constructor injection để tiêm các dịch vụ cần thiết qua các interface.
49
- - Tuyệt đối cấm sử dụng Service Locator pattern ( dụ: giải quyết dependencies thủ công qua `IServiceProvider` trong runtime).
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. Kiểm Thử Dữ Liệu Tự Động Với FluentValidation
52
- - Toàn bộ dữ liệu đầu vào của API Request phải được kiểm duyệt tự động thông qua các class Validator thừa kế từ `AbstractValidator<T>` của thư viện FluentValidation.
53
- - Không viết code validate thủ công bằng các câu lệnh `if` rải rác trong Controller.
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
- # Cấu Trúc Lớp Presentation (API Controllers)
1
+ # Presentation Layer Structure (API Controllers)
2
2
 
3
- Tài liệu này quy định cấu trúc trách nhiệm của API Controllers trong tầng Presentation của ứng dụng .NET.
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
- ## 🏛️ Trách Nhiệm Của API Controller
8
- API Controller chịu trách nhiệm:
9
- 1. Nhận yêu cầu HTTP (HTTP Requests) từ client.
10
- 2. Ánh xạ các tham số URL, Query String, hoặc Request Body vào các DTO tương ứng.
11
- 3. Chuyển giao các tham số đó sang tầng Application (Services/Queries/Commands).
12
- 4. Nhận lại kết quả phản hồi Client thông qua các mã trạng thái HTTP phù hợp (200 OK, 201 Created, 400 Bad Request, 404 Not Found, v.v.).
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
- ## 🚦 Quy Tắc Phát Triển
17
- - **Controller mỏng (Thin Controllers):** Controllers không chứa bất kỳ logic nghiệp vụ, tính toán thuật toán, hay truy vấn DB trực tiếp. 100% logic đó phải nằm dưới Application layer.
18
- - **Không tiêm DbContext vào Controller:** DbContext phải được che giấu dưới Infrastructure / Repository layer. Tầng Presentation tuyệt đối không gọi DbContext.
19
- - **Sử dụng DTO thay Entity trực tiếp:**
20
- - Không nhận trực tiếp Domain Entities làm đầu vào của Controller.
21
- - Không trả trực tiếp Domain Entities về cho Client để tránh lộ cấu trúc DB hoặc lỗi cyclic references. Luôn ánh xạ qua các lớp DTO (Data Transfer Objects).
22
- - **Cấu hình định tuyến Route rõ ràng:** Sử dụng attribute routing để khai báo ràng phương thức HTTP và endpoint:
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]")]