@lenne.tech/cli 1.0.1 → 1.0.2

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 (31) hide show
  1. package/build/commands/claude/install-commands.js +10 -5
  2. package/build/commands/claude/install-mcps.js +256 -0
  3. package/build/commands/claude/install-skills.js +90 -23
  4. package/build/lib/mcp-registry.js +71 -0
  5. package/build/templates/claude-commands/commit-message.md +21 -0
  6. package/build/templates/claude-commands/skill-optimize.md +431 -90
  7. package/build/templates/claude-skills/building-stories-with-tdd/SKILL.md +265 -0
  8. package/build/templates/claude-skills/{story-tdd → building-stories-with-tdd}/code-quality.md +10 -0
  9. package/build/templates/claude-skills/{story-tdd → building-stories-with-tdd}/database-indexes.md +9 -0
  10. package/build/templates/claude-skills/{story-tdd → building-stories-with-tdd}/examples.md +115 -64
  11. package/build/templates/claude-skills/building-stories-with-tdd/handling-existing-tests.md +197 -0
  12. package/build/templates/claude-skills/{story-tdd → building-stories-with-tdd}/reference.md +276 -29
  13. package/build/templates/claude-skills/{story-tdd → building-stories-with-tdd}/security-review.md +8 -0
  14. package/build/templates/claude-skills/building-stories-with-tdd/workflow.md +1004 -0
  15. package/build/templates/claude-skills/generating-nest-servers/SKILL.md +303 -0
  16. package/build/templates/claude-skills/{nest-server-generator → generating-nest-servers}/configuration.md +6 -0
  17. package/build/templates/claude-skills/{nest-server-generator → generating-nest-servers}/declare-keyword-warning.md +9 -0
  18. package/build/templates/claude-skills/{nest-server-generator → generating-nest-servers}/description-management.md +9 -0
  19. package/build/templates/claude-skills/{nest-server-generator → generating-nest-servers}/examples.md +7 -0
  20. package/build/templates/claude-skills/generating-nest-servers/framework-guide.md +259 -0
  21. package/build/templates/claude-skills/{nest-server-generator → generating-nest-servers}/quality-review.md +9 -0
  22. package/build/templates/claude-skills/{nest-server-generator → generating-nest-servers}/reference.md +16 -0
  23. package/build/templates/claude-skills/{nest-server-generator → generating-nest-servers}/security-rules.md +13 -0
  24. package/build/templates/claude-skills/generating-nest-servers/verification-checklist.md +262 -0
  25. package/build/templates/claude-skills/generating-nest-servers/workflow-process.md +1061 -0
  26. package/build/templates/claude-skills/{lt-cli → using-lt-cli}/SKILL.md +22 -10
  27. package/build/templates/claude-skills/{lt-cli → using-lt-cli}/examples.md +7 -3
  28. package/build/templates/claude-skills/{lt-cli → using-lt-cli}/reference.md +10 -3
  29. package/package.json +2 -2
  30. package/build/templates/claude-skills/nest-server-generator/SKILL.md +0 -1891
  31. package/build/templates/claude-skills/story-tdd/SKILL.md +0 -1173
@@ -1,11 +1,18 @@
1
1
  ---
2
2
  name: story-tdd-examples
3
- version: 1.0.0
3
+ version: 1.0.1
4
4
  description: Complete examples for Test-Driven Development workflow with NestJS story tests
5
5
  ---
6
6
 
7
7
  # Story-Based TDD Examples
8
8
 
