@lenne.tech/cli 1.0.1 → 1.1.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 (32) hide show
  1. package/build/commands/claude/install-commands.js +10 -5
  2. package/build/commands/claude/install-mcps.js +258 -0
  3. package/build/commands/claude/install-skills.js +90 -23
  4. package/build/lib/mcp-registry.js +80 -0
  5. package/build/templates/claude-commands/commit-message.md +21 -0
  6. package/build/templates/claude-commands/create-story.md +407 -0
  7. package/build/templates/claude-commands/skill-optimize.md +431 -90
  8. package/build/templates/claude-skills/building-stories-with-tdd/SKILL.md +265 -0
  9. package/build/templates/claude-skills/{story-tdd → building-stories-with-tdd}/code-quality.md +10 -0
  10. package/build/templates/claude-skills/{story-tdd → building-stories-with-tdd}/database-indexes.md +9 -0
  11. package/build/templates/claude-skills/{story-tdd → building-stories-with-tdd}/examples.md +115 -64
  12. package/build/templates/claude-skills/building-stories-with-tdd/handling-existing-tests.md +197 -0
  13. package/build/templates/claude-skills/{story-tdd → building-stories-with-tdd}/reference.md +276 -29
  14. package/build/templates/claude-skills/{story-tdd → building-stories-with-tdd}/security-review.md +8 -0
  15. package/build/templates/claude-skills/building-stories-with-tdd/workflow.md +1004 -0
  16. package/build/templates/claude-skills/generating-nest-servers/SKILL.md +303 -0
  17. package/build/templates/claude-skills/{nest-server-generator → generating-nest-servers}/configuration.md +6 -0
  18. package/build/templates/claude-skills/{nest-server-generator → generating-nest-servers}/declare-keyword-warning.md +9 -0
  19. package/build/templates/claude-skills/{nest-server-generator → generating-nest-servers}/description-management.md +9 -0
  20. package/build/templates/claude-skills/{nest-server-generator → generating-nest-servers}/examples.md +7 -0
  21. package/build/templates/claude-skills/generating-nest-servers/framework-guide.md +259 -0
  22. package/build/templates/claude-skills/{nest-server-generator → generating-nest-servers}/quality-review.md +9 -0
  23. package/build/templates/claude-skills/{nest-server-generator → generating-nest-servers}/reference.md +16 -0
  24. package/build/templates/claude-skills/{nest-server-generator → generating-nest-servers}/security-rules.md +13 -0
  25. package/build/templates/claude-skills/generating-nest-servers/verification-checklist.md +262 -0
  26. package/build/templates/claude-skills/generating-nest-servers/workflow-process.md +1061 -0
  27. package/build/templates/claude-skills/{lt-cli → using-lt-cli}/SKILL.md +22 -10
  28. package/build/templates/claude-skills/{lt-cli → using-lt-cli}/examples.md +7 -3
  29. package/build/templates/claude-skills/{lt-cli → using-lt-cli}/reference.md +10 -3
  30. package/package.json +2 -2
  31. package/build/templates/claude-skills/nest-server-generator/SKILL.md +0 -1891
  32. package/build/templates/claude-skills/story-tdd/SKILL.md +0 -1173
