@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.
Files changed (39) hide show
  1. package/README.md +10 -4
  2. package/bin/aiflow.js +77 -7
  3. package/custom/templates/laravel.md +15 -15
  4. package/custom/templates/nestjs.md +72 -72
  5. package/custom/templates/nextjs.md +14 -14
  6. package/custom/templates/nodejs-express.md +73 -73
  7. package/custom/templates/python-django.md +71 -71
  8. package/custom/templates/python-fastapi.md +54 -54
  9. package/custom/templates/reactjs.md +492 -492
  10. package/custom/templates/shared/gate-workflow.md +88 -75
  11. package/custom/templates/spring-boot.md +523 -523
  12. package/custom/templates/tools/claude.md +13 -0
  13. package/custom/templates/tools/copilot.md +12 -8
  14. package/custom/templates/tools/cursor.md +12 -8
  15. package/custom/templates/tools/gemini.md +12 -8
  16. package/custom/templates/tools/generic.md +17 -12
  17. package/custom/templates/vue-nuxt.md +14 -14
  18. package/{AIFLOW.md → docs/AIFLOW.md} +5 -0
  19. package/{CHANGELOG.md → docs/CHANGELOG.md} +41 -5
  20. package/{IMPLEMENTATION_SUMMARY.md → docs/IMPLEMENTATION_SUMMARY.md} +21 -39
  21. package/{QUICK_START.md → docs/QUICK_START.md} +8 -8
  22. package/docs/ai-integration.md +53 -53
  23. package/docs/architecture.md +4 -5
  24. package/docs/cli-reference.md +97 -27
  25. package/docs/developer-overview.md +126 -126
  26. package/docs/troubleshooting.md +15 -0
  27. package/package.json +6 -11
  28. package/scripts/guide.js +16 -0
  29. package/scripts/hooks/session-start.js +5 -1
  30. package/scripts/init.js +518 -460
  31. package/scripts/telemetry/cli.js +249 -0
  32. package/scripts/telemetry/config.js +94 -0
  33. package/scripts/telemetry/crypto.js +20 -0
  34. package/scripts/telemetry/flush.js +159 -0
  35. package/scripts/telemetry/record.js +138 -0
  36. package/scripts/use.js +594 -594
  37. package/upstream/skills/using-superpowers/SKILL.md +14 -0
  38. package/CONTRIBUTING.md +0 -388
  39. 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 CLAUDE.md templates
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
+ ```