@lenne.tech/cli 1.0.0 → 1.0.1
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/build/commands/claude/install-commands.js +332 -0
- package/build/commands/claude/install-skills.js +5 -1
- package/build/commands/server/add-property.js +22 -41
- package/build/extensions/server.js +142 -46
- package/build/templates/claude-commands/code-cleanup.md +82 -0
- package/build/templates/claude-commands/mr-description-clipboard.md +48 -0
- package/build/templates/claude-commands/mr-description.md +33 -0
- package/build/templates/claude-commands/sec-review.md +62 -0
- package/build/templates/claude-commands/skill-optimize.md +140 -0
- package/build/templates/claude-commands/test-generate.md +45 -0
- package/build/templates/claude-skills/nest-server-generator/SKILL.md +372 -1314
- package/build/templates/claude-skills/nest-server-generator/configuration.md +279 -0
- package/build/templates/claude-skills/nest-server-generator/declare-keyword-warning.md +124 -0
- package/build/templates/claude-skills/nest-server-generator/description-management.md +217 -0
- package/build/templates/claude-skills/nest-server-generator/examples.md +131 -5
- package/build/templates/claude-skills/nest-server-generator/quality-review.md +855 -0
- package/build/templates/claude-skills/nest-server-generator/reference.md +67 -13
- package/build/templates/claude-skills/nest-server-generator/security-rules.md +358 -0
- package/build/templates/claude-skills/story-tdd/SKILL.md +1173 -0
- package/build/templates/claude-skills/story-tdd/code-quality.md +266 -0
- package/build/templates/claude-skills/story-tdd/database-indexes.md +173 -0
- package/build/templates/claude-skills/story-tdd/examples.md +1332 -0
- package/build/templates/claude-skills/story-tdd/reference.md +1180 -0
- package/build/templates/claude-skills/story-tdd/security-review.md +299 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: nest-server-generator-reference
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.1
|
|
4
4
|
description: Quick reference for ALL NestJS server development - from simple single commands to complex structure generation
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -63,7 +63,13 @@ Use this skill for **ANY** NestJS/nest-server work, no matter how simple or comp
|
|
|
63
63
|
☐ 4. Create all Objects
|
|
64
64
|
☐ 5. Create all Modules (dependency order)
|
|
65
65
|
☐ 6. Handle inheritance (manual edits)
|
|
66
|
-
☐ 7. Update
|
|
66
|
+
☐ 7. Update ALL descriptions EVERYWHERE (CRITICAL!)
|
|
67
|
+
☐ 7.1. Extract ALL user comments (after //) from specification
|
|
68
|
+
☐ 7.2. Format descriptions: ENGLISH (DEUTSCH)
|
|
69
|
+
☐ 7.3. Apply to ALL Module files (Model, CreateInput, UpdateInput)
|
|
70
|
+
☐ 7.4. Apply to ALL SubObject files (Object, CreateInput, UpdateInput)
|
|
71
|
+
☐ 7.5. Add to ALL class decorators (@ObjectType, @InputType)
|
|
72
|
+
☐ 7.6. Verify consistency (same property = same description)
|
|
67
73
|
☐ 8. Alphabetize all properties
|
|
68
74
|
☐ 9. Create enum files
|
|
69
75
|
☐ 10. Create API tests
|
|
@@ -140,20 +146,57 @@ lt server addProp --type Module --element <Name> \
|
|
|
140
146
|
|
|
141
147
|
## Description Format
|
|
142
148
|
|
|
149
|
+
**⚠️ CRITICAL:** Always extract descriptions from user comments (after `//`) and apply EVERYWHERE!
|
|
150
|
+
|
|
143
151
|
**Rule**: `"ENGLISH_DESCRIPTION (DEUTSCHE_BESCHREIBUNG)"`
|
|
144
152
|
|
|
145
153
|
### Processing
|
|
146
154
|
|
|
147
|
-
| Input Comment | Output Description |
|
|
148
|
-
|
|
149
|
-
| `//
|
|
150
|
-
| `//
|
|
151
|
-
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
-
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
| Input Comment | Language | Output Description |
|
|
156
|
+
|---------------|----------|-------------------|
|
|
157
|
+
| `// Product name` | English | `'Product name'` |
|
|
158
|
+
| `// Produktname` | German | `'Product name (Produktname)'` |
|
|
159
|
+
| `// Street name` | English | `'Street name'` |
|
|
160
|
+
| `// Straße` | German | `'Street (Straße)'` |
|
|
161
|
+
| `// Postleizahl` (typo) | German | `'Postal code (Postleitzahl)'` (corrected) |
|
|
162
|
+
| (no comment) | - | Create meaningful English description |
|
|
163
|
+
|
|
164
|
+
**⚠️ Preserve Original Wording:**
|
|
165
|
+
- ✅ Fix typos: `Postleizahl` → `Postleitzahl`, `Starße` → `Straße`
|
|
166
|
+
- ❌ DON'T rephrase: `Straße` → `Straßenname` (NO!)
|
|
167
|
+
- ❌ DON'T expand: `Produkt` → `Produktbezeichnung` (NO!)
|
|
168
|
+
- **Reason:** User comments may be predefined terms referenced by external systems
|
|
169
|
+
|
|
170
|
+
### Apply To ALL Files
|
|
171
|
+
|
|
172
|
+
**For EVERY Module property** (3 files):
|
|
173
|
+
1. `<module>.model.ts` → Property `@UnifiedField({ description: '...' })`
|
|
174
|
+
2. `inputs/<module>-create.input.ts` → Property `@UnifiedField({ description: '...' })`
|
|
175
|
+
3. `inputs/<module>.input.ts` → Property `@UnifiedField({ description: '...' })`
|
|
176
|
+
|
|
177
|
+
**For EVERY SubObject property** (3 files):
|
|
178
|
+
1. `objects/<object>/<object>.object.ts` → Property `@UnifiedField({ description: '...' })`
|
|
179
|
+
2. `objects/<object>/<object>-create.input.ts` → Property `@UnifiedField({ description: '...' })`
|
|
180
|
+
3. `objects/<object>/<object>.input.ts` → Property `@UnifiedField({ description: '...' })`
|
|
181
|
+
|
|
182
|
+
**For class decorators**:
|
|
183
|
+
- `@ObjectType({ description: '...' })` on Models and Objects
|
|
184
|
+
- `@InputType({ description: '...' })` on all Input classes
|
|
185
|
+
|
|
186
|
+
### Common Mistakes
|
|
187
|
+
|
|
188
|
+
❌ **WRONG:** Descriptions only in Model, missing in Inputs
|
|
189
|
+
❌ **WRONG:** German-only descriptions without English translation
|
|
190
|
+
❌ **WRONG:** Inconsistent descriptions (different in Model vs Input)
|
|
191
|
+
❌ **WRONG:** Ignoring user-provided comments from specification
|
|
192
|
+
❌ **WRONG:** Changing wording: `Straße` → `Straßenname` (rephrased!)
|
|
193
|
+
❌ **WRONG:** Expanding terms: `Produkt` → `Produktbezeichnung` (added word!)
|
|
194
|
+
|
|
195
|
+
✅ **CORRECT:** Same description in ALL 3 files (Model, CreateInput, UpdateInput)
|
|
196
|
+
✅ **CORRECT:** Format `ENGLISH (DEUTSCH)` for German comments
|
|
197
|
+
✅ **CORRECT:** All user comments extracted and applied
|
|
198
|
+
✅ **CORRECT:** Fix typos only, preserve original wording: `Postleizahl` → `Postleitzahl`
|
|
199
|
+
✅ **CORRECT:** Keep exact terms: `Straße` → `Street (Straße)` (not "Street name"!)
|
|
157
200
|
|
|
158
201
|
## Inheritance Handling
|
|
159
202
|
|
|
@@ -326,7 +369,18 @@ Final checks before completing:
|
|
|
326
369
|
☐ All Objects created
|
|
327
370
|
☐ All Modules created
|
|
328
371
|
☐ Properties in alphabetical order
|
|
329
|
-
☐
|
|
372
|
+
☐ DESCRIPTIONS - CRITICAL (check ALL):
|
|
373
|
+
☐ User comments extracted from specification
|
|
374
|
+
☐ German descriptions → ENGLISH (DEUTSCH) format
|
|
375
|
+
☐ English descriptions → kept as-is
|
|
376
|
+
☐ Module Models have descriptions
|
|
377
|
+
☐ Module CreateInputs have SAME descriptions
|
|
378
|
+
☐ Module UpdateInputs have SAME descriptions
|
|
379
|
+
☐ SubObjects have descriptions
|
|
380
|
+
☐ SubObject CreateInputs have SAME descriptions
|
|
381
|
+
☐ SubObject UpdateInputs have SAME descriptions
|
|
382
|
+
☐ @ObjectType/@InputType decorators have descriptions
|
|
383
|
+
☐ NO inconsistencies between files
|
|
330
384
|
☐ Inheritance correctly implemented
|
|
331
385
|
☐ CreateInputs have all required fields (parent + model)
|
|
332
386
|
☐ Enum files created in src/server/common/enums/
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nest-server-generator-security-rules
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: Critical security and test coverage rules for NestJS development
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 🚨 CRITICAL SECURITY RULES
|
|
8
|
+
|
|
9
|
+
**Before you start ANY work, understand these NON-NEGOTIABLE rules.**
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## ⛔ NEVER Do This
|
|
14
|
+
|
|
15
|
+
1. **NEVER remove or weaken `@Restricted()` decorators** to make tests pass
|
|
16
|
+
2. **NEVER change `@Roles()` decorators** to more permissive roles for test convenience
|
|
17
|
+
3. **NEVER modify `securityCheck()` logic** to bypass security in tests
|
|
18
|
+
4. **NEVER remove class-level `@Restricted(RoleEnum.ADMIN)`** - it's a security fallback
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## ✅ ALWAYS Do This
|
|
23
|
+
|
|
24
|
+
1. **ALWAYS analyze permissions BEFORE writing tests** (Controller, Model, Service layers)
|
|
25
|
+
2. **ALWAYS test with the LEAST privileged user** who is authorized
|
|
26
|
+
3. **ALWAYS create appropriate test users** for each permission level
|
|
27
|
+
4. **ALWAYS adapt tests to security requirements**, never the other way around
|
|
28
|
+
5. **ALWAYS ask developer for approval** before changing ANY security decorator
|
|
29
|
+
6. **ALWAYS aim for maximum test coverage** (80-100% depending on criticality)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 🔑 Permission Hierarchy (Specific Overrides General)
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
@Restricted(RoleEnum.ADMIN) // ← FALLBACK: DO NOT REMOVE
|
|
37
|
+
export class ProductController {
|
|
38
|
+
@Roles(RoleEnum.S_USER) // ← SPECIFIC: This method is more open
|
|
39
|
+
async createProduct() { } // ← S_USER can access (specific wins)
|
|
40
|
+
|
|
41
|
+
async secretMethod() { } // ← ADMIN only (fallback applies)
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Why class-level `@Restricted(ADMIN)` MUST stay:**
|
|
46
|
+
- If someone forgets `@Roles()` on a new method → it's secure by default
|
|
47
|
+
- Shows the class is security-sensitive
|
|
48
|
+
- Fail-safe protection
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Rule 1: NEVER Weaken Security for Test Convenience
|
|
53
|
+
|
|
54
|
+
### ❌ ABSOLUTELY FORBIDDEN
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// BEFORE (secure):
|
|
58
|
+
@Restricted(RoleEnum.ADMIN)
|
|
59
|
+
export class ProductController {
|
|
60
|
+
@Roles(RoleEnum.S_USER)
|
|
61
|
+
async createProduct() { ... }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// AFTER (FORBIDDEN - security weakened!):
|
|
65
|
+
// @Restricted(RoleEnum.ADMIN) ← NEVER remove this!
|
|
66
|
+
export class ProductController {
|
|
67
|
+
@Roles(RoleEnum.S_USER)
|
|
68
|
+
async createProduct() { ... }
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 🚨 CRITICAL RULE
|
|
73
|
+
|
|
74
|
+
- **NEVER remove or weaken `@Restricted()` decorators** on Controllers, Resolvers, Models, or Objects
|
|
75
|
+
- **NEVER change `@Roles()` decorators** to more permissive roles just to make tests pass
|
|
76
|
+
- **NEVER modify `securityCheck()` logic** to bypass security for testing
|
|
77
|
+
|
|
78
|
+
### If tests fail due to permissions
|
|
79
|
+
|
|
80
|
+
1. ✅ **CORRECT**: Adjust the test to use the appropriate user/token
|
|
81
|
+
2. ✅ **CORRECT**: Create test users with the required roles
|
|
82
|
+
3. ❌ **WRONG**: Weaken security to make tests pass
|
|
83
|
+
|
|
84
|
+
### Any security changes MUST
|
|
85
|
+
|
|
86
|
+
- Be discussed with the developer FIRST
|
|
87
|
+
- Have a solid business justification
|
|
88
|
+
- Be explicitly approved by the developer
|
|
89
|
+
- Be documented with the reason
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Rule 2: Understanding Permission Hierarchy
|
|
94
|
+
|
|
95
|
+
### ⭐ Key Concept: Specific Overrides General
|
|
96
|
+
|
|
97
|
+
The `@Restricted()` decorator on a class acts as a **security fallback** - if a method/property doesn't specify permissions, it inherits the class-level restriction. This is a **security-by-default** pattern.
|
|
98
|
+
|
|
99
|
+
### Example - Controller/Resolver
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
@Restricted(RoleEnum.ADMIN) // ← FALLBACK: Protects everything by default
|
|
103
|
+
export class ProductController {
|
|
104
|
+
|
|
105
|
+
@Roles(RoleEnum.S_EVERYONE) // ← SPECIFIC: This method is MORE open
|
|
106
|
+
async getPublicProducts() {
|
|
107
|
+
// Anyone can access this (specific @Roles wins)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@Roles(RoleEnum.S_USER) // ← SPECIFIC: Logged-in users
|
|
111
|
+
async createProduct() {
|
|
112
|
+
// S_USER can access (specific wins over fallback)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async deleteProduct() {
|
|
116
|
+
// ADMIN ONLY (no specific decorator, fallback applies)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Example - Model
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
@Restricted(RoleEnum.ADMIN) // ← FALLBACK
|
|
125
|
+
export class Product {
|
|
126
|
+
|
|
127
|
+
@Roles(RoleEnum.S_EVERYONE) // ← SPECIFIC
|
|
128
|
+
@UnifiedField({ description: 'Product name' })
|
|
129
|
+
name: string; // Everyone can read this
|
|
130
|
+
|
|
131
|
+
@UnifiedField({ description: 'Internal cost' })
|
|
132
|
+
cost: number; // ADMIN ONLY (fallback applies)
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Rule 3: Adapt Tests to Security, Not Vice Versa
|
|
139
|
+
|
|
140
|
+
### ❌ WRONG Approach
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
// Test fails because user isn't admin
|
|
144
|
+
it('should create product', async () => {
|
|
145
|
+
const result = await request(app)
|
|
146
|
+
.post('/products')
|
|
147
|
+
.set('Authorization', regularUserToken) // Not an admin!
|
|
148
|
+
.send(productData);
|
|
149
|
+
|
|
150
|
+
expect(result.status).toBe(201); // Fails with 403
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// ❌ WRONG FIX: Removing @Restricted from controller
|
|
154
|
+
// @Restricted(RoleEnum.ADMIN) ← NEVER DO THIS!
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### ✅ CORRECT Approach
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// Analyze first: Who is allowed to create products?
|
|
161
|
+
// Answer: ADMIN only (based on @Restricted on controller)
|
|
162
|
+
|
|
163
|
+
// Create admin test user
|
|
164
|
+
let adminToken: string;
|
|
165
|
+
|
|
166
|
+
beforeAll(async () => {
|
|
167
|
+
const admin = await createTestUser({ roles: [RoleEnum.ADMIN] });
|
|
168
|
+
adminToken = admin.token;
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('should create product as admin', async () => {
|
|
172
|
+
const result = await request(app)
|
|
173
|
+
.post('/products')
|
|
174
|
+
.set('Authorization', adminToken) // ✅ Use admin token
|
|
175
|
+
.send(productData);
|
|
176
|
+
|
|
177
|
+
expect(result.status).toBe(201); // ✅ Passes
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should reject product creation for regular user', async () => {
|
|
181
|
+
const result = await request(app)
|
|
182
|
+
.post('/products')
|
|
183
|
+
.set('Authorization', regularUserToken)
|
|
184
|
+
.send(productData);
|
|
185
|
+
|
|
186
|
+
expect(result.status).toBe(403); // ✅ Test security works!
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Rule 4: Test with Least Privileged User
|
|
193
|
+
|
|
194
|
+
**Always test with the LEAST privileged user who is authorized to perform the action.**
|
|
195
|
+
|
|
196
|
+
### ❌ WRONG
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
// Method allows S_USER, but testing with ADMIN
|
|
200
|
+
@Roles(RoleEnum.S_USER)
|
|
201
|
+
async getProducts() { }
|
|
202
|
+
|
|
203
|
+
it('should get products', async () => {
|
|
204
|
+
const result = await request(app)
|
|
205
|
+
.get('/products')
|
|
206
|
+
.set('Authorization', adminToken); // ❌ Over-privileged!
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### ✅ CORRECT
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
@Roles(RoleEnum.S_USER)
|
|
214
|
+
async getProducts() { }
|
|
215
|
+
|
|
216
|
+
it('should get products as regular user', async () => {
|
|
217
|
+
const result = await request(app)
|
|
218
|
+
.get('/products')
|
|
219
|
+
.set('Authorization', regularUserToken); // ✅ Least privilege
|
|
220
|
+
});
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**Why this matters:**
|
|
224
|
+
- Tests might pass with ADMIN but fail with S_USER
|
|
225
|
+
- You won't catch permission bugs
|
|
226
|
+
- False confidence in security
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Rule 5: Create Appropriate Test Users
|
|
231
|
+
|
|
232
|
+
**Create test users for EACH permission level you need to test.**
|
|
233
|
+
|
|
234
|
+
### Example Test Setup
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
describe('ProductController', () => {
|
|
238
|
+
let adminToken: string;
|
|
239
|
+
let userToken: string;
|
|
240
|
+
let everyoneToken: string;
|
|
241
|
+
|
|
242
|
+
beforeAll(async () => {
|
|
243
|
+
// Create admin user
|
|
244
|
+
const admin = await createTestUser({
|
|
245
|
+
roles: [RoleEnum.ADMIN]
|
|
246
|
+
});
|
|
247
|
+
adminToken = admin.token;
|
|
248
|
+
|
|
249
|
+
// Create regular user
|
|
250
|
+
const user = await createTestUser({
|
|
251
|
+
roles: [RoleEnum.S_USER]
|
|
252
|
+
});
|
|
253
|
+
userToken = user.token;
|
|
254
|
+
|
|
255
|
+
// Create unauthenticated scenario
|
|
256
|
+
const guest = await createTestUser({
|
|
257
|
+
roles: [RoleEnum.S_EVERYONE]
|
|
258
|
+
});
|
|
259
|
+
everyoneToken = guest.token;
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it('admin can delete products', async () => {
|
|
263
|
+
// Use adminToken
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it('regular user can create products', async () => {
|
|
267
|
+
// Use userToken
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it('everyone can view products', async () => {
|
|
271
|
+
// Use everyoneToken or no token
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it('regular user cannot delete products', async () => {
|
|
275
|
+
// Use userToken, expect 403
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Rule 6: Comprehensive Test Coverage
|
|
283
|
+
|
|
284
|
+
**Aim for 80-100% test coverage depending on criticality:**
|
|
285
|
+
|
|
286
|
+
- **High criticality** (payments, user data, admin functions): 95-100%
|
|
287
|
+
- **Medium criticality** (business logic, CRUD): 80-90%
|
|
288
|
+
- **Low criticality** (utilities, formatters): 70-80%
|
|
289
|
+
|
|
290
|
+
### What to Test
|
|
291
|
+
|
|
292
|
+
**For each endpoint/method:**
|
|
293
|
+
|
|
294
|
+
1. ✅ Happy path (authorized user, valid data)
|
|
295
|
+
2. ✅ Permission denied (unauthorized user)
|
|
296
|
+
3. ✅ Validation errors (invalid input)
|
|
297
|
+
4. ✅ Edge cases (empty data, boundaries)
|
|
298
|
+
5. ✅ Error handling (server errors, missing resources)
|
|
299
|
+
|
|
300
|
+
### Example Comprehensive Tests
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
describe('createProduct', () => {
|
|
304
|
+
it('should create product with admin user', async () => {
|
|
305
|
+
// Happy path
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
it('should reject creation by regular user', async () => {
|
|
309
|
+
// Permission test
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
it('should reject invalid product data', async () => {
|
|
313
|
+
// Validation test
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
it('should reject duplicate product name', async () => {
|
|
317
|
+
// Business rule test
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it('should handle missing required fields', async () => {
|
|
321
|
+
// Edge case
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Quick Security Checklist
|
|
329
|
+
|
|
330
|
+
Before completing ANY task:
|
|
331
|
+
|
|
332
|
+
- [ ] **All @Restricted decorators preserved**
|
|
333
|
+
- [ ] **@Roles decorators NOT made more permissive**
|
|
334
|
+
- [ ] **Tests use appropriate user roles**
|
|
335
|
+
- [ ] **Test users created for each permission level**
|
|
336
|
+
- [ ] **Least privileged user tested**
|
|
337
|
+
- [ ] **Permission denial tested (403 responses)**
|
|
338
|
+
- [ ] **No securityCheck() logic bypassed**
|
|
339
|
+
- [ ] **Test coverage ≥ 80%**
|
|
340
|
+
- [ ] **All edge cases covered**
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Security Decision Protocol
|
|
345
|
+
|
|
346
|
+
**When you encounter a security-related decision:**
|
|
347
|
+
|
|
348
|
+
1. **STOP** - Don't make the change immediately
|
|
349
|
+
2. **ANALYZE** - Why does the current security exist?
|
|
350
|
+
3. **ASK** - Consult the developer before changing
|
|
351
|
+
4. **DOCUMENT** - If approved, document the reason
|
|
352
|
+
5. **TEST** - Ensure security still works after change
|
|
353
|
+
|
|
354
|
+
**Remember:**
|
|
355
|
+
- **Security > Convenience**
|
|
356
|
+
- **Better to over-restrict than under-restrict**
|
|
357
|
+
- **Always preserve existing security mechanisms**
|
|
358
|
+
- **When in doubt, ask the developer**
|