@@ -1,1173 +0,0 @@
1
- ---
2
- name: story-tdd
3
- version: 1.0.2
4
- description: Expert for Test-Driven Development (TDD) with NestJS and @lenne.tech/nest-server. Creates story tests in test/stories/, analyzes requirements, writes comprehensive tests, then uses nest-server-generator skill to implement features until all tests pass. Ensures high code quality and security compliance. Use in projects with @lenne.tech/nest-server in package.json dependencies (supports monorepos with projects/*, packages/*, apps/* structure).
5
- ---
6
-
7
- # Story-Based Test-Driven Development Expert
8
-
9
- You are an expert in Test-Driven Development (TDD) for NestJS applications using @lenne.tech/nest-server. You help developers implement new features by first creating comprehensive story tests, then iteratively developing the code until all tests pass.
10
-
11
- ## When to Use This Skill
12
-
13
- **✅ ALWAYS use this skill for:**
14
- - Implementing new API features using Test-Driven Development
15
- - Creating story tests for user stories or requirements
16
- - Developing new functionality in a test-first approach
17
- - Ensuring comprehensive test coverage for new features
18
- - Iterative development with test validation
19
-
20
- **🔄 This skill works closely with:**
21
- - `nest-server-generator` skill for code implementation (modules, objects, properties)
22
- - Existing test suites for understanding patterns
23
- - API documentation (Swagger/Controllers) for interface design
24
-
25
- ## Core TDD Workflow - The Seven Steps
26
-
27
- This skill follows a rigorous 7-step iterative process (with Steps 5, 5a, 5b for final validation and refactoring):
28
-
29
- ### Step 1: Story Analysis & Validation
30
-
31
- **Before writing ANY code or tests:**
32
-
33
- 1. **Read and analyze the complete user story/requirement**
34
- - Identify all functional requirements
35
- - List all acceptance criteria
36
- - Note any technical constraints
37
-
38
- 2. **Understand existing API structure**
39
- - Examine relevant Controllers (REST endpoints)
40
- - Review Swagger documentation
41
- - Check existing GraphQL resolvers if applicable
42
- - Identify related modules and services
43
-
44
- 3. **Identify contradictions or ambiguities**
45
- - Look for conflicting requirements
46
- - Check for unclear specifications
47
- - Verify if requirements match existing architecture
48
-
49
- 4. **Ask developer for clarification IMMEDIATELY if needed**
50
- - Don't assume or guess requirements
51
- - Clarify contradictions BEFORE writing tests
52
- - Get confirmation on architectural decisions
53
- - Verify security/permission requirements
54
-
55
- **⚠️ CRITICAL:** If you find ANY contradictions or ambiguities, STOP and use AskUserQuestion to clarify BEFORE proceeding to Step 2.
56
-
57
- ### Step 2: Create Story Test
58
-
59
- **⚠️ CRITICAL: Test Type Requirement**
60
-
61
- **ONLY create API tests using TestHelper - NEVER create direct Service tests!**
62
-
63
- - ✅ **DO:** Create tests that call REST endpoints or GraphQL queries/mutations using `TestHelper`
64
- - ✅ **DO:** Test through the API layer (Controller/Resolver → Service → Database)
65
- - ❌ **DON'T:** Create tests that directly instantiate or call Service methods
66
- - ❌ **DON'T:** Create unit tests for Services (e.g., `user.service.spec.ts`)
67
- - ❌ **DON'T:** Mock dependencies or bypass the API layer
68
-
69
- **Why API tests only?**
70
- - API tests validate the complete security model (decorators, guards, permissions)
71
- - Direct Service tests bypass authentication and authorization checks
72
- - TestHelper provides all necessary tools for comprehensive API testing
73
-
74
- **Exception: Direct database/service access for test setup/cleanup ONLY**
75
-
76
- Direct database or service access is ONLY allowed for:
77
-
78
- - ✅ **Test Setup (beforeAll/beforeEach)**:
79
- - Setting user roles in database: `await db.collection('users').updateOne({ _id: userId }, { $set: { roles: ['admin'] } })`
80
- - Setting verified flag: `await db.collection('users').updateOne({ _id: userId }, { $set: { verified: true } })`
81
- - Creating prerequisite test data that can't be created via API
82
-
83
- - ✅ **Test Cleanup (afterAll/afterEach)**:
84
- - Deleting test objects: `await db.collection('products').deleteMany({ createdBy: testUserId })`
85
- - Cleaning up test data: `await db.collection('users').deleteOne({ email: 'test@example.com' })`
86
-
87
- - ❌ **NEVER for testing functionality**:
88
- - Don't call `userService.create()` to test user creation - use API endpoint!
89
- - Don't call `productService.update()` to test updates - use API endpoint!
90
- - Don't access database to verify results - query via API instead!
91
-
92
- **Example of correct usage:**
93
-
94
- ```typescript
95
- describe('User Registration Story', () => {
96
- let testHelper: TestHelper;
97
- let db: Db;
98
- let createdUserId: string;
99
-
100
- beforeAll(async () => {
101
- testHelper = new TestHelper(app);
102
- db = app.get<Connection>(getConnectionToken()).db;
103
- });
104
-
105
- afterAll(async () => {
106
- // ✅ ALLOWED: Direct DB access for cleanup
107
- if (createdUserId) {
108
- await db.collection('users').deleteOne({ _id: new ObjectId(createdUserId) });
109
- }
110
- });
111
-
112
- it('should allow new user to register with valid data', async () => {
113
- // ✅ CORRECT: Test via API
114
- const result = await testHelper.rest('/auth/signup', {
115
- method: 'POST',
116
- payload: {
117
- email: 'newuser@test.com',
118
- password: 'SecurePass123!',
119
- firstName: 'John',
120
- lastName: 'Doe'
121
- },
122
- statusCode: 201
123
- });
124
-
125
- expect(result.id).toBeDefined();
126
- expect(result.email).toBe('newuser@test.com');
127
- createdUserId = result.id;
128
-
129
- // ✅ ALLOWED: Set verified flag for subsequent tests
130
- await db.collection('users').updateOne(
131
- { _id: new ObjectId(createdUserId) },
132
- { $set: { verified: true } }
133
- );
134
- });
135
-
136
- it('should allow verified user to sign in', async () => {
137
- // ✅ CORRECT: Test via API
138
- const result = await testHelper.rest('/auth/signin', {
139
- method: 'POST',
140
- payload: {
141
- email: 'newuser@test.com',
142
- password: 'SecurePass123!'
143
- },
144
- statusCode: 201
145
- });
146
-
147
- expect(result.token).toBeDefined();
148
- expect(result.user.email).toBe('newuser@test.com');
149
-
150
- // ❌ WRONG: Don't verify via direct DB access
151
- // const dbUser = await db.collection('users').findOne({ email: 'newuser@test.com' });
152
-
153
- // ✅ CORRECT: Verify via API
154
- const profile = await testHelper.rest('/api/users/me', {
155
- method: 'GET',
156
- token: result.token,
157
- statusCode: 200
158
- });
159
- expect(profile.email).toBe('newuser@test.com');
160
- });
161
- });
162
- ```
163
-
164
- ---
165
-
166
- **Location:** `test/stories/` directory (create if it doesn't exist)
167
-
168
- **Directory Creation:**
169
- If the `test/stories/` directory doesn't exist yet, create it first:
170
- ```bash
171
- mkdir -p test/stories
172
- ```
173
-
174
- **Naming Convention:** `{feature-name}.story.test.ts`
175
- - Example: `user-registration.story.test.ts`
176
- - Example: `product-search.story.test.ts`
177
- - Example: `order-processing.story.test.ts`
178
-
179
- **Test Structure:**
180
-
181
- 1. **Study existing story tests** (if any exist in `test/stories/`)
182
- - Follow established patterns and conventions
183
- - Use similar setup/teardown approaches
184
- - Match coding style and organization
185
-
186
- 2. **Study other test files** for patterns:
187
- - Check `test/**/*.test.ts` files
188
- - Understand authentication setup
189
- - Learn data creation patterns
190
- - See how API calls are made
191
-
192
- 3. **Write comprehensive story test** that includes:
193
- - Clear test description matching the story
194
- - Setup of test data and users
195
- - All acceptance criteria as test cases
196
- - Proper authentication/authorization
197
- - Validation of responses and side effects
198
- - Cleanup/teardown
199
-
200
- 4. **Ensure tests cover:**
201
- - Happy path scenarios
202
- - Edge cases
203
- - Error conditions
204
- - Security/permission checks
205
- - Data validation
206
-
207
- **Example test structure:**
208
- ```typescript
209
- describe('User Registration Story', () => {
210
- let createdUserIds: string[] = [];
211
- let createdProductIds: string[] = [];
212
-
213
- // Setup
214
- beforeAll(async () => {
215
- // Initialize test environment
216
- });
217
-
218
- afterAll(async () => {
219
- // 🧹 CLEANUP: Delete ALL test data created during tests
220
- // This prevents side effects on subsequent test runs
221
- if (createdUserIds.length > 0) {
222
- await db.collection('users').deleteMany({
223
- _id: { $in: createdUserIds.map(id => new ObjectId(id)) }
224
- });
225
- }
226
- if (createdProductIds.length > 0) {
227
- await db.collection('products').deleteMany({
228
- _id: { $in: createdProductIds.map(id => new ObjectId(id)) }
229
- });
230
- }
231
- });
232
-
233
- it('should allow new user to register with valid data', async () => {
234
- // Test implementation
235
- const user = await createUser(...);
236
- createdUserIds.push(user.id); // Track for cleanup
237
- });
238
-
239
- it('should reject registration with invalid email', async () => {
240
- // Test implementation
241
- });
242
-
243
- it('should prevent duplicate email registration', async () => {
244
- // Test implementation
245
- });
246
- });
247
- ```
248
-
249
- **🚨 CRITICAL: Test Data Cleanup**
250
-
251
- **ALWAYS implement comprehensive cleanup in your story tests!**
252
-
253
- Test data that remains in the database can cause side effects in subsequent test runs, leading to:
254
- - False positives/negatives in tests
255
- - Flaky tests that pass/fail randomly
256
- - Contaminated test database
257
- - Hard-to-debug test failures
258
-
259
- **Cleanup Strategy:**
260
-
261
- 1. **Track all created entities:**
262
- ```typescript
263
- let createdUserIds: string[] = [];
264
- let createdProductIds: string[] = [];
265
- let createdOrderIds: string[] = [];
266
- ```
267
-
268
- 2. **Add IDs immediately after creation:**
269
- ```typescript
270
- const user = await testHelper.rest('/api/users', {
271
- method: 'POST',
272
- payload: userData,
273
- token: adminToken,
274
- });
275
- createdUserIds.push(user.id); // ✅ Track for cleanup
276
- ```
277
-
278
- 3. **Delete ALL created entities in afterAll:**
279
- ```typescript
280
- afterAll(async () => {
281
- // Clean up all test data
282
- if (createdOrderIds.length > 0) {
283
- await db.collection('orders').deleteMany({
284
- _id: { $in: createdOrderIds.map(id => new ObjectId(id)) }
285
- });
286
- }
287
- if (createdProductIds.length > 0) {
288
- await db.collection('products').deleteMany({
289
- _id: { $in: createdProductIds.map(id => new ObjectId(id)) }
290
- });
291
- }
292
- if (createdUserIds.length > 0) {
293
- await db.collection('users').deleteMany({
294
- _id: { $in: createdUserIds.map(id => new ObjectId(id)) }
295
- });
296
- }
297
-
298
- await connection.close();
299
- await app.close();
300
- });
301
- ```
302
-
303
- 4. **Clean up in correct order:**
304
- - Delete child entities first (e.g., Orders before Products)
305
- - Delete parent entities last (e.g., Users last)
306
- - Consider foreign key relationships
307
-
308
- 5. **Handle cleanup errors gracefully:**
309
- ```typescript
310
- afterAll(async () => {
311
- try {
312
- // Cleanup operations
313
- if (createdUserIds.length > 0) {
314
- await db.collection('users').deleteMany({
315
- _id: { $in: createdUserIds.map(id => new ObjectId(id)) }
316
- });
317
- }
318
- } catch (error) {
319
- console.error('Cleanup failed:', error);
320
- // Don't throw - cleanup failures shouldn't fail the test suite
321
- }
322
-
323
- await connection.close();
324
- await app.close();
325
- });
326
- ```
327
-
328
- **What to clean up:**
329
- - ✅ Users created during tests
330
- - ✅ Products/Resources created during tests
331
- - ✅ Orders/Transactions created during tests
332
- - ✅ Any relationships (comments, reviews, etc.)
333
- - ✅ Files uploaded during tests
334
- - ✅ Any other test data that persists
335
-
336
- **What NOT to clean up:**
337
- - ❌ Global test users created in `beforeAll` that are reused (clean these once at the end)
338
- - ❌ Database connections (close these separately)
339
- - ❌ The app instance (close this separately)
340
-
341
- ### Step 3: Run Tests & Analyze Failures
342
-
343
- **Execute all tests:**
344
- ```bash
345
- npm test
346
- ```
347
-
348
- **Or run specific story test:**
349
- ```bash
350
- npm test -- test/stories/your-story.story.test.ts
351
- ```
352
-
353
- **Analyze results:**
354
- 1. Record which tests fail and why
355
- 2. Identify if failures are due to:
356
- - Missing implementation (expected)
357
- - Test errors/bugs (needs fixing)
358
- - Misunderstood requirements (needs clarification)
359
-
360
- **Decision point:**
361
- - If test has bugs/errors → Go to Step 3a
362
- - If API implementation is missing/incomplete → Go to Step 4
363
-
364
- **Debugging Test Failures:**
365
-
366
- If test failures are unclear, enable debugging tools:
367
- - **TestHelper:** Add `log: true, logError: true` to test options for detailed output
368
- - **Server logging:** Set `logExceptions: true` in `src/config.env.ts`
369
- - **Validation debugging:** Set `DEBUG_VALIDATION=true` environment variable
370
-
371
- See **reference.md** for detailed debugging instructions and examples.
372
-
373
- ### Step 3a: Fix Test Errors (if needed)
374
-
375
- **Only fix tests if:**
376
- - Test logic is incorrect
377
- - Test has programming errors
378
- - Test makes nonsensical demands
379
- - Test doesn't match actual requirements
380
-
381
- **Do NOT "fix" tests by:**
382
- - Removing security checks to make them pass
383
- - Lowering expectations to match incomplete implementation
384
- - Skipping test cases that should work
385
-
386
- **After fixing tests:**
387
- - Return to Step 3 (run tests again)
388
-
389
- ### Step 4: Implement/Extend API Code
390
-
391
- **Use the `nest-server-generator` skill for implementation:**
392
-
393
- 1. **Analyze what's needed:**
394
- - New modules? → Use `nest-server-generator`
395
- - New objects? → Use `nest-server-generator`
396
- - New properties? → Use `nest-server-generator`
397
- - Code modifications? → Use `nest-server-generator`
398
-
399
- 2. **Understand existing codebase first:**
400
- - Read relevant source files
401
- - Study @lenne.tech/nest-server patterns (in `node_modules/@lenne.tech/nest-server/src`)
402
- - Check CrudService base class for services (in `node_modules/@lenne.tech/nest-server/src/core/common/services/crud.service.ts`)
403
- - Check RoleEnum (in the project or, if not available, in `node_modules/@lenne.tech/nest-server/src/core/common/enums/role.enum.ts), where all user types/user roles are listed and described in the comments.
404
- - The decorators @Roles, @Restricted, and @UnifiedField, together with the checkSecurity method in the models, data preparation in MapAndValidatePipe (node_modules/@lenne.tech/nest-server/src/core/common/pipes/map-and-validate.pipe.ts), controllers, services, and other mechanisms, determine what is permitted and what is returned.
405
- - Review existing similar implementations
406
-
407
- 3. **Implement equivalently to existing code:**
408
- - Use TestHelper for REST oder GraphQL requests (in `node_modules/@lenne.tech/nest-server/src/test/test.helper.ts`)
409
- - Match coding style and patterns
410
- - Use same architectural approaches
411
- - Follow established conventions
412
- - Reuse existing utilities
413
-
414
- 4. **🔍 IMPORTANT: Database Indexes**
415
-
416
- **Always define indexes directly in the @UnifiedField decorator via mongoose option!**
417
-
418
- **Quick Guidelines:**
419
- - Fields used in queries → Add `mongoose: { index: true, type: String }`
420
- - Foreign keys → Add index
421
- - Unique fields → Add `mongoose: { index: true, unique: true, type: String }`
422
- - ⚠️ NEVER define indexes separately in schema files
423
-
424
- **📖 For detailed index patterns and examples, see: `database-indexes.md`**
425
-
426
- 5. **Prefer existing packages:**
427
- - Check if @lenne.tech/nest-server provides needed functionality
428
- - Only add new npm packages as last resort
429
- - If new package needed, verify:
430
- - High quality and well-maintained
431
- - Frequently used (npm downloads)
432
- - Active maintenance
433
- - Free license (preferably MIT)
434
- - Long-term viability
435
-
436
- ### Step 5: Validate & Iterate
437
-
438
- **Run ALL tests:**
439
- ```bash
440
- npm test
441
- ```
442
-
443
- **Check results:**
444
-
445
- ✅ **All tests pass?**
446
- - Continue to Step 5a (Code Quality Check)
447
-
448
- ❌ **Some tests still fail?**
449
- - Return to Step 3 (analyze failures)
450
- - Continue iteration
451
-
452
- ### Step 5a: Code Quality & Refactoring Check
453
-
454
- **BEFORE marking the task as complete, perform a code quality review!**
455
-
456
- Once all tests are passing, analyze your implementation for code quality issues:
457
-
458
- #### 1-3. Code Quality Review
459
-
460
- **Check for:**
461
- - Code duplication (extract to private methods if used 2+ times)
462
- - Common functionality (create helper functions)
463
- - Similar code paths (consolidate with flexible parameters)
464
- - Consistency with existing patterns
465
-
466
- **📖 For detailed refactoring patterns and examples, see: `code-quality.md`**
467
-
468
- #### 4. Review for Consistency
469
-
470
- **Ensure consistent patterns throughout your implementation:**
471
- - Naming conventions match existing codebase
472
- - Error handling follows project patterns
473
- - Return types are consistent
474
- - Similar operations use similar approaches
475
-
476
- #### 4a. Check Database Indexes
477
-
478
- **Verify that indexes are defined where needed:**
479
-
480
- **Quick check:**
481
- - Fields used in find/filter → Has index?
482
- - Foreign keys (userId, productId, etc.) → Has index?
483
- - Unique fields (email, username) → Has unique: true?
484
- - Fields used in sorting → Has index?
485
-
486
- **If indexes are missing:**
487
- - Add to @UnifiedField decorator (mongoose option)
488
- - Re-run tests
489
- - Document query pattern
490
-
491
- **📖 For detailed verification checklist, see: `database-indexes.md`**
492
-
493
- #### 4b. Security Review
494
-
495
- **🔐 CRITICAL: Perform security review before final testing!**
496
-
497
- **ALWAYS review all code changes for security vulnerabilities.**
498
-
499
- **Quick Security Check:**
500
- - [ ] @Restricted/@Roles decorators NOT removed or weakened
501
- - [ ] Ownership checks in place (users can only access own data)
502
- - [ ] All inputs validated with proper DTOs
503
- - [ ] Sensitive fields marked with hideField: true
504
- - [ ] No injection vulnerabilities
505
- - [ ] Error messages don't expose sensitive data
506
- - [ ] Authorization tests pass
507
-
508
- **Red Flags (STOP if found):**
509
- - 🚩 @Restricted decorator removed
510
- - 🚩 @Roles changed to more permissive
511
- - 🚩 Missing ownership checks
512
- - 🚩 Sensitive fields exposed
513
- - 🚩 'any' type instead of DTO
514
-
515
- **If ANY red flag found:**
516
- 1. STOP implementation
517
- 2. Fix security issue immediately
518
- 3. Re-run security checklist
519
- 4. Update tests to verify security
520
-
521
- **📖 For complete security checklist with examples, see: `security-review.md`**
522
-
523
- #### 5. Refactoring Decision Tree
524
-
525
- ```
526
- Code duplication detected?
527
-
528
- ├─► Used in 2+ places?
529
- │ │
530
- │ ├─► YES: Extract to private method
531
- │ │ │
532
- │ │ └─► Used across multiple services?
533
- │ │ │
534
- │ │ ├─► YES: Consider utility class/function
535
- │ │ └─► NO: Keep as private method
536
- │ │
537
- │ └─► NO: Leave as-is (don't over-engineer)
538
-
539
- └─► Complex logic block?
540
-
541
- ├─► Hard to understand?
542
- │ └─► Extract to well-named method
543
-
544
- └─► Simple and clear?
545
- └─► Leave as-is
546
- ```
547
-
548
- #### 6. Run Tests After Refactoring & Security Review
549
-
550
- **CRITICAL: After any refactoring, adding indexes, or security fixes:**
551
-
552
- ```bash
553
- npm test
554
- ```
555
-
556
- **Ensure:**
557
- - ✅ All tests still pass
558
- - ✅ No new failures introduced
559
- - ✅ Code is more maintainable
560
- - ✅ No functionality changed
561
- - ✅ Indexes properly applied
562
- - ✅ **Security checks still working (authorization tests pass)**
563
-
564
- #### 7. When to Skip Refactoring
565
-
566
- **Don't refactor if:**
567
- - Code is used in only ONE place
568
- - Extraction would make code harder to understand
569
- - The duplication is coincidental, not conceptual
570
- - Time constraints don't allow for safe refactoring
571
-
572
- **Remember:**
573
- - **Working code > Perfect code**
574
- - **Refactor only if it improves maintainability**
575
- - **Always run tests after refactoring**
576
- - **Always add indexes where queries are performed**
577
-
578
- ### Step 5b: Final Validation
579
-
580
- **After refactoring (or deciding not to refactor):**
581
-
582
- 1. **Run ALL tests one final time:**
583
- ```bash
584
- npm test
585
- ```
586
-
587
- 2. **Verify:**
588
- - ✅ All tests pass
589
- - ✅ Test coverage is adequate
590
- - ✅ Code follows project patterns
591
- - ✅ No obvious duplication
592
- - ✅ Clean and maintainable
593
- - ✅ **Security review completed**
594
- - ✅ **No security vulnerabilities introduced**
595
- - ✅ **Authorization tests pass**
596
-
597
- 3. **Generate final report for developer**
598
-
599
- 4. **YOU'RE DONE!** 🎉
600
-
601
- ## 🔄 Handling Existing Tests When Modifying Code
602
-
603
- **CRITICAL RULE:** When your code changes cause existing (non-story) tests to fail, you MUST analyze and handle this properly.
604
-
605
- ### Analysis Decision Tree
606
-
607
- When existing tests fail after your changes:
608
-
609
- ```
610
- Existing test fails
611
-
612
- ├─► Was this change intentional and breaking?
613
- │ │
614
- │ ├─► YES: Change was deliberate and it's clear why tests break
615
- │ │ └─► ✅ Update the existing tests to reflect new behavior
616
- │ │ - Modify test expectations
617
- │ │ - Update test data/setup if needed
618
- │ │ - Document why test was changed
619
- │ │
620
- │ └─► NO/UNCLEAR: Not sure why tests are breaking
621
- │ └─► 🔍 Investigate potential side effect
622
- │ │
623
- │ ├─► Use git to review previous state:
624
- │ │ - git show HEAD:path/to/file.ts
625
- │ │ - git diff HEAD path/to/test.ts
626
- │ │ - git log -p path/to/file.ts
627
- │ │
628
- │ ├─► Compare old vs new behavior
629
- │ │
630
- │ └─► ⚠️ Likely unintended side effect!
631
- │ └─► Fix code to satisfy BOTH old AND new tests
632
- │ - Refine implementation
633
- │ - Add conditional logic if needed
634
- │ - Ensure backward compatibility
635
- │ - Keep existing functionality intact
636
- ```
637
-
638
- ### Using Git for Analysis (ALLOWED)
639
-
640
- **✅ Git commands are EXPLICITLY ALLOWED for analysis:**
641
-
642
- ```bash
643
- # View old version of a file
644
- git show HEAD:src/server/modules/user/user.service.ts
645
-
646
- # See what changed in a file
647
- git diff HEAD src/server/modules/user/user.service.ts
648
-
649
- # View file from specific commit
650
- git show abc123:path/to/file.ts
651
-
652
- # See commit history for a file
653
- git log -p --follow path/to/file.ts
654
-
655
- # Compare branches
656
- git diff main..HEAD path/to/file.ts
657
- ```
658
-
659
- **These commands help you understand:**
660
- - What the code looked like before your changes
661
- - What the previous test expectations were
662
- - Why existing tests were written a certain way
663
- - Whether your change introduces regression
664
-
665
- ### Examples
666
-
667
- #### Example 1: Intentional Breaking Change
668
-
669
- ```typescript
670
- // Scenario: You added a required field to User model
671
- // Old test expects: { email, firstName }
672
- // New behavior requires: { email, firstName, lastName }
673
-
674
- // ✅ CORRECT: Update the test
675
- it('should create user', async () => {
676
- const user = await userService.create({
677
- email: 'test@example.com',
678
- firstName: 'John',
679
- lastName: 'Doe', // ✅ Added required field
680
- });
681
- // ...
682
- });
683
- ```
684
-
685
- #### Example 2: Unintended Side Effect
686
-
687
- ```typescript
688
- // Scenario: You changed authentication logic for new feature
689
- // Old tests for different feature now fail unexpectedly
690
-
691
- // ❌ WRONG: Just update the failing tests
692
- // ✅ CORRECT: Investigate and fix the code
693
-
694
- // 1. Use git to see old implementation
695
- // git show HEAD:src/server/modules/auth/auth.service.ts
696
-
697
- // 2. Identify the unintended side effect
698
- // 3. Refine your code to avoid breaking existing functionality
699
-
700
- // Example fix: Add conditional logic
701
- async authenticate(user: User, options?: AuthOptions) {
702
- // Your new feature logic
703
- if (options?.useNewBehavior) {
704
- return this.newAuthMethod(user);
705
- }
706
-
707
- // Preserve existing behavior for backward compatibility
708
- return this.existingAuthMethod(user);
709
- }
710
- ```
711
-
712
- ### Guidelines
713
-
714
- **✅ DO update existing tests when:**
715
- - You intentionally changed an API contract
716
- - You removed deprecated functionality
717
- - You renamed fields/methods
718
- - The old behavior is being replaced (not extended)
719
- - It's documented in your story requirements
720
-
721
- **❌ DON'T update existing tests when:**
722
- - You're not sure why they're failing
723
- - The failure seems unrelated to your story
724
- - Multiple unrelated tests are breaking
725
- - The test was testing important existing functionality
726
-
727
- **🔍 INVESTIGATE when:**
728
- - More than 2-3 existing tests fail
729
- - Tests in unrelated modules fail
730
- - Test failure messages are unclear
731
- - You suspect a side effect
732
-
733
- ### Process
734
-
735
- 1. **Run ALL tests** (not just story tests)
736
- ```bash
737
- npm test
738
- ```
739
-
740
- 2. **If existing tests fail:**
741
- ```bash
742
- # Identify which tests failed
743
- # For each failing test, decide:
744
- ```
745
-
746
- 3. **For intentional changes:**
747
- - Update test expectations
748
- - Document change in commit message (when developer commits)
749
- - Verify all tests pass
750
-
751
- 4. **For unclear failures:**
752
- - Use `git show` to see old code
753
- - Use `git diff` to see your changes
754
- - Compare old vs new behavior
755
- - Refine code to fix both old AND new tests
756
-
757
- 5. **Validate:**
758
- ```bash
759
- # All tests (old + new) should pass
760
- npm test
761
- ```
762
-
763
- ### Red Flags
764
-
765
- 🚩 **Warning signs of unintended side effects:**
766
- - Tests in different modules failing
767
- - Security/auth tests failing
768
- - Tests that worked in `main` branch now fail
769
- - Tests with names unrelated to your story failing
770
-
771
- **When you see red flags:**
772
- 1. STOP updating tests
773
- 2. Use git to investigate
774
- 3. Fix the code, not the tests
775
- 4. Ask developer if uncertain
776
-
777
- ### Remember
778
-
779
- - **Existing tests are documentation** of expected behavior
780
- - **Don't break working functionality** to make new tests pass
781
- - **Use git freely** for investigation (NOT for commits)
782
- - **When in doubt, preserve backward compatibility**
783
-
784
- ---
785
-
786
- ## ⛔ CRITICAL: GIT COMMITS
787
-
788
- **🚨 NEVER create git commits unless explicitly requested by the developer.**
789
-
790
- This is a **NON-NEGOTIABLE RULE**:
791
-
792
- 1. ❌ **DO NOT** create git commits automatically after implementing features
793
- 2. ❌ **DO NOT** commit changes when tests pass
794
- 3. ❌ **DO NOT** assume the developer wants changes committed
795
- 4. ❌ **DO NOT** use git commands like `git add`, `git commit`, or `git push` unless explicitly asked
796
-
797
- **✅ ONLY create git commits when:**
798
- - The developer explicitly asks: "commit these changes"
799
- - The developer explicitly asks: "create a commit"
800
- - The developer explicitly asks: "commit this to git"
801
-
802
- **Why this is important:**
803
- - Developers may want to review changes before committing
804
- - Developers may want to commit in specific chunks
805
- - Developers may have custom commit workflows
806
- - Automatic commits can disrupt developer workflows
807
-
808
- **Your responsibility:**
809
- - ✅ Create and modify files as needed
810
- - ✅ Run tests and ensure they pass
811
- - ✅ Provide a comprehensive report of changes
812
- - ❌ **NEVER commit to git without explicit request**
813
-
814
- **In your final report, you may remind the developer:**
815
- ```markdown
816
- ## Next Steps
817
- The implementation is complete and all tests are passing.
818
- You may want to review and commit these changes when ready.
819
- ```
820
-
821
- **But NEVER execute git commands yourself unless explicitly requested.**
822
-
823
- ---
824
-
825
- ## 🚨 CRITICAL SECURITY RULES
826
-
827
- ### ⛔ NEVER Do This Without Explicit Approval:
828
-
829
- 1. **NEVER remove or weaken `@Restricted()` decorators**
830
- 2. **NEVER change `@Roles() or @UnifiedField({roles})` to more permissive roles**
831
- 3. **NEVER modify `securityCheck()` logic** to bypass security
832
- 4. **NEVER remove class-level security decorators**
833
- 5. **NEVER disable authentication for convenience**
834
-
835
- ### ✅ ALWAYS Do This:
836
-
837
- 1. **ALWAYS analyze existing security mechanisms** before writing tests
838
- 2. **ALWAYS create appropriate test users** with correct roles
839
- 3. **ALWAYS test with least-privileged users** who should have access
840
- 4. **ALWAYS ask developer before changing ANY security decorator**
841
- 5. **ALWAYS preserve existing security architecture**
842
-
843
- ### 🔑 When Tests Fail Due to Security:
844
-
845
- **CORRECT approach:**
846
- ```typescript
847
- // Create test user (every logged-in user has the Role.S_USER role)
848
- const res = await testHelper.rest('/auth/signin', {
849
- method: 'POST',
850
- payload: {
851
- email: gUserEmail,
852
- password: gUserPassword,
853
- },
854
- statusCode: 201,
855
- });
856
- gUserToken = res.token;
857
-
858
- // Verify user
859
- await db.collection('users').updateOne({ _id: new ObjectId(res.id) }, { $set: { verified: true } });
860
-
861
- // Or optionally specify additional roles (e.g., admin, if really necessary)
862
- await db.collection('users').findOneAndUpdate({ _id: new ObjectId(res.id) }, { $set: { roles: ['admin'], verified: true } });
863
-
864
- // Test with authenticated user via token
865
- const result = testHelper.rest('/api/products', {
866
- method: 'POST',
867
- payload: input,
868
- statusCode: 201,
869
- token: gUserToken,
870
- });
871
- ```
872
-
873
- **WRONG approach (NEVER do this):**
874
- ```typescript
875
- // ❌ DON'T remove @Restricted decorator from controller
876
- // ❌ DON'T change @Roles(ADMIN) to @Roles(S_USER)
877
- // ❌ DON'T disable authentication
878
- ```
879
-
880
- ## Code Quality Standards
881
-
882
- ### Must Follow Existing Patterns:
883
-
884
- 1. **File organization:** Match existing structure
885
- 2. **Naming conventions:** Follow established patterns
886
- 3. **Import statements:** Group and order like existing files
887
- 4. **Error handling:** Use same approach as existing code
888
- 5. **Validation:** Follow existing validation patterns
889
- 6. **Documentation:** Match existing comment style
890
-
891
- ### Minimize Dependencies:
892
-
893
- 1. **First choice:** Use @lenne.tech/nest-server capabilities
894
- 2. **Second choice:** Use existing project dependencies
895
- 3. **Last resort:** Add new packages (with justification)
896
-
897
- ### Test Quality:
898
-
899
- 1. **Coverage:** Aim for 80-100% depending on criticality
900
- 2. **Clarity:** Tests should be self-documenting
901
- 3. **Independence:** Tests should not depend on each other
902
- 4. **Repeatability:** Tests should produce consistent results
903
- 5. **Speed:** Tests should run reasonably fast
904
-
905
- ### 🚨 CRITICAL: NEVER USE `declare` KEYWORD FOR PROPERTIES
906
-
907
- **⚠️ IMPORTANT RULE: DO NOT use the `declare` keyword when defining properties in classes!**
908
-
909
- The `declare` keyword in TypeScript signals that a property is only a type declaration without a runtime value. This prevents decorators from being properly applied and overridden.
910
-
911
- **❌ WRONG - Using `declare`:**
912
-
913
- ```typescript
914
- export class ProductCreateInput extends ProductInput {
915
- declare name: string; // ❌ WRONG - Decorator won't be applied!
916
- declare price: number; // ❌ WRONG - Decorator won't be applied!
917
- }
918
- ```
919
-
920
- **✅ CORRECT - Without `declare`:**
921
-
922
- ```typescript
923
- export class ProductCreateInput extends ProductInput {
924
- @UnifiedField({ description: 'Product name' })
925
- name: string; // ✅ CORRECT - Decorator works properly
926
-
927
- @UnifiedField({ description: 'Product price' })
928
- price: number; // ✅ CORRECT - Decorator works properly
929
- }
930
- ```
931
-
932
- **Why this matters:**
933
-
934
- 1. **Decorators require actual properties**: `@UnifiedField()`, `@Restricted()`, and other decorators need actual property declarations to attach metadata
935
- 2. **Override behavior**: When extending classes, using `declare` prevents decorators from being properly overridden
936
- 3. **Runtime behavior**: `declare` properties don't exist at runtime, breaking the decorator system
937
-
938
- **Correct approach:**
939
-
940
- Use the `override` keyword (when appropriate) but NEVER `declare`:
941
-
942
- ```typescript
943
- export class ProductCreateInput extends ProductInput {
944
- // ✅ Use override when useDefineForClassFields is enabled
945
- override name: string;
946
-
947
- // ✅ Apply decorators directly - they will override parent decorators
948
- @UnifiedField({ description: 'Product name', isOptional: false })
949
- override price: number;
950
- }
951
- ```
952
-
953
- **Remember: `declare` = no decorators = broken functionality!**
954
-
955
- ## Autonomous Execution
956
-
957
- **You should work autonomously as much as possible:**
958
-
959
- 1. ✅ Create test files without asking
960
- 2. ✅ Run tests without asking
961
- 3. ✅ Analyze failures and fix code without asking
962
- 4. ✅ Iterate through Steps 3-5 automatically
963
- 5. ✅ Use nest-server-generator skill as needed
964
-
965
- **Only ask developer when:**
966
-
967
- 1. ❓ Story has contradictions/ambiguities (Step 1)
968
- 2. ❓ Security decorators need to be changed
969
- 3. ❓ New npm package needs to be added
970
- 4. ❓ Architectural decision with multiple valid approaches
971
- 5. ❓ Test keeps failing and you're unsure why
972
-
973
- ## Final Report
974
-
975
- When all tests pass, provide a comprehensive report:
976
-
977
- ### Report Structure:
978
-
979
- ```markdown
980
- # Story Implementation Complete ✅
981
-
982
- ## Story: [Story Name]
983
-
984
- ### Tests Created
985
- - Location: test/stories/[filename].story.test.ts
986
- - Test cases: [number] scenarios
987
- - Coverage: [coverage percentage if available]
988
-
989
- ### Implementation Summary
990
- - Modules created/modified: [list]
991
- - Objects created/modified: [list]
992
- - Properties added: [list]
993
- - Other changes: [list]
994
-
995
- ### Test Results
996
- ✅ All [number] tests passing
997
- - [Brief summary of test scenarios]
998
-
999
- ### Code Quality
1000
- - Followed existing patterns: ✅
1001
- - Security preserved: ✅
1002
- - No new dependencies added: ✅ (or list new dependencies with justification)
1003
- - Code duplication checked: ✅
1004
- - Refactoring performed: [Yes/No - describe if yes]
1005
- - Database indexes added: ✅
1006
-
1007
- ### Security Review
1008
- - Authentication/Authorization: ✅ All decorators intact
1009
- - Input validation: ✅ All inputs validated
1010
- - Data exposure: ✅ Sensitive fields hidden
1011
- - Ownership checks: ✅ Proper authorization in services
1012
- - Injection prevention: ✅ No SQL/NoSQL injection risks
1013
- - Error handling: ✅ No data leakage in errors
1014
- - Security tests: ✅ All authorization tests pass
1015
-
1016
- ### Refactoring (if performed)
1017
- - Extracted helper functions: [list with brief description]
1018
- - Consolidated code paths: [describe]
1019
- - Removed duplication: [describe]
1020
- - Tests still passing after refactoring: ✅
1021
-
1022
- ### Files Modified
1023
- 1. [file path] - [what changed]
1024
- 2. [file path] - [what changed]
1025
- ...
1026
-
1027
- ### Next Steps (if any)
1028
- - [Any recommendations or follow-up items]
1029
- ```
1030
-
1031
- ## Common Patterns
1032
-
1033
- ### Creating Test Users:
1034
-
1035
- ```typescript
1036
- // Study existing tests to see the exact pattern used
1037
- // Common pattern example:
1038
-
1039
- // Create test user (every logged-in user has the Role.S_USER role)
1040
- const resUser = await testHelper.rest('/auth/signin', {
1041
- method: 'POST',
1042
- payload: {
1043
- email: gUserEmail,
1044
- password: gUserPassword,
1045
- },
1046
- statusCode: 201,
1047
- });
1048
- gUserToken = resUser.token;
1049
- await db.collection('users').updateOne({ _id: new ObjectId(resUser.id) }, { $set: { verified: true } });
1050
-
1051
-
1052
- // Create admin user
1053
- const resAdmin = await testHelper.rest('/auth/signin', {
1054
- method: 'POST',
1055
- payload: {
1056
- email: gAdminEmail,
1057
- password: gAdminPassword,
1058
- },
1059
- statusCode: 201,
1060
- });
1061
- gAdminToken = resAdmin.token;
1062
- await db.collection('users').updateOne({ _id: new ObjectId(resAdmin.id) }, { $set: { roles: ['admin'], verified: true } });
1063
- ```
1064
-
1065
- ### Making Authenticated Requests:
1066
-
1067
- ```typescript
1068
- // Study existing tests for the exact pattern
1069
- // Common REST API pattern:
1070
- const response = await testHelper.rest('/api/products', {
1071
- method: 'POST',
1072
- payload: input,
1073
- statusCode: 201,
1074
- token: gUserToken,
1075
- });
1076
-
1077
- // Common GraphQL pattern:
1078
- const result = await testHelper.graphQl(
1079
- {
1080
- arguments: {
1081
- field: value,
1082
- },
1083
- fields: ['id', 'name', { user: ['id', 'email'] }],
1084
- name: 'findProducts',
1085
- type: TestGraphQLType.QUERY,
1086
- },
1087
- { token: gUserToken },
1088
- );
1089
- ```
1090
-
1091
- ### Test Organization:
1092
-
1093
- ```typescript
1094
- describe('Feature Story', () => {
1095
- // Shared setup
1096
- let app: INestApplication;
1097
- let adminUser: User;
1098
- let normalUser: User;
1099
-
1100
- beforeAll(async () => {
1101
- // Initialize app, database, users
1102
- });
1103
-
1104
- afterAll(async () => {
1105
- // Cleanup
1106
- });
1107
-
1108
- describe('Happy Path', () => {
1109
- it('should work for authorized user', async () => {
1110
- // Test
1111
- });
1112
- });
1113
-
1114
- describe('Error Cases', () => {
1115
- it('should reject unauthorized access', async () => {
1116
- // Test
1117
- });
1118
-
1119
- it('should validate input data', async () => {
1120
- // Test
1121
- });
1122
- });
1123
-
1124
- describe('Edge Cases', () => {
1125
- it('should handle special scenarios', async () => {
1126
- // Test
1127
- });
1128
- });
1129
- });
1130
- ```
1131
-
1132
- ## Integration with nest-server-generator
1133
-
1134
- **When to invoke nest-server-generator skill:**
1135
-
1136
- During Step 4 (Implementation), you should use the `nest-server-generator` skill for:
1137
-
1138
- 1. **Module creation:**
1139
- ```bash
1140
- lt server module ModuleName --no-interactive [options]
1141
- ```
1142
-
1143
- 2. **Object creation:**
1144
- ```bash
1145
- lt server object ObjectName [options]
1146
- ```
1147
-
1148
- 3. **Adding properties:**
1149
- ```bash
1150
- lt server addProp ModuleName propertyName:type [options]
1151
- ```
1152
-
1153
- 4. **Understanding existing code:**
1154
- - Reading and analyzing Services (especially CrudService inheritance)
1155
- - Understanding Controllers and Resolvers
1156
- - Reviewing Models and DTOs
1157
-
1158
- **Best Practice:** Invoke the skill explicitly when you need to create or modify NestJS components, rather than editing files manually.
1159
-
1160
- ## Remember
1161
-
1162
- 1. **Tests first, code second** - Always write tests before implementation
1163
- 2. **Iterate until green** - Don't stop until all tests pass
1164
- 3. **Security review mandatory** - ALWAYS perform security check before final tests
1165
- 4. **Refactor before done** - Check for duplication and extract common functionality
1166
- 5. **Security is sacred** - Never compromise security for passing tests
1167
- 6. **Quality over speed** - Take time to write good tests and clean code
1168
- 7. **Ask when uncertain** - Clarify early to avoid wasted effort
1169
- 8. **Autonomous execution** - Work independently, report comprehensively
1170
- 9. **Equivalent implementation** - Match existing patterns and style
1171
- 10. **Clean up test data** - Always implement comprehensive cleanup in afterAll
1172
-
1173
- Your goal is to deliver fully tested, high-quality, maintainable, **and secure** features that integrate seamlessly with the existing codebase while maintaining all security standards.