@relipa/ai-flow-kit 0.2.0 → 0.2.2-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 +4 -4
- package/custom/rules/java/spring-boot-rules.md +209 -0
- package/custom/rules/javascript/nestjs-examples.md +41 -0
- package/custom/rules/javascript/nestjs-rules.md +42 -0
- package/custom/rules/javascript/nodejs-express-examples.md +35 -0
- package/custom/rules/javascript/nodejs-express-rules.md +49 -0
- package/custom/rules/javascript/reactjs-examples.md +380 -0
- package/custom/rules/javascript/reactjs-rules.md +173 -0
- package/custom/rules/php/php-examples.md +161 -0
- package/custom/rules/php/php-rules.md +127 -0
- package/custom/rules/python/python-django-examples.md +34 -0
- package/custom/rules/python/python-django-rules.md +48 -0
- package/custom/rules/python/python-examples.md +32 -0
- package/custom/rules/python/python-fastapi-examples.md +30 -0
- package/custom/rules/python/python-fastapi-rules.md +35 -0
- package/custom/rules/python/python-ml-examples.md +187 -0
- package/custom/rules/python/python-ml-rules.md +121 -0
- package/custom/rules/python/python-rules.md +58 -0
- package/custom/skills/ba-skills/skill-ba-qna-template-v1.md +4 -4
- package/custom/skills/ba-skills/skill-ba-qna-v1.md +6 -0
- package/custom/skills/create-system-requirement/SKILL.md +99 -25
- package/custom/skills/create-system-requirement/system-requirement-template-v1.md +282 -0
- package/custom/skills/execute-flow/SKILL.md +142 -36
- package/custom/skills/execute-flow/templates/evidence-helper.ts +145 -0
- package/custom/skills/execute-flow/templates/playwright.config.ts +28 -8
- package/custom/skills/impact-analysis/SKILL.md +106 -106
- package/custom/skills/read-study-requirement/SKILL.md +1 -2
- package/custom/skills/report-customer/SKILL.md +99 -99
- package/custom/skills/script-sync/SKILL.md +54 -16
- package/custom/templates/nestjs.md +5 -72
- package/custom/templates/nodejs-express.md +5 -73
- package/custom/templates/php-plain.md +5 -261
- package/custom/templates/php.md +5 -261
- package/custom/templates/python-django.md +5 -71
- package/custom/templates/python-fastapi.md +5 -54
- package/custom/templates/python-ml.md +1 -269
- package/custom/templates/python.md +5 -79
- package/custom/templates/reactjs.md +5 -492
- package/custom/templates/shared/gate-workflow.md +18 -11
- package/custom/templates/shared/ml-gate-workflow.md +1 -0
- package/custom/templates/spring-boot.md +5 -224
- package/docs/common/CHANGELOG.md +24 -6
- package/docs/common/INDEX.md +1 -0
- package/docs/common/QUICK_START.md +1 -1
- package/docs/common/System-Requirement-Read-Guide.md +178 -0
- package/docs/common/Testing-Structure.md +31 -25
- package/docs/common/cli-reference.md +12 -10
- package/package.json +1 -1
- package/scripts/init.js +143 -40
- package/scripts/prompt.js +3 -3
- package/scripts/scaffold-playwright.js +2 -0
package/README.md
CHANGED
|
@@ -80,8 +80,8 @@ ak execute PROJ-44 (or ./testcases.md or ak execute)
|
|
|
80
80
|
│
|
|
81
81
|
▼
|
|
82
82
|
⛩️ GATE 1 — Pre-flight & Work Plan [AI + QA]
|
|
83
|
-
Parse TC file → verify
|
|
84
|
-
Check BASE_URL env var + playwright.config.ts
|
|
83
|
+
Parse TC file → verify AK-Docs/03.Testing/ subfolders exist
|
|
84
|
+
Check BASE_URL env var + playwright.config.ts + .gitignore covers 04.Evidence/
|
|
85
85
|
Create execution work plan
|
|
86
86
|
QA reviews → "APPROVED"
|
|
87
87
|
│ APPROVED
|
|
@@ -341,9 +341,9 @@ ak execute
|
|
|
341
341
|
```
|
|
342
342
|
|
|
343
343
|
**What happens (4-gate Execute Flow):**
|
|
344
|
-
1. **Gate 1 — Pre-flight:** Parse TC file, verify `
|
|
344
|
+
1. **Gate 1 — Pre-flight:** Parse TC file, verify `AK-Docs/03.Testing/` subfolders exist, check `BASE_URL`, `playwright.config.ts`, and `.gitignore` covers `04.Evidence/` — QA reviews → `APPROVED`
|
|
345
345
|
2. **Gate 2 — Script Sync:** Hash-based TC↔script sync — gen new, update changed, skip unchanged (never fabricates selectors — uses Playwright MCP)
|
|
346
|
-
3. **Gate 3 — Execute & Evidence:** Run Playwright
|
|
346
|
+
3. **Gate 3 — Execute & Evidence:** Run Playwright from `AK-Docs/03.Testing/05.Scripts/`, evidence lands in `04.Evidence/` (gitignored) per `run-{N}/`, update TC file R1/R2 columns — QA reviews → `APPROVED`
|
|
347
347
|
4. **Gate 4 — Report & Bug Logging:** Generate `testreport.md`, ask per-bug Jira confirmation — QA reviews → `APPROVED`
|
|
348
348
|
|
|
349
349
|
> **Multi-AI:** Works with Claude, Codex, Gemini, Cursor, Copilot — the execute-flow skill is loaded via `ak init`/`ak up`.
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# Spring Boot Rules
|
|
2
|
+
|
|
3
|
+
Full coding rules for this stack. Read this in full before writing or modifying any Java code in this project — not just once, keep applying it to every edit in the session, not only the first.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Architecture
|
|
8
|
+
|
|
9
|
+
Follow strict **Layered Architecture**:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Controller (HTTP layer)
|
|
13
|
+
↓
|
|
14
|
+
Service (Business logic)
|
|
15
|
+
↓
|
|
16
|
+
Repository (Data access - Spring Data JPA)
|
|
17
|
+
↓
|
|
18
|
+
Entity / Domain Model
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Package Structure
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
com.company.project/
|
|
25
|
+
├── controller/ # \@RestController — HTTP endpoints only
|
|
26
|
+
├── service/
|
|
27
|
+
│ ├── impl/ # \@Service — business logic implementation
|
|
28
|
+
│ └── [Interface].java
|
|
29
|
+
├── repository/ # \@Repository — extends JpaRepository
|
|
30
|
+
├── entity/ # \@Entity — JPA entities
|
|
31
|
+
├── dto/
|
|
32
|
+
│ ├── request/ # Input DTOs (e.g. CreateUserRequest)
|
|
33
|
+
│ └── response/ # Output DTOs (e.g. UserResponse)
|
|
34
|
+
├── mapper/ # MapStruct mappers (Entity ↔ DTO)
|
|
35
|
+
├── exception/
|
|
36
|
+
│ ├── GlobalExceptionHandler.java # \@RestControllerAdvice
|
|
37
|
+
│ └── [CustomException].java
|
|
38
|
+
├── config/ # \@Configuration classes
|
|
39
|
+
└── util/ # Pure utility helpers (stateless)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Controller Rules
|
|
45
|
+
|
|
46
|
+
- Annotate with `\@RestController` + `\@RequestMapping`
|
|
47
|
+
- **Only** handle HTTP concerns: parse request, call service, return response
|
|
48
|
+
- Never put business logic in Controller
|
|
49
|
+
- Always use DTOs — never expose Entity directly
|
|
50
|
+
- Use `ResponseEntity<T>` for explicit HTTP status control
|
|
51
|
+
- Validate input with `\@Valid` + Bean Validation annotations
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Service Rules
|
|
56
|
+
|
|
57
|
+
- Always define an **interface**, implement in the `impl/` package
|
|
58
|
+
- Annotate implementation with `\@Service`
|
|
59
|
+
- All business logic lives here
|
|
60
|
+
- Use `\@Transactional` at the method level (not class level)
|
|
61
|
+
- Throw specific custom exceptions, not generic `RuntimeException`
|
|
62
|
+
- Never return an Entity — always convert to DTO via Mapper
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Repository Rules
|
|
67
|
+
|
|
68
|
+
- Extend `JpaRepository<Entity, ID>`
|
|
69
|
+
- Use **method name queries** for simple queries
|
|
70
|
+
- Use `\@Query` (JPQL) for complex queries — avoid native SQL unless necessary
|
|
71
|
+
- Never add business logic here
|
|
72
|
+
- Use `\@EntityGraph` to solve N+1 problems
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Entity Rules
|
|
77
|
+
|
|
78
|
+
- Use Lombok: `\@Getter`, `\@Setter`, `\@NoArgsConstructor`, `\@AllArgsConstructor`, `\@Builder`
|
|
79
|
+
- Avoid `\@Data` on entities (causes issues with `equals/hashCode` + lazy loading)
|
|
80
|
+
- Always use `\@Table(name = "snake_case_table_name")`
|
|
81
|
+
- Use `\@Column(name = "snake_case_column_name")` explicitly
|
|
82
|
+
- For soft delete: add `deleted` boolean + `deletedAt` timestamp
|
|
83
|
+
- Extend `BaseEntity` for audit fields (`createdAt`, `updatedAt`)
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## DTO Rules
|
|
88
|
+
|
|
89
|
+
- Use separate DTOs for **Request** and **Response** — never share
|
|
90
|
+
- Use Lombok: `\@Getter`, `\@Builder`, `\@AllArgsConstructor`, `\@NoArgsConstructor`
|
|
91
|
+
- Validate in the Request DTO with Bean Validation (`\@NotBlank`, `\@Email`, `\@NotNull`, `\@Size`)
|
|
92
|
+
- Never expose internal fields (password hash, audit timestamps) in the Response DTO
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## MapStruct Mapper Rules
|
|
97
|
+
|
|
98
|
+
- Use `\@Mapper(componentModel = "spring")` — inject as a Spring bean
|
|
99
|
+
- Define explicit mappings with `\@Mapping` when field names differ
|
|
100
|
+
- Never do manual mapping (`new DTO(); dto.setField(entity.getField())`)
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Exception Handling
|
|
105
|
+
|
|
106
|
+
- Create custom exceptions extending `RuntimeException`
|
|
107
|
+
- Handle all exceptions in one `\@RestControllerAdvice` class
|
|
108
|
+
- Return a consistent error response format
|
|
109
|
+
- Never expose stack traces to the client
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Testing Rules
|
|
114
|
+
|
|
115
|
+
### Unit Tests (Service layer)
|
|
116
|
+
- Test class: `[ServiceImpl]Test.java`
|
|
117
|
+
- Mock all dependencies with `\@ExtendWith(MockitoExtension.class)` + `\@Mock`
|
|
118
|
+
- Test happy path + edge cases + exception scenarios
|
|
119
|
+
- Use AssertJ: `assertThat(result).isEqualTo(expected)`
|
|
120
|
+
|
|
121
|
+
### Integration Tests (Controller layer)
|
|
122
|
+
- Use `\@SpringBootTest` + `\@AutoConfigureMockMvc`
|
|
123
|
+
- Test full HTTP flow with `MockMvc`
|
|
124
|
+
- Use `\@Sql` or Testcontainers for database state
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Naming Conventions
|
|
129
|
+
|
|
130
|
+
| Element | Convention | Example |
|
|
131
|
+
|---------|-----------|---------|
|
|
132
|
+
| Class | PascalCase | `UserService`, `OrderController` |
|
|
133
|
+
| Method | camelCase | `findById`, `createOrder` |
|
|
134
|
+
| Variable | camelCase | `userResponse`, `orderId` |
|
|
135
|
+
| Constant | UPPER_SNAKE_CASE | `MAX_RETRY_COUNT` |
|
|
136
|
+
| Package | lowercase | `com.company.project.service` |
|
|
137
|
+
| DB Table | snake_case | `user_orders`, `product_items` |
|
|
138
|
+
| DB Column | snake_case | `created_at`, `user_id` |
|
|
139
|
+
| REST endpoint | kebab-case | `/api/v1/user-profiles` |
|
|
140
|
+
| Request DTO | `[Action][Resource]Request` | `CreateOrderRequest` |
|
|
141
|
+
| Response DTO | `[Resource]Response` | `OrderResponse` |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## API Design
|
|
146
|
+
|
|
147
|
+
- Version all APIs: `/api/v1/...`
|
|
148
|
+
- Use plural nouns for resources: `/users`, `/orders`
|
|
149
|
+
- HTTP methods: `GET` (read), `POST` (create), `PUT` (full update), `PATCH` (partial), `DELETE`
|
|
150
|
+
- Return `201 Created` for POST, `200 OK` for GET/PUT/PATCH, `204 No Content` for DELETE
|
|
151
|
+
- Use consistent pagination: `?page=0&size=20&sort=createdAt,desc`
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
GET /api/v1/users → 200 list
|
|
155
|
+
POST /api/v1/users → 201 created
|
|
156
|
+
GET /api/v1/users/{id} → 200 or 404
|
|
157
|
+
PUT /api/v1/users/{id} → 200 or 404
|
|
158
|
+
DELETE /api/v1/users/{id} → 204 or 404
|
|
159
|
+
GET /api/v1/users/{id}/orders → 200 nested resource
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Performance Rules
|
|
165
|
+
|
|
166
|
+
- Always use pagination — never return unbounded lists
|
|
167
|
+
- Avoid N+1: use `\@EntityGraph` or `JOIN FETCH` in JPQL
|
|
168
|
+
- Add database indexes on frequently queried columns
|
|
169
|
+
- Use `\@Transactional(readOnly = true)` on read-only service methods
|
|
170
|
+
- For heavy read operations, consider projection interfaces
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Security Rules
|
|
175
|
+
|
|
176
|
+
- Never log passwords, tokens, or sensitive PII
|
|
177
|
+
- Hash passwords with BCrypt: `passwordEncoder.encode(rawPassword)`
|
|
178
|
+
- Validate and sanitize all user inputs via Bean Validation
|
|
179
|
+
- Use `\@PreAuthorize` for method-level security
|
|
180
|
+
- Never return stack traces to API consumers
|
|
181
|
+
- Store secrets in environment variables / Vault — never in code
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Logging Rules
|
|
186
|
+
|
|
187
|
+
- Use SLF4J with Lombok `\@Slf4j`
|
|
188
|
+
- `log.info` — normal business events
|
|
189
|
+
- `log.warn` — recoverable issues (not found, validation fail)
|
|
190
|
+
- `log.error` — unexpected exceptions (always include `ex` as the second argument)
|
|
191
|
+
- Never log sensitive data (password, credit card, token)
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Common Anti-Patterns to Avoid
|
|
196
|
+
|
|
197
|
+
- ❌ `\@Autowired` field injection → use constructor injection (Lombok `\@RequiredArgsConstructor`)
|
|
198
|
+
- ❌ `\@Data` on JPA entities → use `\@Getter \@Setter` separately
|
|
199
|
+
- ❌ Returning `Entity` directly from Controller → always use DTO
|
|
200
|
+
- ❌ `SELECT *` or unbounded `findAll()` → always paginate
|
|
201
|
+
- ❌ Business logic in Controller → move to Service
|
|
202
|
+
- ❌ Catching and swallowing exceptions → handle properly or rethrow
|
|
203
|
+
- ❌ `new RuntimeException("something")` → create a specific custom exception
|
|
204
|
+
- ❌ Hardcoding config values → use `\@Value` or `\@ConfigurationProperties`
|
|
205
|
+
- ❌ `\@Transactional` on Controller → only on Service methods
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
When explaining changes, refer to the [Spring Boot Official Documentation](https://docs.spring.io/spring-boot/docs/current/reference/html/) and [Spring Data JPA](https://docs.spring.io/spring-data/jpa/docs/current/reference/html/) conventions.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# NestJS Code Examples
|
|
2
|
+
|
|
3
|
+
Reference examples for each rule area. Read the relevant section when generating code for that area.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## NestJS Rules
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// ✅ Good: DTO with validation
|
|
11
|
+
export class CreateUserDto {
|
|
12
|
+
@IsEmail()
|
|
13
|
+
email: string;
|
|
14
|
+
|
|
15
|
+
@IsString()
|
|
16
|
+
@MinLength(8)
|
|
17
|
+
password: string;
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Testing
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
describe('UsersService', () => {
|
|
27
|
+
let service: UsersService;
|
|
28
|
+
|
|
29
|
+
beforeEach(async () => {
|
|
30
|
+
const module: TestingModule = await Test.createTestingModule({
|
|
31
|
+
providers: [UsersService],
|
|
32
|
+
}).compile();
|
|
33
|
+
|
|
34
|
+
service = module.get<UsersService>(UsersService);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should be defined', () => {
|
|
38
|
+
expect(service).toBeDefined();
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# NestJS Rules
|
|
2
|
+
|
|
3
|
+
Full coding rules for this stack. Read this in full before writing or modifying any NestJS code in this project — not just once, keep applying it to every edit in the session, not only the first.
|
|
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
|
+
---
|
|
38
|
+
|
|
39
|
+
## Testing Rules
|
|
40
|
+
|
|
41
|
+
- Use the built-in **Jest** testing suite.
|
|
42
|
+
- Use `Test.createTestingModule` to create isolated environments for unit tests.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Node.js Express Code Examples
|
|
2
|
+
|
|
3
|
+
Reference examples for each rule area. Read the relevant section when generating code for that area.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Express Rules
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
// ✅ Good: Controller calls service
|
|
11
|
+
export const createUser = async (req, res, next) => {
|
|
12
|
+
const userData = req.body;
|
|
13
|
+
const user = await userService.create(userData);
|
|
14
|
+
res.status(201).json(user);
|
|
15
|
+
};
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Testing
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
// Example test
|
|
24
|
+
import request from 'supertest';
|
|
25
|
+
import app from '../app';
|
|
26
|
+
|
|
27
|
+
describe('POST /api/users', () => {
|
|
28
|
+
it('should create a new user', async () => {
|
|
29
|
+
const response = await request(app)
|
|
30
|
+
.post('/api/users')
|
|
31
|
+
.send({ email: 'test@example.com', password: 'password123' });
|
|
32
|
+
expect(response.status).toBe(201);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
```
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Node.js Express Rules
|
|
2
|
+
|
|
3
|
+
Full coding rules for this stack. Read this in full before writing or modifying any Express code in this project — not just once, keep applying it to every edit in the session, not only the first.
|
|
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
|
+
---
|
|
34
|
+
|
|
35
|
+
## Security Rules
|
|
36
|
+
|
|
37
|
+
- Never expose stack traces in production.
|
|
38
|
+
- Use `helmet` to set secure HTTP headers.
|
|
39
|
+
- Sanitize input to prevent NoSQL/SQL injection.
|
|
40
|
+
- Use `argon2` or `bcrypt` for password hashing.
|
|
41
|
+
- Standardize on JWT for authentication.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Testing Rules
|
|
46
|
+
|
|
47
|
+
- Use **Jest** and **Supertest** for testing.
|
|
48
|
+
- Test every API endpoint with integration tests.
|
|
49
|
+
- Mock external services (Email, Payment Gateways).
|