9
+ ## Table of Contents
10
+ - [Example 1: Simple CRUD Feature - Product Reviews](#example-1-simple-crud-feature---product-reviews)
11
+ - [Example 2: Complex Business Logic - Order Processing](#example-2-complex-business-logic---order-processing)
12
+ - [Example 3: GraphQL Mutation - User Profile Update](#example-3-graphql-mutation---user-profile-update)
13
+ - [Debugging Test Failures](#debugging-test-failures)
14
+ - [Key Takeaways from Examples](#key-takeaways-from-examples)
15
+
9
16
  This document provides complete examples of the TDD workflow for different types of user stories.
10
17
 
11
18
  ## Example 1: Simple CRUD Feature - Product Reviews
@@ -36,13 +43,36 @@ Acceptance Criteria:
36
43
  - Can users review a product multiple times? (Assuming NO)
37
44
  - What validation for rating? (Assuming 1-5 integer)
38
45
 
46
+ **🔍 Verification of existing API (CRITICAL - Do this BEFORE writing tests!):**
47
+
48
+ 1. **Check Product endpoints:**
49
+ ```
50
+ ✅ Read src/server/modules/product/product.controller.ts
51
+ ✅ Verified: GET /api/products exists (line 23)
52
+ ✅ Verified: POST /api/products exists (line 45)
53
+ ✅ Verified: Returns Product with id, name, price
54
+ ```
55
+
56
+ 2. **Check Review endpoints:**
57
+ ```
58
+ ❌ Review module does NOT exist yet
59
+ ❌ POST /api/reviews needs to be implemented
60
+ ❌ GET /api/products/:id/reviews needs to be implemented
61
+ ```
62
+
63
+ 3. **Plan implementation:**
64
+ - Need to create Review module (service, controller, model)
65
+ - Need to add POST /api/reviews endpoint
66
+ - Need to add GET /api/products/:id/reviews endpoint
67
+
39
68
  ### Step 2: Create Story Test
40
69
 
41
- **File:** `test/stories/product-review.story.test.ts`
70
+ **File:** `tests/stories/product-review.story.test.ts`
42
71
 
43
72
  ```typescript
44
73
  import {
45
74
  ConfigService,
75
+ getObjectIds,
46
76
  HttpExceptionLogFilter,
47
77
  TestGraphQLType,
48
78
  TestHelper,
@@ -53,11 +83,11 @@ import { MongoClient, ObjectId } from 'mongodb';
53
83
 
54
84
  import envConfig from '../../src/config.env';
55
85
  import { RoleEnum } from '../../src/server/common/enums/role.enum';
56
- import { ProductService } from '../../src/server/modules/product/product.service';
57
- import { ReviewService } from '../../src/server/modules/review/review.service';
58
- import { UserService } from '../../src/server/modules/user/user.service';
59
86
  import { imports, ServerModule } from '../../src/server/server.module';
60
87
 
88
+ // ⚠️ NOTE: No Service imports! Tests must use API endpoints only.
89
+ // Services are only accessed indirectly through Controllers/Resolvers.
90
+
61
91
  describe('Product Review Story', () => {
62
92
  // Test environment properties
63
93
  let app;
@@ -67,11 +97,6 @@ describe('Product Review Story', () => {
67
97
  let connection;
68
98
  let db;
69
99
 
70
- // Services
71
- let userService: UserService;
72
- let productService: ProductService;
73
- let reviewService: ReviewService;
74
-
75
100
  // Global test data
76
101
  let gAdminToken: string;
77
102
  let gAdminId: string;
@@ -87,9 +112,6 @@ describe('Product Review Story', () => {
87
112
  const moduleFixture: TestingModule = await Test.createTestingModule({
88
113
  imports: [...imports, ServerModule],
89
114
  providers: [
90
- UserService,
91
- ProductService,
92
- ReviewService,
93
115
  {
94
116
  provide: 'PUB_SUB',
95
117
  useValue: new PubSub(),
@@ -104,15 +126,12 @@ describe('Product Review Story', () => {
104
126
  await app.init();
105
127
 
106
128
  testHelper = new TestHelper(app);
107
- userService = moduleFixture.get(UserService);
108
- productService = moduleFixture.get(ProductService);
109
- reviewService = moduleFixture.get(ReviewService);
110
129
 
111
130
  // Connection to database
112
131
  connection = await MongoClient.connect(envConfig.mongoose.uri);
113
132
  db = await connection.db();
114
133
 
115
- // Create admin user
134
+ // Create admin user via API
116
135
  const adminPassword = Math.random().toString(36).substring(7);
117
136
  const adminEmail = `admin-${adminPassword}@test.com`;
118
137
  const adminSignUp = await testHelper.graphQl({
@@ -130,8 +149,11 @@ describe('Product Review Story', () => {
130
149
  gAdminId = adminSignUp.user.id;
131
150
  gAdminToken = adminSignUp.token;
132
151
 
133
- // Set admin role
134
- await userService.update(gAdminId, { roles: [RoleEnum.ADMIN] }, gAdminId);
152
+ // ✅ ALLOWED EXCEPTION: Set admin role via direct DB access (no API endpoint for this)
153
+ await db.collection('users').updateOne(
154
+ { _id: new ObjectId(gAdminId) },
155
+ { $set: { roles: [RoleEnum.ADMIN] } }
156
+ );
135
157
 
136
158
  // Create normal user
137
159
  const userPassword = Math.random().toString(36).substring(7);
@@ -166,24 +188,24 @@ describe('Product Review Story', () => {
166
188
  afterAll(async () => {
167
189
  // 🧹 CLEANUP: Delete all test data created during tests
168
190
  try {
169
- // Delete all created reviews
191
+ // Delete all created reviews (using getObjectIds for array conversion)
170
192
  if (createdReviewIds.length > 0) {
171
193
  await db.collection('reviews').deleteMany({
172
- _id: { $in: createdReviewIds.map(id => new ObjectId(id)) }
194
+ _id: { $in: getObjectIds(createdReviewIds) }
173
195
  });
174
196
  }
175
197
 
176
- // Delete test product
198
+ // Delete test product (using getObjectIds for single value - no array needed!)
177
199
  if (gProductId) {
178
- await db.collection('products').deleteOne({ _id: new ObjectId(gProductId) });
200
+ await db.collection('products').deleteOne({ _id: getObjectIds(gProductId) });
179
201
  }
180
202
 
181
- // Delete test users
203
+ // Delete test users (using getObjectIds for single values)
182
204
  if (gUserId) {
183
- await db.collection('users').deleteOne({ _id: new ObjectId(gUserId) });
205
+ await db.collection('users').deleteOne({ _id: getObjectIds(gUserId) });
184
206
  }
185
207
  if (gAdminId) {
186
- await db.collection('users').deleteOne({ _id: new ObjectId(gAdminId) });
208
+ await db.collection('users').deleteOne({ _id: getObjectIds(gAdminId) });
187
209
  }
188
210
  } catch (error) {
189
211
  console.error('Cleanup failed:', error);
@@ -390,11 +412,12 @@ Acceptance Criteria:
390
412
 
391
413
  ### Step 2: Create Story Test
392
414
 
393
- **File:** `test/stories/order-processing.story.test.ts`
415
+ **File:** `tests/stories/order-processing.story.test.ts`
394
416
 
395
417
  ```typescript
396
418
  import {
397
419
  ConfigService,
420
+ getObjectIds,
398
421
  HttpExceptionLogFilter,
399
422
  TestGraphQLType,
400
423
  TestHelper,
@@ -405,11 +428,11 @@ import { MongoClient, ObjectId } from 'mongodb';
405
428
 
406
429
  import envConfig from '../../src/config.env';
407
430
  import { RoleEnum } from '../../src/server/common/enums/role.enum';
408
- import { OrderService } from '../../src/server/modules/order/order.service';
409
- import { ProductService } from '../../src/server/modules/product/product.service';
410
- import { UserService } from '../../src/server/modules/user/user.service';
411
431
  import { imports, ServerModule } from '../../src/server/server.module';
412
432
 
433
+ // ⚠️ NOTE: No Service imports! Tests must use API endpoints only.
434
+ // Services are only accessed indirectly through Controllers/Resolvers.
435
+
413
436
  describe('Order Processing Story', () => {
414
437
  // Test environment properties
415
438
  let app;
@@ -419,11 +442,6 @@ describe('Order Processing Story', () => {
419
442
  let connection;
420
443
  let db;
421
444
 
422
- // Services
423
- let userService: UserService;
424
- let productService: ProductService;
425
- let orderService: OrderService;
426
-
427
445
  // Global test data
428
446
  let gAdminToken: string;
429
447
  let gAdminId: string;
@@ -442,9 +460,6 @@ describe('Order Processing Story', () => {
442
460
  const moduleFixture: TestingModule = await Test.createTestingModule({
443
461
  imports: [...imports, ServerModule],
444
462
  providers: [
445
- UserService,
446
- ProductService,
447
- OrderService,
448
463
  {
449
464
  provide: 'PUB_SUB',
450
465
  useValue: new PubSub(),
@@ -459,15 +474,12 @@ describe('Order Processing Story', () => {
459
474
  await app.init();
460
475
 
461
476
  testHelper = new TestHelper(app);
462
- userService = moduleFixture.get(UserService);
463
- productService = moduleFixture.get(ProductService);
464
- orderService = moduleFixture.get(OrderService);
465
477
 
466
478
  // Connection to database
467
479
  connection = await MongoClient.connect(envConfig.mongoose.uri);
468
480
  db = await connection.db();
469
481
 
470
- // Create admin user
482
+ // Create admin user via API
471
483
  const adminPassword = Math.random().toString(36).substring(7);
472
484
  const adminEmail = `admin-${adminPassword}@test.com`;
473
485
  const adminSignUp = await testHelper.graphQl({
@@ -485,8 +497,11 @@ describe('Order Processing Story', () => {
485
497
  gAdminId = adminSignUp.user.id;
486
498
  gAdminToken = adminSignUp.token;
487
499
 
488
- // Set admin role
489
- await userService.update(gAdminId, { roles: [RoleEnum.ADMIN] }, gAdminId);
500
+ // ✅ ALLOWED EXCEPTION: Set admin role via direct DB access (no API endpoint for this)
501
+ await db.collection('users').updateOne(
502
+ { _id: new ObjectId(gAdminId) },
503
+ { $set: { roles: [RoleEnum.ADMIN] } }
504
+ );
490
505
 
491
506
  // Create customer user
492
507
  const customerPassword = Math.random().toString(36).substring(7);
@@ -537,26 +552,26 @@ describe('Order Processing Story', () => {
537
552
  afterAll(async () => {
538
553
  // 🧹 CLEANUP: Delete all test data created during tests
539
554
  try {
540
- // Delete all created orders first (child entities)
555
+ // Delete all created orders first (child entities) - using getObjectIds for arrays
541
556
  if (createdOrderIds.length > 0) {
542
557
  await db.collection('orders').deleteMany({
543
- _id: { $in: createdOrderIds.map(id => new ObjectId(id)) }
558
+ _id: { $in: getObjectIds(createdOrderIds) }
544
559
  });
545
560
  }
546
561
 
547
- // Delete all created products
562
+ // Delete all created products - using getObjectIds for arrays
548
563
  if (createdProductIds.length > 0) {
549
564
  await db.collection('products').deleteMany({
550
- _id: { $in: createdProductIds.map(id => new ObjectId(id)) }
565
+ _id: { $in: getObjectIds(createdProductIds) }
551
566
  });
552
567
  }
553
568
 
554
- // Delete test users
569
+ // Delete test users - using getObjectIds for single values (no array needed!)
555
570
  if (gCustomerId) {
556
- await db.collection('users').deleteOne({ _id: new ObjectId(gCustomerId) });
571
+ await db.collection('users').deleteOne({ _id: getObjectIds(gCustomerId) });
557
572
  }
558
573
  if (gAdminId) {
559
- await db.collection('users').deleteOne({ _id: new ObjectId(gAdminId) });
574
+ await db.collection('users').deleteOne({ _id: getObjectIds(gAdminId) });
560
575
  }
561
576
  } catch (error) {
562
577
  console.error('Cleanup failed:', error);
@@ -930,24 +945,27 @@ Acceptance Criteria:
930
945
 
931
946
  ### Step 2: Create Story Test (GraphQL)
932
947
 
933
- **File:** `test/stories/profile-update.story.test.ts`
948
+ **File:** `tests/stories/profile-update.story.test.ts`
934
949
 
935
950
  ```typescript
936
951
  import {
937
952
  ConfigService,
953
+ getObjectIds,
938
954
  HttpExceptionLogFilter,
939
955
  TestGraphQLType,
940
956
  TestHelper,
941
957
  } from '@lenne.tech/nest-server';
942
958
  import { Test, TestingModule } from '@nestjs/testing';
943
959
  import { PubSub } from 'graphql-subscriptions';
944
- import { MongoClient } from 'mongodb';
960
+ import { MongoClient, ObjectId } from 'mongodb';
945
961
 
946
962
  import envConfig from '../../src/config.env';
947
963
  import { RoleEnum } from '../../src/server/common/enums/role.enum';
948
- import { UserService } from '../../src/server/modules/user/user.service';
949
964
  import { imports, ServerModule } from '../../src/server/server.module';
950
965
 
966
+ // ⚠️ NOTE: No Service imports! Tests must use API endpoints only.
967
+ // Services are only accessed indirectly through Controllers/Resolvers.
968
+
951
969
  describe('Profile Update Story (GraphQL)', () => {
952
970
  // Test environment properties
953
971
  let app;
@@ -957,9 +975,6 @@ describe('Profile Update Story (GraphQL)', () => {
957
975
  let connection;
958
976
  let db;
959
977
 
960
- // Services
961
- let userService: UserService;
962
-
963
978
  // Global test data
964
979
  let gNormalUserId: string;
965
980
  let gNormalUserToken: string;
@@ -977,7 +992,6 @@ describe('Profile Update Story (GraphQL)', () => {
977
992
  const moduleFixture: TestingModule = await Test.createTestingModule({
978
993
  imports: [...imports, ServerModule],
979
994
  providers: [
980
- UserService,
981
995
  {
982
996
  provide: 'PUB_SUB',
983
997
  useValue: new PubSub(),
@@ -992,7 +1006,6 @@ describe('Profile Update Story (GraphQL)', () => {
992
1006
  await app.init();
993
1007
 
994
1008
  testHelper = new TestHelper(app);
995
- userService = moduleFixture.get(UserService);
996
1009
 
997
1010
  // Connection to database
998
1011
  connection = await MongoClient.connect(envConfig.mongoose.uri);
@@ -1062,17 +1075,20 @@ describe('Profile Update Story (GraphQL)', () => {
1062
1075
  // Track for cleanup
1063
1076
  createdUserIds.push(gAdminUserId);
1064
1077
 
1065
- // Set admin role
1066
- await userService.update(gAdminUserId, { roles: [RoleEnum.ADMIN] }, gAdminUserId);
1078
+ // ✅ ALLOWED EXCEPTION: Set admin role via direct DB access (no API endpoint for this)
1079
+ await db.collection('users').updateOne(
1080
+ { _id: new ObjectId(gAdminUserId) },
1081
+ { $set: { roles: [RoleEnum.ADMIN] } }
1082
+ );
1067
1083
  });
1068
1084
 
1069
1085
  afterAll(async () => {
1070
1086
  // 🧹 CLEANUP: Delete all test data created during tests
1071
1087
  try {
1072
- // Delete all created users
1088
+ // Delete all created users - using getObjectIds
1073
1089
  if (createdUserIds.length > 0) {
1074
1090
  await db.collection('users').deleteMany({
1075
- _id: { $in: createdUserIds.map(id => new ObjectId(id)) }
1091
+ _id: { $in: getObjectIds(createdUserIds) }
1076
1092
  });
1077
1093
  }
1078
1094
  } catch (error) {
@@ -1211,6 +1227,14 @@ describe('Profile Update Story (GraphQL)', () => {
1211
1227
 
1212
1228
  When your tests fail and error messages are unclear, enable debugging:
1213
1229
 
1230
+ **🔍 TIP: For all TestHelper options, read the source file:**
1231
+
1232
+ ```
1233
+ node_modules/@lenne.tech/nest-server/src/test/test.helper.ts
1234
+ ```
1235
+
1236
+ This file documents all capabilities including `log`, `logError`, file uploads via `attachments`, and more.
1237
+
1214
1238
  ### TestHelper Debugging Options
1215
1239
 
1216
1240
  ```typescript
@@ -1262,7 +1286,7 @@ beforeAll(async () => {
1262
1286
  });
1263
1287
  ```
1264
1288
 
1265
- This enables detailed console.debug output from MapAndValidatePipe (`node_modules/@lenne.tech/nest-server/src/core/common/pipes/map-and-validate.pipe.ts`).
1289
+ This enables detailed console.debug output from MapAndValidatePipe (automatically activated via CoreModule - see `node_modules/@lenne.tech/nest-server/src/core/common/pipes/map-and-validate.pipe.ts`).
1266
1290
 
1267
1291
  ### Full Debugging Setup Example
1268
1292
 
@@ -1288,6 +1312,33 @@ describe('My Story Test', () => {
1288
1312
 
1289
1313
  **Remember to disable debugging logs before committing** to keep test output clean in CI/CD.
1290
1314
 
1315
+ ### File Upload Testing
1316
+
1317
+ TestHelper supports file uploads via the `attachments` option:
1318
+
1319
+ ```typescript
1320
+ // Upload a single file
1321
+ const result = await testHelper.rest('/api/upload', {
1322
+ method: 'POST',
1323
+ attachments: [
1324
+ { name: 'document', path: '/path/to/document.pdf' },
1325
+ ],
1326
+ token: userToken,
1327
+ });
1328
+
1329
+ // Upload multiple files
1330
+ const result = await testHelper.rest('/api/upload-multiple', {
1331
+ method: 'POST',
1332
+ attachments: [
1333
+ { name: 'avatar', path: '/path/to/avatar.png' },
1334
+ { name: 'resume', path: '/path/to/resume.pdf' },
1335
+ ],
1336
+ token: userToken,
1337
+ });
1338
+ ```
1339
+
1340
+ **See `node_modules/@lenne.tech/nest-server/src/test/test.helper.ts` for all available options.**
1341
+
1291
1342
  ---
1292
1343
 
1293
1344
  ## Key Takeaways from Examples
@@ -0,0 +1,197 @@
1
+ ---
2
+ name: story-tdd-handling-existing-tests
3
+ version: 1.0.0
4
+ description: Complete guide for handling existing tests when modifying code in TDD workflow - decision trees, git analysis, examples, and guidelines for determining when to update tests vs fix code
5
+ ---
6
+
7
+ # 🔄 Handling Existing Tests When Modifying Code
8
+
9
+ ## Table of Contents
10
+ - [Analysis Decision Tree](#analysis-decision-tree)
11
+ - [Using Git for Analysis (ALLOWED)](#using-git-for-analysis-allowed)
12
+ - [Examples](#examples)
13
+ - [Guidelines](#guidelines)
14
+ - [Process](#process)
15
+ - [Red Flags](#red-flags)
16
+ - [Remember](#remember)
17
+
18
+ **CRITICAL RULE:** When your code changes cause existing (non-story) tests to fail, you MUST analyze and handle this properly.
19
+
20
+ ## Analysis Decision Tree
21
+
22
+ When existing tests fail after your changes:
23
+
24
+ ```
25
+ Existing test fails
26
+
27
+ ├─► Was this change intentional and breaking?
28
+ │ │
29
+ │ ├─► YES: Change was deliberate and it's clear why tests break
30
+ │ │ └─► ✅ Update the existing tests to reflect new behavior
31
+ │ │ - Modify test expectations
32
+ │ │ - Update test data/setup if needed
33
+ │ │ - Document why test was changed
34
+ │ │
35
+ │ └─► NO/UNCLEAR: Not sure why tests are breaking
36
+ │ └─► 🔍 Investigate potential side effect
37
+ │ │
38
+ │ ├─► Use git to review previous state:
39
+ │ │ - git show HEAD:path/to/file.ts
40
+ │ │ - git diff HEAD path/to/test.ts
41
+ │ │ - git log -p path/to/file.ts
42
+ │ │
43
+ │ ├─► Compare old vs new behavior
44
+ │ │
45
+ │ └─► ⚠️ Likely unintended side effect!
46
+ │ └─► Fix code to satisfy BOTH old AND new tests
47
+ │ - Refine implementation
48
+ │ - Add conditional logic if needed
49
+ │ - Ensure backward compatibility
50
+ │ - Keep existing functionality intact
51
+ ```
52
+
53
+ ## Using Git for Analysis (ALLOWED)
54
+
55
+ **✅ Git commands are EXPLICITLY ALLOWED for analysis:**
56
+
57
+ ```bash
58
+ # View old version of a file
59
+ git show HEAD:src/server/modules/user/user.service.ts
60
+
61
+ # See what changed in a file
62
+ git diff HEAD src/server/modules/user/user.service.ts
63
+
64
+ # View file from specific commit
65
+ git show abc123:path/to/file.ts
66
+
67
+ # See commit history for a file
68
+ git log -p --follow path/to/file.ts
69
+
70
+ # Compare branches
71
+ git diff main..HEAD path/to/file.ts
72
+ ```
73
+
74
+ **These commands help you understand:**
75
+ - What the code looked like before your changes
76
+ - What the previous test expectations were
77
+ - Why existing tests were written a certain way
78
+ - Whether your change introduces regression
79
+
80
+ ## Examples
81
+
82
+ ### Example 1: Intentional Breaking Change
83
+
84
+ ```typescript
85
+ // Scenario: You added a required field to User model
86
+ // Old test expects: { email, firstName }
87
+ // New behavior requires: { email, firstName, lastName }
88
+
89
+ // ✅ CORRECT: Update the test
90
+ it('should create user', async () => {
91
+ const user = await userService.create({
92
+ email: 'test@example.com',
93
+ firstName: 'John',
94
+ lastName: 'Doe', // ✅ Added required field
95
+ });
96
+ // ...
97
+ });
98
+ ```
99
+
100
+ ### Example 2: Unintended Side Effect
101
+
102
+ ```typescript
103
+ // Scenario: You changed authentication logic for new feature
104
+ // Old tests for different feature now fail unexpectedly
105
+
106
+ // ❌ WRONG: Just update the failing tests
107
+ // ✅ CORRECT: Investigate and fix the code
108
+
109
+ // 1. Use git to see old implementation
110
+ // git show HEAD:src/server/modules/auth/auth.service.ts
111
+
112
+ // 2. Identify the unintended side effect
113
+ // 3. Refine your code to avoid breaking existing functionality
114
+
115
+ // Example fix: Add conditional logic
116
+ async authenticate(user: User, options?: AuthOptions) {
117
+ // Your new feature logic
118
+ if (options?.useNewBehavior) {
119
+ return this.newAuthMethod(user);
120
+ }
121
+
122
+ // Preserve existing behavior for backward compatibility
123
+ return this.existingAuthMethod(user);
124
+ }
125
+ ```
126
+
127
+ ## Guidelines
128
+
129
+ **✅ DO update existing tests when:**
130
+ - You intentionally changed an API contract
131
+ - You removed deprecated functionality
132
+ - You renamed fields/methods
133
+ - The old behavior is being replaced (not extended)
134
+ - It's documented in your story requirements
135
+
136
+ **❌ DON'T update existing tests when:**
137
+ - You're not sure why they're failing
138
+ - The failure seems unrelated to your story
139
+ - Multiple unrelated tests are breaking
140
+ - The test was testing important existing functionality
141
+
142
+ **🔍 INVESTIGATE when:**
143
+ - More than 2-3 existing tests fail
144
+ - Tests in unrelated modules fail
145
+ - Test failure messages are unclear
146
+ - You suspect a side effect
147
+
148
+ ## Process
149
+
150
+ 1. **Run ALL tests** (not just story tests)
151
+ ```bash
152
+ npm test
153
+ ```
154
+
155
+ 2. **If existing tests fail:**
156
+ ```bash
157
+ # Identify which tests failed
158
+ # For each failing test, decide:
159
+ ```
160
+
161
+ 3. **For intentional changes:**
162
+ - Update test expectations
163
+ - Document change in commit message (when developer commits)
164
+ - Verify all tests pass
165
+
166
+ 4. **For unclear failures:**
167
+ - Use `git show` to see old code
168
+ - Use `git diff` to see your changes
169
+ - Compare old vs new behavior
170
+ - Refine code to fix both old AND new tests
171
+
172
+ 5. **Validate:**
173
+ ```bash
174
+ # All tests (old + new) should pass
175
+ npm test
176
+ ```
177
+
178
+ ## Red Flags
179
+
180
+ 🚩 **Warning signs of unintended side effects:**
181
+ - Tests in different modules failing
182
+ - Security/auth tests failing
183
+ - Tests that worked in `main` branch now fail
184
+ - Tests with names unrelated to your story failing
185
+
186
+ **When you see red flags:**
187
+ 1. STOP updating tests
188
+ 2. Use git to investigate
189
+ 3. Fix the code, not the tests
190
+ 4. Ask developer if uncertain
191
+
192
+ ## Remember
193
+
194
+ - **Existing tests are documentation** of expected behavior
195
+ - **Don't break working functionality** to make new tests pass
196
+ - **Use git freely** for investigation (NOT for commits)
197
+ - **When in doubt, preserve backward compatibility**