@relipa/ai-flow-kit 0.0.4-beta.3 → 0.0.5-beta.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/README.md +10 -4
- package/bin/aiflow.js +77 -7
- package/custom/templates/laravel.md +15 -15
- package/custom/templates/nestjs.md +72 -72
- package/custom/templates/nextjs.md +14 -14
- package/custom/templates/nodejs-express.md +73 -73
- package/custom/templates/python-django.md +71 -71
- package/custom/templates/python-fastapi.md +54 -54
- package/custom/templates/reactjs.md +492 -492
- package/custom/templates/shared/gate-workflow.md +88 -75
- package/custom/templates/spring-boot.md +523 -523
- package/custom/templates/tools/claude.md +13 -0
- package/custom/templates/tools/copilot.md +12 -8
- package/custom/templates/tools/cursor.md +12 -8
- package/custom/templates/tools/gemini.md +12 -8
- package/custom/templates/tools/generic.md +17 -12
- package/custom/templates/vue-nuxt.md +14 -14
- package/{AIFLOW.md → docs/AIFLOW.md} +5 -0
- package/{CHANGELOG.md → docs/CHANGELOG.md} +41 -5
- package/{IMPLEMENTATION_SUMMARY.md → docs/IMPLEMENTATION_SUMMARY.md} +21 -39
- package/{QUICK_START.md → docs/QUICK_START.md} +8 -8
- package/docs/ai-integration.md +53 -53
- package/docs/architecture.md +4 -5
- package/docs/cli-reference.md +97 -27
- package/docs/developer-overview.md +126 -126
- package/docs/troubleshooting.md +15 -0
- package/package.json +6 -11
- package/scripts/guide.js +16 -0
- package/scripts/hooks/session-start.js +5 -1
- package/scripts/init.js +518 -460
- package/scripts/telemetry/cli.js +249 -0
- package/scripts/telemetry/config.js +94 -0
- package/scripts/telemetry/crypto.js +20 -0
- package/scripts/telemetry/flush.js +159 -0
- package/scripts/telemetry/record.js +138 -0
- package/scripts/use.js +594 -594
- package/upstream/skills/using-superpowers/SKILL.md +14 -0
- package/CONTRIBUTING.md +0 -388
- package/upstream/tests/brainstorm-server/package-lock.json +0 -36
package/README.md
CHANGED
|
@@ -23,10 +23,9 @@ Developers only need a single command to load ticket context → AI automaticall
|
|
|
23
23
|
> [!TIP]
|
|
24
24
|
> After running `aiflow init`, all documentation files are automatically copied to your project root and `.aiflow/docs/` for easy access.
|
|
25
25
|
|
|
26
|
-
- **[Quick Start Guide](./QUICK_START.md)** — Step-by-step instructions for developers.
|
|
27
|
-
- **[Full Workflow (5 Gates)](./AIFLOW.md)** — In-depth look at the Gate process.
|
|
26
|
+
- **[Quick Start Guide](./docs/QUICK_START.md)** — Step-by-step instructions for developers.
|
|
27
|
+
- **[Full Workflow (5 Gates)](./docs/AIFLOW.md)** — In-depth look at the Gate process.
|
|
28
28
|
- **[Developer Onboarding](./docs/developer-overview.md)** — Presentation-ready guide for new team members.
|
|
29
|
-
- **[Contributing Guide](./CONTRIBUTING.md)** — How to extend with new skills/templates.
|
|
30
29
|
- **[Troubleshooting](./docs/troubleshooting.md)** — Common issues and fixes.
|
|
31
30
|
- **[Integration Guide](./docs/ai-integration.md)** — Advanced tool setup (Claude, Cursor, Gemini).
|
|
32
31
|
|
|
@@ -123,6 +122,7 @@ npm uninstall -g @relipa/ai-flow-kit
|
|
|
123
122
|
| `aiflow init` | Setup framework, adapters, and multi-AI rules. |
|
|
124
123
|
| `aiflow use <ticket>` | Load ticket context (Backlog/Jira). |
|
|
125
124
|
| `aiflow prompt` | Generate tool-optimized prompts (`--env cursor`). |
|
|
125
|
+
| `aiflow telemetry` | Manage telemetry tracking (enable/disable/status). |
|
|
126
126
|
| `aiflow guide` | View integrated multi-AI integration guide. |
|
|
127
127
|
|
|
128
128
|
### `aiflow init`
|
|
@@ -281,7 +281,13 @@ aiflow memory --list
|
|
|
281
281
|
|
|
282
282
|
```
|
|
283
283
|
ai-flow-kit/
|
|
284
|
+
├── README.md # Main documentation
|
|
284
285
|
├── bin/aiflow.js # CLI entry
|
|
286
|
+
├── docs/ # Documentation and Guides
|
|
287
|
+
│ ├── QUICK_START.md # Quick start guide
|
|
288
|
+
│ ├── AIFLOW.md # Workflow (5 Gates) detail
|
|
289
|
+
│ ├── CHANGELOG.md # Version history
|
|
290
|
+
│ └── ... # Other guides
|
|
285
291
|
├── scripts/
|
|
286
292
|
│ ├── init.js # Project initialization
|
|
287
293
|
│ ├── update.js # Version management
|
|
@@ -297,7 +303,7 @@ ai-flow-kit/
|
|
|
297
303
|
│ ├── rules/java/ # Java/Spring Boot rules
|
|
298
304
|
│ ├── rules/php/ # PHP/Laravel rules
|
|
299
305
|
│ ├── rules/javascript/ # JS/TS rules
|
|
300
|
-
│ ├── templates/ # Framework
|
|
306
|
+
│ ├── templates/ # Framework tool templates
|
|
301
307
|
│ ├── prompts/ # Task prompt templates
|
|
302
308
|
│ └── mcp-presets/ # Backlog/Jira/Sheets config
|
|
303
309
|
└── upstream/ # obra/superpowers (inherited)
|
package/bin/aiflow.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { program } = require('commander');
|
|
4
4
|
const chalk = require('chalk');
|
|
@@ -14,11 +14,45 @@ const contextCommand = require('../scripts/context');
|
|
|
14
14
|
const promptCommand = require('../scripts/prompt');
|
|
15
15
|
const removeCommand = require('../scripts/remove');
|
|
16
16
|
const guideCommand = require('../scripts/guide');
|
|
17
|
+
const telemetryCommand= require('../scripts/telemetry/cli');
|
|
18
|
+
const { record } = require('../scripts/telemetry/record');
|
|
17
19
|
|
|
18
20
|
program
|
|
19
21
|
.version(packageJson.version)
|
|
20
22
|
.description('AI Flow Kit CLI - AI-powered development workflows for teams');
|
|
21
23
|
|
|
24
|
+
// ── GLOBAL TELEMETRY HOOK ────────────────────────────────────
|
|
25
|
+
// We intercept raw argv here so we can catch --version, --help,
|
|
26
|
+
// and invalid commands *before* Commander exits the process.
|
|
27
|
+
(() => {
|
|
28
|
+
const args = process.argv.slice(2);
|
|
29
|
+
let cmd = 'help';
|
|
30
|
+
if (args.length > 0) {
|
|
31
|
+
const first = args[0];
|
|
32
|
+
if (['-V', '-v', '--version'].includes(first)) {
|
|
33
|
+
cmd = 'version';
|
|
34
|
+
} else if (['-h', '--help'].includes(first)) {
|
|
35
|
+
cmd = 'help';
|
|
36
|
+
} else if (first.startsWith('-')) {
|
|
37
|
+
cmd = 'unknown_flag';
|
|
38
|
+
if (args.includes('--help') || args.includes('-h')) cmd = 'help';
|
|
39
|
+
} else if (first === 'memory') {
|
|
40
|
+
const sec = args[1];
|
|
41
|
+
cmd = (sec && !sec.startsWith('-')) ? `memory.${sec}` : 'memory';
|
|
42
|
+
} else {
|
|
43
|
+
cmd = first;
|
|
44
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
45
|
+
cmd = `${first}.help`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Record everything except telemetry and gate actions (gate records its own rich event)
|
|
50
|
+
if (cmd !== 'telemetry' && !cmd.startsWith('telemetry.') && cmd !== 'gate') {
|
|
51
|
+
record('command.invoked', { command: cmd });
|
|
52
|
+
}
|
|
53
|
+
})();
|
|
54
|
+
|
|
55
|
+
|
|
22
56
|
// ── init ──────────────────────────────────────────────────────
|
|
23
57
|
program
|
|
24
58
|
.command('init')
|
|
@@ -37,6 +71,7 @@ program
|
|
|
37
71
|
? options.env.split(',').map(s => s.trim()).filter(Boolean)
|
|
38
72
|
: Object.keys(require('../scripts/init').AI_TOOL_FILES || {});
|
|
39
73
|
|
|
74
|
+
record('command.invoked', { command: 'init' });
|
|
40
75
|
initCommand(options);
|
|
41
76
|
});
|
|
42
77
|
|
|
@@ -51,6 +86,7 @@ program
|
|
|
51
86
|
.option('--comments-last <n>', 'load only the last N comments', parseInt)
|
|
52
87
|
.option('--comments-from <n>', 'load comments from index N onward (0-based)', parseInt)
|
|
53
88
|
.action((target, options) => {
|
|
89
|
+
record('command.invoked', { command: 'use' });
|
|
54
90
|
useCommand(target, options);
|
|
55
91
|
});
|
|
56
92
|
|
|
@@ -63,6 +99,7 @@ program
|
|
|
63
99
|
.option('--lang <lang>', 'language: english (default) or vietnamese')
|
|
64
100
|
.option('--detail <level>', 'detail level: minimal | standard (default) | comprehensive')
|
|
65
101
|
.action((type, options) => {
|
|
102
|
+
record('command.invoked', { command: 'prompt' });
|
|
66
103
|
promptCommand(type, options);
|
|
67
104
|
});
|
|
68
105
|
|
|
@@ -73,6 +110,7 @@ program
|
|
|
73
110
|
.option('-v, --verbose', 'show detection details')
|
|
74
111
|
.option('-t, --threshold <number>', 'confidence threshold (0-100)')
|
|
75
112
|
.action((description, options) => {
|
|
113
|
+
record('command.invoked', { command: 'detect' });
|
|
76
114
|
const detector = new TaskDetector();
|
|
77
115
|
const threshold = options.threshold ? parseInt(options.threshold) / 100 : 0.8;
|
|
78
116
|
const result = detector.detect(description, threshold);
|
|
@@ -90,6 +128,7 @@ program
|
|
|
90
128
|
.option('--clear', 'clear all saved contexts')
|
|
91
129
|
.option('--show', 'show current context')
|
|
92
130
|
.action((action, options) => {
|
|
131
|
+
record('command.invoked', { command: 'context' });
|
|
93
132
|
contextCommand(action, options);
|
|
94
133
|
});
|
|
95
134
|
|
|
@@ -101,6 +140,7 @@ program
|
|
|
101
140
|
.option('-v, --verbose', 'detailed report')
|
|
102
141
|
.option('--fix', 'auto-fix trailing whitespace')
|
|
103
142
|
.action((file, options) => {
|
|
143
|
+
record('command.invoked', { command: 'validate' });
|
|
104
144
|
validateCommand(file, {
|
|
105
145
|
ruleset: options.ruleset,
|
|
106
146
|
verbose: options.verbose,
|
|
@@ -115,32 +155,32 @@ const memCmd = program.command('memory').description('Manage team knowledge and
|
|
|
115
155
|
memCmd
|
|
116
156
|
.command('save <key> <value>')
|
|
117
157
|
.description('Save a memory entry')
|
|
118
|
-
.action((key, value) => memoryCommand('save', { key, value }));
|
|
158
|
+
.action((key, value) => { record('command.invoked', { command: 'memory.save' }); memoryCommand('save', { key, value }); });
|
|
119
159
|
|
|
120
160
|
memCmd
|
|
121
161
|
.command('get <key>')
|
|
122
162
|
.description('Retrieve a memory entry')
|
|
123
|
-
.action((key) => memoryCommand('get', { key }));
|
|
163
|
+
.action((key) => { record('command.invoked', { command: 'memory.get' }); memoryCommand('get', { key }); });
|
|
124
164
|
|
|
125
165
|
memCmd
|
|
126
166
|
.command('list')
|
|
127
167
|
.description('List all memories')
|
|
128
|
-
.action(() => memoryCommand('list'));
|
|
168
|
+
.action(() => { record('command.invoked', { command: 'memory.list' }); memoryCommand('list'); });
|
|
129
169
|
|
|
130
170
|
memCmd
|
|
131
171
|
.command('search <query>')
|
|
132
172
|
.description('Search memories by keyword')
|
|
133
|
-
.action((query) => memoryCommand('search', { query }));
|
|
173
|
+
.action((query) => { record('command.invoked', { command: 'memory.search' }); memoryCommand('search', { query }); });
|
|
134
174
|
|
|
135
175
|
memCmd
|
|
136
176
|
.command('delete <key>')
|
|
137
177
|
.description('Delete a memory entry')
|
|
138
|
-
.action((key) => memoryCommand('delete', { key }));
|
|
178
|
+
.action((key) => { record('command.invoked', { command: 'memory.delete' }); memoryCommand('delete', { key }); });
|
|
139
179
|
|
|
140
180
|
memCmd
|
|
141
181
|
.command('clear')
|
|
142
182
|
.description('Clear all memories')
|
|
143
|
-
.action(() => memoryCommand('clear'));
|
|
183
|
+
.action(() => { record('command.invoked', { command: 'memory.clear' }); memoryCommand('clear'); });
|
|
144
184
|
|
|
145
185
|
// ── guide ─────────────────────────────────────────────────────
|
|
146
186
|
program
|
|
@@ -149,9 +189,28 @@ program
|
|
|
149
189
|
.option('--flow', 'show architecture & flow diagram only')
|
|
150
190
|
.option('--commands', 'show command reference only')
|
|
151
191
|
.action((options) => {
|
|
192
|
+
record('command.invoked', { command: 'guide' });
|
|
152
193
|
guideCommand(options);
|
|
153
194
|
});
|
|
154
195
|
|
|
196
|
+
// ── gate (telemetry for gate workflow events) ─────────────────
|
|
197
|
+
program
|
|
198
|
+
.command('gate <number> <action>')
|
|
199
|
+
.description('Log a gate workflow event (start|approved) — called by AI during gate workflow')
|
|
200
|
+
.option('--ticket <id>', 'ticket ID')
|
|
201
|
+
.option('--ai-tool <tool>', 'AI tool name')
|
|
202
|
+
.action((number, action, options) => {
|
|
203
|
+
const gateNum = parseInt(number);
|
|
204
|
+
if (isNaN(gateNum) || gateNum < 1 || gateNum > 5) return;
|
|
205
|
+
if (!['start', 'approved'].includes(action)) return;
|
|
206
|
+
record(`gate.${action}`, {
|
|
207
|
+
gate: gateNum,
|
|
208
|
+
ticket_id: options.ticket || '',
|
|
209
|
+
command: `gate${gateNum}.${action}`,
|
|
210
|
+
ai_tool: options.aiTool || ''
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
|
|
155
214
|
// ── remove ────────────────────────────────────────────────────
|
|
156
215
|
program
|
|
157
216
|
.command('remove')
|
|
@@ -159,6 +218,7 @@ program
|
|
|
159
218
|
.option('--version <ver>', 'remove a specific cached version from .aiflow/versions/')
|
|
160
219
|
.option('--global', 'uninstall the global npm package (removes `aiflow` command)')
|
|
161
220
|
.action((options) => {
|
|
221
|
+
record('command.invoked', { command: 'remove' });
|
|
162
222
|
removeCommand(options);
|
|
163
223
|
});
|
|
164
224
|
|
|
@@ -168,6 +228,7 @@ program
|
|
|
168
228
|
.description('Update to latest version')
|
|
169
229
|
.option('--force', 'force update even if already on latest')
|
|
170
230
|
.action((options) => {
|
|
231
|
+
record('command.invoked', { command: 'update' });
|
|
171
232
|
updateCommand(options);
|
|
172
233
|
});
|
|
173
234
|
|
|
@@ -177,7 +238,16 @@ program
|
|
|
177
238
|
.description('Health check of AI Flow Kit setup')
|
|
178
239
|
.option('-v, --verbose', 'detailed output')
|
|
179
240
|
.action(() => {
|
|
241
|
+
record('command.invoked', { command: 'doctor' });
|
|
180
242
|
doctorCommand();
|
|
181
243
|
});
|
|
182
244
|
|
|
245
|
+
// ── telemetry ──────────────────────────────────────────────────
|
|
246
|
+
program
|
|
247
|
+
.command('telemetry [action]')
|
|
248
|
+
.description('Manage telemetry logging (enable|disable|status)')
|
|
249
|
+
.action((action) => {
|
|
250
|
+
telemetryCommand(action || 'status');
|
|
251
|
+
});
|
|
252
|
+
|
|
183
253
|
program.parse(process.argv);
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
# Laravel AI System Prompt
|
|
2
|
-
|
|
3
|
-
You are an expert Laravel developer. Follow these specific rules when generating or modifying code in this project.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
- Use Laravel's built-in tools over custom solutions (e.g., Collections, Eloquent features, built-in validation rules).
|
|
8
|
-
- Keep Controllers thin. Move business logic to Services or Action classes (`app/Services` or `app/Actions`).
|
|
9
|
-
- Use FormRequests for validation, never validate inside the controller logic.
|
|
10
|
-
- Avoid N+1 queries. Always use `with()` when eager loading relationships.
|
|
11
|
-
- Return typed Responses or API Resources, never arbitrary arrays.
|
|
12
|
-
- Use strict typing natively in PHP 8+.
|
|
13
|
-
- Adhere to PSR-12 styling.
|
|
14
|
-
|
|
15
|
-
When explaining changes, refer to Laravel's official documentation conventions.
|
|
1
|
+
# Laravel AI System Prompt
|
|
2
|
+
|
|
3
|
+
You are an expert Laravel developer. Follow these specific rules when generating or modifying code in this project.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
- Use Laravel's built-in tools over custom solutions (e.g., Collections, Eloquent features, built-in validation rules).
|
|
8
|
+
- Keep Controllers thin. Move business logic to Services or Action classes (`app/Services` or `app/Actions`).
|
|
9
|
+
- Use FormRequests for validation, never validate inside the controller logic.
|
|
10
|
+
- Avoid N+1 queries. Always use `with()` when eager loading relationships.
|
|
11
|
+
- Return typed Responses or API Resources, never arbitrary arrays.
|
|
12
|
+
- Use strict typing natively in PHP 8+.
|
|
13
|
+
- Adhere to PSR-12 styling.
|
|
14
|
+
|
|
15
|
+
When explaining changes, refer to Laravel's official documentation conventions.
|
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
# NestJS AI System Prompt
|
|
2
|
-
|
|
3
|
-
You are an expert NestJS developer. Follow these modular architecture rules and best practices.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Project Architecture
|
|
8
|
-
|
|
9
|
-
NestJS follows a strict **Module-based** architecture. Every feature should be contained in its own module.
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
src/
|
|
13
|
-
├── app.module.ts
|
|
14
|
-
├── main.ts
|
|
15
|
-
└── features/
|
|
16
|
-
└── [feature-name]/
|
|
17
|
-
├── [feature].module.ts
|
|
18
|
-
├── [feature].controller.ts
|
|
19
|
-
├── [feature].service.ts
|
|
20
|
-
├── [feature].entity.ts (if using TypeORM)
|
|
21
|
-
└── dto/
|
|
22
|
-
├── create-[feature].dto.ts
|
|
23
|
-
└── update-[feature].dto.ts
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## NestJS Rules
|
|
29
|
-
|
|
30
|
-
- Use **Constructor Injection** for all dependencies.
|
|
31
|
-
- Always use **DTOs** (Data Transfer Objects) with `class-validator` for input validation.
|
|
32
|
-
- Annotate controllers with `@Controller()`.
|
|
33
|
-
- Use `@Injectable()` for services.
|
|
34
|
-
- Leverage **Pipes** for data transformation and validation.
|
|
35
|
-
- Leverage **Interceptors** for logging and response mapping.
|
|
36
|
-
|
|
37
|
-
```typescript
|
|
38
|
-
// ✅ Good: DTO with validation
|
|
39
|
-
export class CreateUserDto {
|
|
40
|
-
@IsEmail()
|
|
41
|
-
email: string;
|
|
42
|
-
|
|
43
|
-
@IsString()
|
|
44
|
-
@MinLength(8)
|
|
45
|
-
password: string;
|
|
46
|
-
}
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## Testing Rules
|
|
52
|
-
|
|
53
|
-
- Use the built-in **Jest** testing suite.
|
|
54
|
-
- Use `Test.createTestingModule` to create isolated environments for unit tests.
|
|
55
|
-
|
|
56
|
-
```typescript
|
|
57
|
-
describe('UsersService', () => {
|
|
58
|
-
let service: UsersService;
|
|
59
|
-
|
|
60
|
-
beforeEach(async () => {
|
|
61
|
-
const module: TestingModule = await Test.createTestingModule({
|
|
62
|
-
providers: [UsersService],
|
|
63
|
-
}).compile();
|
|
64
|
-
|
|
65
|
-
service = module.get<UsersService>(UsersService);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('should be defined', () => {
|
|
69
|
-
expect(service).toBeDefined();
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
```
|
|
1
|
+
# NestJS AI System Prompt
|
|
2
|
+
|
|
3
|
+
You are an expert NestJS developer. Follow these modular architecture rules and best practices.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Project Architecture
|
|
8
|
+
|
|
9
|
+
NestJS follows a strict **Module-based** architecture. Every feature should be contained in its own module.
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
src/
|
|
13
|
+
├── app.module.ts
|
|
14
|
+
├── main.ts
|
|
15
|
+
└── features/
|
|
16
|
+
└── [feature-name]/
|
|
17
|
+
├── [feature].module.ts
|
|
18
|
+
├── [feature].controller.ts
|
|
19
|
+
├── [feature].service.ts
|
|
20
|
+
├── [feature].entity.ts (if using TypeORM)
|
|
21
|
+
└── dto/
|
|
22
|
+
├── create-[feature].dto.ts
|
|
23
|
+
└── update-[feature].dto.ts
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## NestJS Rules
|
|
29
|
+
|
|
30
|
+
- Use **Constructor Injection** for all dependencies.
|
|
31
|
+
- Always use **DTOs** (Data Transfer Objects) with `class-validator` for input validation.
|
|
32
|
+
- Annotate controllers with `@Controller()`.
|
|
33
|
+
- Use `@Injectable()` for services.
|
|
34
|
+
- Leverage **Pipes** for data transformation and validation.
|
|
35
|
+
- Leverage **Interceptors** for logging and response mapping.
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// ✅ Good: DTO with validation
|
|
39
|
+
export class CreateUserDto {
|
|
40
|
+
@IsEmail()
|
|
41
|
+
email: string;
|
|
42
|
+
|
|
43
|
+
@IsString()
|
|
44
|
+
@MinLength(8)
|
|
45
|
+
password: string;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Testing Rules
|
|
52
|
+
|
|
53
|
+
- Use the built-in **Jest** testing suite.
|
|
54
|
+
- Use `Test.createTestingModule` to create isolated environments for unit tests.
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
describe('UsersService', () => {
|
|
58
|
+
let service: UsersService;
|
|
59
|
+
|
|
60
|
+
beforeEach(async () => {
|
|
61
|
+
const module: TestingModule = await Test.createTestingModule({
|
|
62
|
+
providers: [UsersService],
|
|
63
|
+
}).compile();
|
|
64
|
+
|
|
65
|
+
service = module.get<UsersService>(UsersService);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should be defined', () => {
|
|
69
|
+
expect(service).toBeDefined();
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
```
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
# Next.js AI System Prompt
|
|
2
|
-
|
|
3
|
-
You are an expert React & Next.js developer. Follow these specific rules.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
- Use the Next.js App Router (`app/` directory).
|
|
8
|
-
- Default to Server Components. Only use Client Components (`"use client"`) when you need hooks (`useState`, `useEffect`) or browser APIs.
|
|
9
|
-
- For data fetching, prefer native `fetch` with caching logic in Server Components. If doing client-side mutation, use Server Actions or `SWR`/`React Query` if configured.
|
|
10
|
-
- Style with CSS Modules or TailwindCSS (check project configuration).
|
|
11
|
-
- Ensure strict TypeScript typing. Avoid `any` at all costs.
|
|
12
|
-
- Place reusable isolated UI components in `components/ui/` and complex view logic in `components/`.
|
|
13
|
-
|
|
14
|
-
When explaining concepts, focus on SSR, CSR, and hydration best practices.
|
|
1
|
+
# Next.js AI System Prompt
|
|
2
|
+
|
|
3
|
+
You are an expert React & Next.js developer. Follow these specific rules.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
- Use the Next.js App Router (`app/` directory).
|
|
8
|
+
- Default to Server Components. Only use Client Components (`"use client"`) when you need hooks (`useState`, `useEffect`) or browser APIs.
|
|
9
|
+
- For data fetching, prefer native `fetch` with caching logic in Server Components. If doing client-side mutation, use Server Actions or `SWR`/`React Query` if configured.
|
|
10
|
+
- Style with CSS Modules or TailwindCSS (check project configuration).
|
|
11
|
+
- Ensure strict TypeScript typing. Avoid `any` at all costs.
|
|
12
|
+
- Place reusable isolated UI components in `components/ui/` and complex view logic in `components/`.
|
|
13
|
+
|
|
14
|
+
When explaining concepts, focus on SSR, CSR, and hydration best practices.
|
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
# Node.js Express AI System Prompt
|
|
2
|
-
|
|
3
|
-
You are an expert Node.js developer specialized in the Express.js framework. Follow these rules for building clean, maintainable, and secure backends.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Project Structure
|
|
8
|
-
|
|
9
|
-
Follow the **Controller-Service-Repository** pattern:
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
src/
|
|
13
|
-
├── controllers/ # Route handlers — parse input, call service, return response
|
|
14
|
-
├── services/ # Business logic — core logic, database transactions
|
|
15
|
-
├── repositories/ # Data access — database queries, ORM interactions
|
|
16
|
-
├── models/ # Database models (Sequelize/Prisma/Mongoose)
|
|
17
|
-
├── middleware/ # Custom Express middleware (auth, logging)
|
|
18
|
-
├── routes/ # Route definitions
|
|
19
|
-
├── dtos/ # Input/Output Data Transfer Objects (if using TS)
|
|
20
|
-
├── utils/ # Stateless helper functions
|
|
21
|
-
└── config/ # App configuration
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## Express Rules
|
|
27
|
-
|
|
28
|
-
- Use **Async/Await** for all asynchronous operations — avoid callbacks or manual promise chains.
|
|
29
|
-
- Always use a global error handler middleware. Never use `try/catch` in controllers if you use an async-wrapper middleware.
|
|
30
|
-
- Validate all incoming data using `Joi`, `Zod`, or `express-validator`.
|
|
31
|
-
- Keep controllers thin; they should only handle request parsing and response formatting.
|
|
32
|
-
|
|
33
|
-
```javascript
|
|
34
|
-
// ✅ Good: Controller calls service
|
|
35
|
-
export const createUser = async (req, res, next) => {
|
|
36
|
-
const userData = req.body;
|
|
37
|
-
const user = await userService.create(userData);
|
|
38
|
-
res.status(201).json(user);
|
|
39
|
-
};
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## Security Rules
|
|
45
|
-
|
|
46
|
-
- Never expose stack traces in production.
|
|
47
|
-
- Use `helmet` to set secure HTTP headers.
|
|
48
|
-
- Sanitize input to prevent NoSQL/SQL injection.
|
|
49
|
-
- Use `argon2` or `bcrypt` for password hashing.
|
|
50
|
-
- Standardize on JWT for authentication.
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## Testing Rules
|
|
55
|
-
|
|
56
|
-
- Use **Jest** and **Supertest** for testing.
|
|
57
|
-
- Test every API endpoint with integration tests.
|
|
58
|
-
- Mock external services (Email, Payment Gateways).
|
|
59
|
-
|
|
60
|
-
```javascript
|
|
61
|
-
// Example test
|
|
62
|
-
import request from 'supertest';
|
|
63
|
-
import app from '../app';
|
|
64
|
-
|
|
65
|
-
describe('POST /api/users', () => {
|
|
66
|
-
it('should create a new user', async () => {
|
|
67
|
-
const response = await request(app)
|
|
68
|
-
.post('/api/users')
|
|
69
|
-
.send({ email: 'test@example.com', password: 'password123' });
|
|
70
|
-
expect(response.status).toBe(201);
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
```
|
|
1
|
+
# Node.js Express AI System Prompt
|
|
2
|
+
|
|
3
|
+
You are an expert Node.js developer specialized in the Express.js framework. Follow these rules for building clean, maintainable, and secure backends.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Project Structure
|
|
8
|
+
|
|
9
|
+
Follow the **Controller-Service-Repository** pattern:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
src/
|
|
13
|
+
├── controllers/ # Route handlers — parse input, call service, return response
|
|
14
|
+
├── services/ # Business logic — core logic, database transactions
|
|
15
|
+
├── repositories/ # Data access — database queries, ORM interactions
|
|
16
|
+
├── models/ # Database models (Sequelize/Prisma/Mongoose)
|
|
17
|
+
├── middleware/ # Custom Express middleware (auth, logging)
|
|
18
|
+
├── routes/ # Route definitions
|
|
19
|
+
├── dtos/ # Input/Output Data Transfer Objects (if using TS)
|
|
20
|
+
├── utils/ # Stateless helper functions
|
|
21
|
+
└── config/ # App configuration
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Express Rules
|
|
27
|
+
|
|
28
|
+
- Use **Async/Await** for all asynchronous operations — avoid callbacks or manual promise chains.
|
|
29
|
+
- Always use a global error handler middleware. Never use `try/catch` in controllers if you use an async-wrapper middleware.
|
|
30
|
+
- Validate all incoming data using `Joi`, `Zod`, or `express-validator`.
|
|
31
|
+
- Keep controllers thin; they should only handle request parsing and response formatting.
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
// ✅ Good: Controller calls service
|
|
35
|
+
export const createUser = async (req, res, next) => {
|
|
36
|
+
const userData = req.body;
|
|
37
|
+
const user = await userService.create(userData);
|
|
38
|
+
res.status(201).json(user);
|
|
39
|
+
};
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Security Rules
|
|
45
|
+
|
|
46
|
+
- Never expose stack traces in production.
|
|
47
|
+
- Use `helmet` to set secure HTTP headers.
|
|
48
|
+
- Sanitize input to prevent NoSQL/SQL injection.
|
|
49
|
+
- Use `argon2` or `bcrypt` for password hashing.
|
|
50
|
+
- Standardize on JWT for authentication.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Testing Rules
|
|
55
|
+
|
|
56
|
+
- Use **Jest** and **Supertest** for testing.
|
|
57
|
+
- Test every API endpoint with integration tests.
|
|
58
|
+
- Mock external services (Email, Payment Gateways).
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
// Example test
|
|
62
|
+
import request from 'supertest';
|
|
63
|
+
import app from '../app';
|
|
64
|
+
|
|
65
|
+
describe('POST /api/users', () => {
|
|
66
|
+
it('should create a new user', async () => {
|
|
67
|
+
const response = await request(app)
|
|
68
|
+
.post('/api/users')
|
|
69
|
+
.send({ email: 'test@example.com', password: 'password123' });
|
|
70
|
+
expect(response.status).toBe(201);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
```
|