@atlashub/smartstack-cli 1.4.1 → 1.5.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/.documentation/agents.html +916 -916
- package/.documentation/apex.html +1018 -1018
- package/.documentation/business-analyse.html +1501 -1501
- package/.documentation/commands.html +680 -680
- package/.documentation/css/styles.css +2168 -2168
- package/.documentation/efcore.html +2505 -2505
- package/.documentation/gitflow.html +2618 -2618
- package/.documentation/hooks.html +413 -413
- package/.documentation/index.html +323 -323
- package/.documentation/installation.html +462 -462
- package/.documentation/js/app.js +794 -794
- package/.documentation/test-web.html +513 -513
- package/dist/index.js +807 -277
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/agents/efcore/conflicts.md +44 -17
- package/templates/agents/efcore/db-status.md +27 -6
- package/templates/agents/efcore/scan.md +43 -13
- package/templates/commands/ai-prompt.md +315 -315
- package/templates/commands/application/create.md +362 -362
- package/templates/commands/controller/create.md +216 -216
- package/templates/commands/controller.md +59 -0
- package/templates/commands/documentation/module.md +202 -202
- package/templates/commands/efcore/_env-check.md +153 -153
- package/templates/commands/efcore/conflicts.md +109 -192
- package/templates/commands/efcore/db-status.md +101 -89
- package/templates/commands/efcore/migration.md +23 -11
- package/templates/commands/efcore/scan.md +115 -119
- package/templates/commands/efcore.md +54 -6
- package/templates/commands/feature-full.md +267 -267
- package/templates/commands/gitflow/11-finish.md +145 -11
- package/templates/commands/gitflow/13-sync.md +216 -216
- package/templates/commands/gitflow/14-rebase.md +251 -251
- package/templates/commands/gitflow/2-status.md +120 -10
- package/templates/commands/gitflow/3-commit.md +150 -0
- package/templates/commands/gitflow/7-pull-request.md +134 -5
- package/templates/commands/gitflow/9-merge.md +142 -1
- package/templates/commands/implement.md +663 -663
- package/templates/commands/init.md +562 -0
- package/templates/commands/mcp-integration.md +330 -0
- package/templates/commands/notification.md +129 -129
- package/templates/commands/validate.md +233 -0
- package/templates/commands/workflow.md +193 -193
- package/templates/skills/ai-prompt/SKILL.md +778 -778
- package/templates/skills/application/SKILL.md +563 -563
- package/templates/skills/application/templates-backend.md +450 -450
- package/templates/skills/application/templates-frontend.md +531 -531
- package/templates/skills/application/templates-i18n.md +520 -520
- package/templates/skills/application/templates-seed.md +647 -647
- package/templates/skills/controller/SKILL.md +240 -240
- package/templates/skills/controller/postman-templates.md +614 -614
- package/templates/skills/controller/templates.md +1468 -1468
- package/templates/skills/documentation/SKILL.md +133 -133
- package/templates/skills/documentation/templates.md +476 -476
- package/templates/skills/feature-full/SKILL.md +838 -838
- package/templates/skills/notification/SKILL.md +555 -555
- package/templates/skills/ui-components/SKILL.md +870 -870
- package/templates/skills/workflow/SKILL.md +582 -582
|
@@ -1,315 +1,315 @@
|
|
|
1
|
-
# /ai-prompt - Gestion Prompts IA SmartStack
|
|
2
|
-
|
|
3
|
-
> **Synergie Skill/Commande:**
|
|
4
|
-
> - **Skill** (`templates/skills/ai-prompt/`) → Invocation automatique par Claude
|
|
5
|
-
> - **Commande** (`/ai-prompt`) → Invocation manuelle par l'utilisateur
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## ARGUMENTS
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
/ai-prompt <action> [options]
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
| Action | Description |
|
|
16
|
-
|--------|-------------|
|
|
17
|
-
| `create` | Creer un nouveau prompt avec blocks |
|
|
18
|
-
| `schema` | Creer un schema de validation |
|
|
19
|
-
| `integrate` | Integrer l'IA dans un service existant |
|
|
20
|
-
| `test` | Tester un prompt avec des variables |
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## WORKFLOW
|
|
25
|
-
|
|
26
|
-
### /ai-prompt create
|
|
27
|
-
|
|
28
|
-
Cree un nouveau prompt avec ses blocks.
|
|
29
|
-
|
|
30
|
-
**Questions:**
|
|
31
|
-
1. Code du prompt ? (kebab-case)
|
|
32
|
-
2. Nom descriptif ?
|
|
33
|
-
3. Description ?
|
|
34
|
-
4. Type ? (Analyzer, Generator, Classifier, Assistant)
|
|
35
|
-
5. Blocks a creer ? (System, User, Examples)
|
|
36
|
-
6. Schema de validation ? (oui/non)
|
|
37
|
-
|
|
38
|
-
**Actions:**
|
|
39
|
-
1. Creer le prompt via API ou seed
|
|
40
|
-
2. Ajouter les blocks
|
|
41
|
-
3. Creer le schema si requis
|
|
42
|
-
4. Lier le schema au prompt
|
|
43
|
-
|
|
44
|
-
### /ai-prompt schema
|
|
45
|
-
|
|
46
|
-
Cree un schema de validation JSON.
|
|
47
|
-
|
|
48
|
-
**Questions:**
|
|
49
|
-
1. Code du schema ?
|
|
50
|
-
2. Nom ?
|
|
51
|
-
3. Proprietes requises ?
|
|
52
|
-
4. Type .NET associe ?
|
|
53
|
-
|
|
54
|
-
**Actions:**
|
|
55
|
-
1. Generer le JSON Schema
|
|
56
|
-
2. Creer le DTO C# correspondant
|
|
57
|
-
3. Ajouter dans la base de donnees
|
|
58
|
-
|
|
59
|
-
### /ai-prompt integrate
|
|
60
|
-
|
|
61
|
-
Integre l'execution IA dans un service existant.
|
|
62
|
-
|
|
63
|
-
**Questions:**
|
|
64
|
-
1. Quel service modifier ?
|
|
65
|
-
2. Quelle methode ajouter ? (Analyze, Generate, Classify)
|
|
66
|
-
3. Quel prompt utiliser ?
|
|
67
|
-
4. Retour type ?
|
|
68
|
-
|
|
69
|
-
**Actions:**
|
|
70
|
-
1. Injecter `IAiCompletionService`
|
|
71
|
-
2. Creer la methode d'execution
|
|
72
|
-
3. Ajouter la validation du resultat
|
|
73
|
-
4. Logger l'execution
|
|
74
|
-
|
|
75
|
-
### /ai-prompt test
|
|
76
|
-
|
|
77
|
-
Teste un prompt avec des variables.
|
|
78
|
-
|
|
79
|
-
**Questions:**
|
|
80
|
-
1. Quel prompt tester ?
|
|
81
|
-
2. Variables a injecter ?
|
|
82
|
-
|
|
83
|
-
**Actions:**
|
|
84
|
-
1. Afficher le prompt rendu
|
|
85
|
-
2. Executer contre le provider
|
|
86
|
-
3. Afficher le resultat et les metriques
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## TEMPLATES
|
|
91
|
-
|
|
92
|
-
### Template Prompt Block System
|
|
93
|
-
|
|
94
|
-
```csharp
|
|
95
|
-
new CreateBlockRequest
|
|
96
|
-
{
|
|
97
|
-
BlockType = PromptBlockType.System,
|
|
98
|
-
Label = "Instructions",
|
|
99
|
-
Content = @"Tu es un expert en $DOMAIN.
|
|
100
|
-
Analyse le contenu fourni et retourne:
|
|
101
|
-
- $OUTPUT_1
|
|
102
|
-
- $OUTPUT_2
|
|
103
|
-
- $OUTPUT_3
|
|
104
|
-
|
|
105
|
-
Reponds UNIQUEMENT en JSON valide correspondant au schema fourni.",
|
|
106
|
-
DisplayOrder = 1,
|
|
107
|
-
IsRequired = true
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### Template Prompt Block User
|
|
112
|
-
|
|
113
|
-
```csharp
|
|
114
|
-
new CreateBlockRequest
|
|
115
|
-
{
|
|
116
|
-
BlockType = PromptBlockType.User,
|
|
117
|
-
Label = "Input",
|
|
118
|
-
Content = "Contenu: {{content}}\nContexte: {{context}}",
|
|
119
|
-
DisplayOrder = 2,
|
|
120
|
-
IsRequired = true
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### Template JSON Schema
|
|
125
|
-
|
|
126
|
-
```json
|
|
127
|
-
{
|
|
128
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
129
|
-
"type": "object",
|
|
130
|
-
"required": ["$PROP_1", "$PROP_2"],
|
|
131
|
-
"properties": {
|
|
132
|
-
"$PROP_1": {
|
|
133
|
-
"type": "string",
|
|
134
|
-
"description": "$DESCRIPTION_1"
|
|
135
|
-
},
|
|
136
|
-
"$PROP_2": {
|
|
137
|
-
"type": "integer",
|
|
138
|
-
"minimum": 1,
|
|
139
|
-
"maximum": 10,
|
|
140
|
-
"description": "$DESCRIPTION_2"
|
|
141
|
-
},
|
|
142
|
-
"$PROP_3": {
|
|
143
|
-
"type": "array",
|
|
144
|
-
"items": { "type": "string" },
|
|
145
|
-
"maxItems": 5,
|
|
146
|
-
"description": "$DESCRIPTION_3"
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Template DTO Result
|
|
153
|
-
|
|
154
|
-
```csharp
|
|
155
|
-
// Application/AI/{Entity}AnalysisResult.cs
|
|
156
|
-
|
|
157
|
-
public class {Entity}AnalysisResult
|
|
158
|
-
{
|
|
159
|
-
[JsonPropertyName("$PROP_1")]
|
|
160
|
-
public string $Prop1 { get; set; } = string.Empty;
|
|
161
|
-
|
|
162
|
-
[JsonPropertyName("$PROP_2")]
|
|
163
|
-
public int $Prop2 { get; set; }
|
|
164
|
-
|
|
165
|
-
[JsonPropertyName("$PROP_3")]
|
|
166
|
-
public List<string> $Prop3 { get; set; } = new();
|
|
167
|
-
}
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Template Service Integration
|
|
171
|
-
|
|
172
|
-
```csharp
|
|
173
|
-
public async Task<{Entity}AnalysisResult?> Analyze{Entity}Async(
|
|
174
|
-
Guid entityId,
|
|
175
|
-
CancellationToken ct)
|
|
176
|
-
{
|
|
177
|
-
var entity = await _context.{Entity}s.FindAsync(entityId);
|
|
178
|
-
if (entity == null) return null;
|
|
179
|
-
|
|
180
|
-
try
|
|
181
|
-
{
|
|
182
|
-
var result = await _aiCompletionService
|
|
183
|
-
.ExecutePromptByCodeWithValidationAsync<{Entity}AnalysisResult>(
|
|
184
|
-
"{entity}-analyzer",
|
|
185
|
-
new Dictionary<string, object>
|
|
186
|
-
{
|
|
187
|
-
["content"] = entity.Content,
|
|
188
|
-
["context"] = entity.Context ?? ""
|
|
189
|
-
},
|
|
190
|
-
cancellationToken: ct);
|
|
191
|
-
|
|
192
|
-
if (result.Success && result.IsValid)
|
|
193
|
-
{
|
|
194
|
-
_logger.LogInformation(
|
|
195
|
-
"{Entity} {EntityId} analyzed in {Ms}ms: {Result}",
|
|
196
|
-
entityId,
|
|
197
|
-
result.ExecutionTimeMs,
|
|
198
|
-
result.Data.$Prop1);
|
|
199
|
-
|
|
200
|
-
return result.Data;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
if (!result.Success)
|
|
204
|
-
{
|
|
205
|
-
_logger.LogError(
|
|
206
|
-
"AI analysis failed for {Entity} {EntityId}: {Error}",
|
|
207
|
-
entityId, result.Error);
|
|
208
|
-
}
|
|
209
|
-
else if (!result.IsValid)
|
|
210
|
-
{
|
|
211
|
-
_logger.LogWarning(
|
|
212
|
-
"AI response invalid for {Entity} {EntityId}: {Errors}",
|
|
213
|
-
entityId, string.Join(", ", result.ValidationErrors));
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
catch (Exception ex)
|
|
219
|
-
{
|
|
220
|
-
_logger.LogError(ex, "Exception analyzing {Entity} {EntityId}", entityId);
|
|
221
|
-
return null;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### Template Controller Endpoint
|
|
227
|
-
|
|
228
|
-
```csharp
|
|
229
|
-
[HttpPost("{id}/analyze")]
|
|
230
|
-
[RequirePermission(Permissions.$Module.$Entity.Update)]
|
|
231
|
-
[ProducesResponseType(typeof({Entity}AnalysisResult), StatusCodes.Status200OK)]
|
|
232
|
-
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
233
|
-
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
234
|
-
public async Task<ActionResult<{Entity}AnalysisResult>> Analyze{Entity}(
|
|
235
|
-
Guid id,
|
|
236
|
-
CancellationToken ct)
|
|
237
|
-
{
|
|
238
|
-
var result = await _service.Analyze{Entity}Async(id, ct);
|
|
239
|
-
|
|
240
|
-
if (result == null)
|
|
241
|
-
return BadRequest(new { message = "Analysis failed" });
|
|
242
|
-
|
|
243
|
-
return Ok(result);
|
|
244
|
-
}
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
### Template Frontend Button
|
|
248
|
-
|
|
249
|
-
```tsx
|
|
250
|
-
import { Sparkles, Loader2 } from 'lucide-react';
|
|
251
|
-
|
|
252
|
-
interface AiAnalyzeButtonProps {
|
|
253
|
-
entityId: string;
|
|
254
|
-
onResult: (result: AnalysisResult) => void;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
export function AiAnalyzeButton({ entityId, onResult }: AiAnalyzeButtonProps) {
|
|
258
|
-
const [loading, setLoading] = useState(false);
|
|
259
|
-
|
|
260
|
-
const handleAnalyze = async () => {
|
|
261
|
-
setLoading(true);
|
|
262
|
-
try {
|
|
263
|
-
const result = await {module}Api.analyze(entityId);
|
|
264
|
-
onResult(result);
|
|
265
|
-
toast.success('Analyse terminee');
|
|
266
|
-
} catch (error) {
|
|
267
|
-
toast.error('Erreur lors de l\'analyse');
|
|
268
|
-
} finally {
|
|
269
|
-
setLoading(false);
|
|
270
|
-
}
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
return (
|
|
274
|
-
<button
|
|
275
|
-
onClick={handleAnalyze}
|
|
276
|
-
disabled={loading}
|
|
277
|
-
className="inline-flex items-center gap-2 px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 disabled:opacity-50"
|
|
278
|
-
>
|
|
279
|
-
{loading ? (
|
|
280
|
-
<Loader2 className="w-4 h-4 animate-spin" />
|
|
281
|
-
) : (
|
|
282
|
-
<Sparkles className="w-4 h-4" />
|
|
283
|
-
)}
|
|
284
|
-
Analyser avec IA
|
|
285
|
-
</button>
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
---
|
|
291
|
-
|
|
292
|
-
## FICHIERS CLES
|
|
293
|
-
|
|
294
|
-
| Fichier | Role |
|
|
295
|
-
|---------|------|
|
|
296
|
-
| `Domain/AI/Prompts/Prompt.cs` | Entite prompt |
|
|
297
|
-
| `Domain/AI/Schemas/OutputSchema.cs` | Schema validation |
|
|
298
|
-
| `Application/Common/Interfaces/IAiCompletionService.cs` | Interface |
|
|
299
|
-
| `Infrastructure/Services/AI/AiCompletionService.cs` | Implementation |
|
|
300
|
-
| `Infrastructure/Services/AI/PromptService.cs` | Gestion prompts |
|
|
301
|
-
|
|
302
|
-
---
|
|
303
|
-
|
|
304
|
-
## REGLES
|
|
305
|
-
|
|
306
|
-
1. **TOUJOURS** creer un schema de validation pour les reponses structurees
|
|
307
|
-
2. **TOUJOURS** creer le DTO C# correspondant au schema
|
|
308
|
-
3. **TOUJOURS** logger les executions avec tokens et duree
|
|
309
|
-
4. **TOUJOURS** gerer les erreurs (API down, validation)
|
|
310
|
-
5. **JAMAIS** exposer les prompts systeme au frontend
|
|
311
|
-
6. **JAMAIS** hardcoder les cles API
|
|
312
|
-
|
|
313
|
-
---
|
|
314
|
-
|
|
315
|
-
User: $ARGUMENTS
|
|
1
|
+
# /ai-prompt - Gestion Prompts IA SmartStack
|
|
2
|
+
|
|
3
|
+
> **Synergie Skill/Commande:**
|
|
4
|
+
> - **Skill** (`templates/skills/ai-prompt/`) → Invocation automatique par Claude
|
|
5
|
+
> - **Commande** (`/ai-prompt`) → Invocation manuelle par l'utilisateur
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## ARGUMENTS
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
/ai-prompt <action> [options]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
| Action | Description |
|
|
16
|
+
|--------|-------------|
|
|
17
|
+
| `create` | Creer un nouveau prompt avec blocks |
|
|
18
|
+
| `schema` | Creer un schema de validation |
|
|
19
|
+
| `integrate` | Integrer l'IA dans un service existant |
|
|
20
|
+
| `test` | Tester un prompt avec des variables |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## WORKFLOW
|
|
25
|
+
|
|
26
|
+
### /ai-prompt create
|
|
27
|
+
|
|
28
|
+
Cree un nouveau prompt avec ses blocks.
|
|
29
|
+
|
|
30
|
+
**Questions:**
|
|
31
|
+
1. Code du prompt ? (kebab-case)
|
|
32
|
+
2. Nom descriptif ?
|
|
33
|
+
3. Description ?
|
|
34
|
+
4. Type ? (Analyzer, Generator, Classifier, Assistant)
|
|
35
|
+
5. Blocks a creer ? (System, User, Examples)
|
|
36
|
+
6. Schema de validation ? (oui/non)
|
|
37
|
+
|
|
38
|
+
**Actions:**
|
|
39
|
+
1. Creer le prompt via API ou seed
|
|
40
|
+
2. Ajouter les blocks
|
|
41
|
+
3. Creer le schema si requis
|
|
42
|
+
4. Lier le schema au prompt
|
|
43
|
+
|
|
44
|
+
### /ai-prompt schema
|
|
45
|
+
|
|
46
|
+
Cree un schema de validation JSON.
|
|
47
|
+
|
|
48
|
+
**Questions:**
|
|
49
|
+
1. Code du schema ?
|
|
50
|
+
2. Nom ?
|
|
51
|
+
3. Proprietes requises ?
|
|
52
|
+
4. Type .NET associe ?
|
|
53
|
+
|
|
54
|
+
**Actions:**
|
|
55
|
+
1. Generer le JSON Schema
|
|
56
|
+
2. Creer le DTO C# correspondant
|
|
57
|
+
3. Ajouter dans la base de donnees
|
|
58
|
+
|
|
59
|
+
### /ai-prompt integrate
|
|
60
|
+
|
|
61
|
+
Integre l'execution IA dans un service existant.
|
|
62
|
+
|
|
63
|
+
**Questions:**
|
|
64
|
+
1. Quel service modifier ?
|
|
65
|
+
2. Quelle methode ajouter ? (Analyze, Generate, Classify)
|
|
66
|
+
3. Quel prompt utiliser ?
|
|
67
|
+
4. Retour type ?
|
|
68
|
+
|
|
69
|
+
**Actions:**
|
|
70
|
+
1. Injecter `IAiCompletionService`
|
|
71
|
+
2. Creer la methode d'execution
|
|
72
|
+
3. Ajouter la validation du resultat
|
|
73
|
+
4. Logger l'execution
|
|
74
|
+
|
|
75
|
+
### /ai-prompt test
|
|
76
|
+
|
|
77
|
+
Teste un prompt avec des variables.
|
|
78
|
+
|
|
79
|
+
**Questions:**
|
|
80
|
+
1. Quel prompt tester ?
|
|
81
|
+
2. Variables a injecter ?
|
|
82
|
+
|
|
83
|
+
**Actions:**
|
|
84
|
+
1. Afficher le prompt rendu
|
|
85
|
+
2. Executer contre le provider
|
|
86
|
+
3. Afficher le resultat et les metriques
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## TEMPLATES
|
|
91
|
+
|
|
92
|
+
### Template Prompt Block System
|
|
93
|
+
|
|
94
|
+
```csharp
|
|
95
|
+
new CreateBlockRequest
|
|
96
|
+
{
|
|
97
|
+
BlockType = PromptBlockType.System,
|
|
98
|
+
Label = "Instructions",
|
|
99
|
+
Content = @"Tu es un expert en $DOMAIN.
|
|
100
|
+
Analyse le contenu fourni et retourne:
|
|
101
|
+
- $OUTPUT_1
|
|
102
|
+
- $OUTPUT_2
|
|
103
|
+
- $OUTPUT_3
|
|
104
|
+
|
|
105
|
+
Reponds UNIQUEMENT en JSON valide correspondant au schema fourni.",
|
|
106
|
+
DisplayOrder = 1,
|
|
107
|
+
IsRequired = true
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Template Prompt Block User
|
|
112
|
+
|
|
113
|
+
```csharp
|
|
114
|
+
new CreateBlockRequest
|
|
115
|
+
{
|
|
116
|
+
BlockType = PromptBlockType.User,
|
|
117
|
+
Label = "Input",
|
|
118
|
+
Content = "Contenu: {{content}}\nContexte: {{context}}",
|
|
119
|
+
DisplayOrder = 2,
|
|
120
|
+
IsRequired = true
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Template JSON Schema
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
129
|
+
"type": "object",
|
|
130
|
+
"required": ["$PROP_1", "$PROP_2"],
|
|
131
|
+
"properties": {
|
|
132
|
+
"$PROP_1": {
|
|
133
|
+
"type": "string",
|
|
134
|
+
"description": "$DESCRIPTION_1"
|
|
135
|
+
},
|
|
136
|
+
"$PROP_2": {
|
|
137
|
+
"type": "integer",
|
|
138
|
+
"minimum": 1,
|
|
139
|
+
"maximum": 10,
|
|
140
|
+
"description": "$DESCRIPTION_2"
|
|
141
|
+
},
|
|
142
|
+
"$PROP_3": {
|
|
143
|
+
"type": "array",
|
|
144
|
+
"items": { "type": "string" },
|
|
145
|
+
"maxItems": 5,
|
|
146
|
+
"description": "$DESCRIPTION_3"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Template DTO Result
|
|
153
|
+
|
|
154
|
+
```csharp
|
|
155
|
+
// Application/AI/{Entity}AnalysisResult.cs
|
|
156
|
+
|
|
157
|
+
public class {Entity}AnalysisResult
|
|
158
|
+
{
|
|
159
|
+
[JsonPropertyName("$PROP_1")]
|
|
160
|
+
public string $Prop1 { get; set; } = string.Empty;
|
|
161
|
+
|
|
162
|
+
[JsonPropertyName("$PROP_2")]
|
|
163
|
+
public int $Prop2 { get; set; }
|
|
164
|
+
|
|
165
|
+
[JsonPropertyName("$PROP_3")]
|
|
166
|
+
public List<string> $Prop3 { get; set; } = new();
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Template Service Integration
|
|
171
|
+
|
|
172
|
+
```csharp
|
|
173
|
+
public async Task<{Entity}AnalysisResult?> Analyze{Entity}Async(
|
|
174
|
+
Guid entityId,
|
|
175
|
+
CancellationToken ct)
|
|
176
|
+
{
|
|
177
|
+
var entity = await _context.{Entity}s.FindAsync(entityId);
|
|
178
|
+
if (entity == null) return null;
|
|
179
|
+
|
|
180
|
+
try
|
|
181
|
+
{
|
|
182
|
+
var result = await _aiCompletionService
|
|
183
|
+
.ExecutePromptByCodeWithValidationAsync<{Entity}AnalysisResult>(
|
|
184
|
+
"{entity}-analyzer",
|
|
185
|
+
new Dictionary<string, object>
|
|
186
|
+
{
|
|
187
|
+
["content"] = entity.Content,
|
|
188
|
+
["context"] = entity.Context ?? ""
|
|
189
|
+
},
|
|
190
|
+
cancellationToken: ct);
|
|
191
|
+
|
|
192
|
+
if (result.Success && result.IsValid)
|
|
193
|
+
{
|
|
194
|
+
_logger.LogInformation(
|
|
195
|
+
"{Entity} {EntityId} analyzed in {Ms}ms: {Result}",
|
|
196
|
+
entityId,
|
|
197
|
+
result.ExecutionTimeMs,
|
|
198
|
+
result.Data.$Prop1);
|
|
199
|
+
|
|
200
|
+
return result.Data;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (!result.Success)
|
|
204
|
+
{
|
|
205
|
+
_logger.LogError(
|
|
206
|
+
"AI analysis failed for {Entity} {EntityId}: {Error}",
|
|
207
|
+
entityId, result.Error);
|
|
208
|
+
}
|
|
209
|
+
else if (!result.IsValid)
|
|
210
|
+
{
|
|
211
|
+
_logger.LogWarning(
|
|
212
|
+
"AI response invalid for {Entity} {EntityId}: {Errors}",
|
|
213
|
+
entityId, string.Join(", ", result.ValidationErrors));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
catch (Exception ex)
|
|
219
|
+
{
|
|
220
|
+
_logger.LogError(ex, "Exception analyzing {Entity} {EntityId}", entityId);
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Template Controller Endpoint
|
|
227
|
+
|
|
228
|
+
```csharp
|
|
229
|
+
[HttpPost("{id}/analyze")]
|
|
230
|
+
[RequirePermission(Permissions.$Module.$Entity.Update)]
|
|
231
|
+
[ProducesResponseType(typeof({Entity}AnalysisResult), StatusCodes.Status200OK)]
|
|
232
|
+
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
233
|
+
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
234
|
+
public async Task<ActionResult<{Entity}AnalysisResult>> Analyze{Entity}(
|
|
235
|
+
Guid id,
|
|
236
|
+
CancellationToken ct)
|
|
237
|
+
{
|
|
238
|
+
var result = await _service.Analyze{Entity}Async(id, ct);
|
|
239
|
+
|
|
240
|
+
if (result == null)
|
|
241
|
+
return BadRequest(new { message = "Analysis failed" });
|
|
242
|
+
|
|
243
|
+
return Ok(result);
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Template Frontend Button
|
|
248
|
+
|
|
249
|
+
```tsx
|
|
250
|
+
import { Sparkles, Loader2 } from 'lucide-react';
|
|
251
|
+
|
|
252
|
+
interface AiAnalyzeButtonProps {
|
|
253
|
+
entityId: string;
|
|
254
|
+
onResult: (result: AnalysisResult) => void;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export function AiAnalyzeButton({ entityId, onResult }: AiAnalyzeButtonProps) {
|
|
258
|
+
const [loading, setLoading] = useState(false);
|
|
259
|
+
|
|
260
|
+
const handleAnalyze = async () => {
|
|
261
|
+
setLoading(true);
|
|
262
|
+
try {
|
|
263
|
+
const result = await {module}Api.analyze(entityId);
|
|
264
|
+
onResult(result);
|
|
265
|
+
toast.success('Analyse terminee');
|
|
266
|
+
} catch (error) {
|
|
267
|
+
toast.error('Erreur lors de l\'analyse');
|
|
268
|
+
} finally {
|
|
269
|
+
setLoading(false);
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
return (
|
|
274
|
+
<button
|
|
275
|
+
onClick={handleAnalyze}
|
|
276
|
+
disabled={loading}
|
|
277
|
+
className="inline-flex items-center gap-2 px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 disabled:opacity-50"
|
|
278
|
+
>
|
|
279
|
+
{loading ? (
|
|
280
|
+
<Loader2 className="w-4 h-4 animate-spin" />
|
|
281
|
+
) : (
|
|
282
|
+
<Sparkles className="w-4 h-4" />
|
|
283
|
+
)}
|
|
284
|
+
Analyser avec IA
|
|
285
|
+
</button>
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## FICHIERS CLES
|
|
293
|
+
|
|
294
|
+
| Fichier | Role |
|
|
295
|
+
|---------|------|
|
|
296
|
+
| `Domain/AI/Prompts/Prompt.cs` | Entite prompt |
|
|
297
|
+
| `Domain/AI/Schemas/OutputSchema.cs` | Schema validation |
|
|
298
|
+
| `Application/Common/Interfaces/IAiCompletionService.cs` | Interface |
|
|
299
|
+
| `Infrastructure/Services/AI/AiCompletionService.cs` | Implementation |
|
|
300
|
+
| `Infrastructure/Services/AI/PromptService.cs` | Gestion prompts |
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## REGLES
|
|
305
|
+
|
|
306
|
+
1. **TOUJOURS** creer un schema de validation pour les reponses structurees
|
|
307
|
+
2. **TOUJOURS** creer le DTO C# correspondant au schema
|
|
308
|
+
3. **TOUJOURS** logger les executions avec tokens et duree
|
|
309
|
+
4. **TOUJOURS** gerer les erreurs (API down, validation)
|
|
310
|
+
5. **JAMAIS** exposer les prompts systeme au frontend
|
|
311
|
+
6. **JAMAIS** hardcoder les cles API
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
User: $ARGUMENTS
|