@lenne.tech/cli 1.2.0 → 1.3.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 (36) hide show
  1. package/build/commands/claude/install-plugin.js +339 -0
  2. package/package.json +1 -1
  3. package/build/commands/claude/install-commands.js +0 -337
  4. package/build/commands/claude/install-mcps.js +0 -258
  5. package/build/commands/claude/install-skills.js +0 -693
  6. package/build/lib/mcp-registry.js +0 -80
  7. package/build/templates/claude-commands/code-cleanup.md +0 -82
  8. package/build/templates/claude-commands/commit-message.md +0 -21
  9. package/build/templates/claude-commands/create-story.md +0 -435
  10. package/build/templates/claude-commands/mr-description-clipboard.md +0 -48
  11. package/build/templates/claude-commands/mr-description.md +0 -33
  12. package/build/templates/claude-commands/sec-review.md +0 -62
  13. package/build/templates/claude-commands/skill-optimize.md +0 -481
  14. package/build/templates/claude-commands/test-generate.md +0 -45
  15. package/build/templates/claude-skills/building-stories-with-tdd/SKILL.md +0 -265
  16. package/build/templates/claude-skills/building-stories-with-tdd/code-quality.md +0 -276
  17. package/build/templates/claude-skills/building-stories-with-tdd/database-indexes.md +0 -182
  18. package/build/templates/claude-skills/building-stories-with-tdd/examples.md +0 -1383
  19. package/build/templates/claude-skills/building-stories-with-tdd/handling-existing-tests.md +0 -197
  20. package/build/templates/claude-skills/building-stories-with-tdd/reference.md +0 -1427
  21. package/build/templates/claude-skills/building-stories-with-tdd/security-review.md +0 -307
  22. package/build/templates/claude-skills/building-stories-with-tdd/workflow.md +0 -1004
  23. package/build/templates/claude-skills/generating-nest-servers/SKILL.md +0 -303
  24. package/build/templates/claude-skills/generating-nest-servers/configuration.md +0 -285
  25. package/build/templates/claude-skills/generating-nest-servers/declare-keyword-warning.md +0 -133
  26. package/build/templates/claude-skills/generating-nest-servers/description-management.md +0 -226
  27. package/build/templates/claude-skills/generating-nest-servers/examples.md +0 -893
  28. package/build/templates/claude-skills/generating-nest-servers/framework-guide.md +0 -259
  29. package/build/templates/claude-skills/generating-nest-servers/quality-review.md +0 -864
  30. package/build/templates/claude-skills/generating-nest-servers/reference.md +0 -487
  31. package/build/templates/claude-skills/generating-nest-servers/security-rules.md +0 -371
  32. package/build/templates/claude-skills/generating-nest-servers/verification-checklist.md +0 -262
  33. package/build/templates/claude-skills/generating-nest-servers/workflow-process.md +0 -1061
  34. package/build/templates/claude-skills/using-lt-cli/SKILL.md +0 -284
  35. package/build/templates/claude-skills/using-lt-cli/examples.md +0 -546
  36. package/build/templates/claude-skills/using-lt-cli/reference.md +0 -513
@@ -1,864 +0,0 @@
1
- ---
2
- name: nest-server-generator-quality-review
3
- version: 1.0.0
4
- description: Comprehensive quality review guidelines before creating final report
5
- ---
6
-
7
- # Phase 8: Pre-Report Quality Review
8
-
9
- ## Table of Contents
10
- - [Step 1: Identify All Changes](#step-1-identify-all-changes)
11
- - [Step 2: Test Management](#step-2-test-management)
12
- - [Step 3: Compare with Existing Code](#step-3-compare-with-existing-code)
13
- - [Step 4: Critical Analysis](#step-4-critical-analysis)
14
- - [Step 5: Automated Optimizations](#step-5-automated-optimizations)
15
- - [Step 6: Pre-Report Testing](#step-6-pre-report-testing)
16
- - [Step 7: Final Verification](#step-7-final-verification)
17
-
18
- **CRITICAL**: Before creating the final report, you MUST perform a comprehensive quality review:
19
-
20
- ## Step 1: Identify All Changes
21
-
22
- Use git to identify all created and modified files:
23
-
24
- ```bash
25
- git status --short
26
- git diff --name-only
27
- ```
28
-
29
- For each file, review:
30
- - All newly created files
31
- - All modified files
32
- - File structure and organization
33
-
34
- ## Step 2: Test Management
35
-
36
- **CRITICAL**: Ensure tests are created/updated for all changes:
37
-
38
- ### Step 2.1: Analyze Existing Tests FIRST
39
-
40
- **BEFORE creating or modifying ANY tests, you MUST thoroughly analyze existing tests**:
41
-
42
- 1. **Identify all existing test files**:
43
- ```bash
44
- # List all test directories and files
45
- ls -la tests/
46
- ls -la tests/modules/
47
- find tests -name "*.e2e-spec.ts" -type f
48
- ```
49
-
50
- 2. **Read multiple existing test files completely**:
51
- ```bash
52
- # Read at least 2-3 different module tests to understand patterns
53
- cat tests/modules/user.e2e-spec.ts
54
- cat tests/modules/<another-module>.e2e-spec.ts
55
-
56
- # Also check the common and project test files
57
- cat tests/common.e2e-spec.ts
58
- cat tests/project.e2e-spec.ts
59
- ```
60
-
61
- 3. **CRITICAL: Understand the TestHelper thoroughly**:
62
-
63
- **Before creating any tests, you MUST understand the TestHelper from @lenne.tech/nest-server**:
64
-
65
- ```bash
66
- # Read the TestHelper source code to understand its capabilities
67
- cat node_modules/@lenne.tech/nest-server/src/test/test.helper.ts
68
- ```
69
-
70
- **Analyze the TestHelper to understand**:
71
- - **Available methods**: What methods does TestHelper provide?
72
- - **Configuration options**: How can TestHelper be configured?
73
- - **GraphQL support**: How to use `graphQl()` method? What parameters does it accept?
74
- - **REST support**: How to use `rest()` method? What parameters does it accept?
75
- - **Authentication**: How does TestHelper handle tokens and authentication?
76
- - **Request building**: How are requests constructed? What options are available?
77
- - **Response handling**: How are responses processed? What format is returned?
78
- - **Error handling**: How does TestHelper handle errors and failures?
79
- - **Helper utilities**: What additional utilities are available?
80
-
81
- **Document your findings**:
82
- ```typescript
83
- // Example: Understanding TestHelper.graphQl()
84
- // Method signature: graphQl(options: GraphQLOptions, config?: RequestConfig)
85
- // GraphQLOptions: { name, type (QUERY/MUTATION), arguments, fields }
86
- // RequestConfig: { token, statusCode, headers }
87
- // Returns: Parsed response data or error
88
-
89
- // Example: Understanding TestHelper.rest()
90
- // Method signature: rest(method: HttpMethod, path: string, options?: RestOptions)
91
- // HttpMethod: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
92
- // RestOptions: { body, token, statusCode, headers }
93
- // Returns: Response data or error
94
- ```
95
-
96
- **Common TestHelper patterns to understand**:
97
- - How to execute GraphQL queries/mutations with `graphQl()`
98
- - How to execute REST requests with `rest()`
99
- - How to pass authentication tokens (same for both methods)
100
- - How to handle expected errors (statusCode parameter)
101
- - How to work with response data
102
- - How to structure test data
103
- - When to use GraphQL vs REST methods
104
-
105
- **Only after fully understanding TestHelper, proceed to next step.**
106
-
107
- 4. **Understand the testing approach used**:
108
- - Which test framework? (Jest, Mocha, etc.)
109
- - Which testing utilities? (@lenne.tech/nest-server testHelper, custom helpers)
110
- - How is the test app initialized? (beforeAll setup)
111
- - How are test users/auth handled?
112
- - How is test data created and cleaned up?
113
- - What assertion library? (expect, should, etc.)
114
- - Are there custom matchers?
115
-
116
- 5. **Document the patterns you observe**:
117
- - **Import patterns**: Which modules are imported? In what order?
118
- - **Setup patterns**: How is beforeAll/beforeEach structured?
119
- - **Auth patterns**: How do tests authenticate? Token handling?
120
- - **Test structure**: Describe blocks organization? Test naming conventions?
121
- - **CRUD patterns**: How are create/read/update/delete tested?
122
- - **Assertion patterns**: What assertions are used? How detailed?
123
- - **Cleanup patterns**: How is afterAll/afterEach structured?
124
- - **Error testing**: How are failures/validations tested?
125
-
126
- 6. **Verify existing tests run successfully**:
127
- ```bash
128
- # Run existing tests to ensure they pass
129
- npm run test:e2e
130
-
131
- # If any fail, understand why before proceeding
132
- # Your new/modified tests MUST NOT break existing tests
133
- ```
134
-
135
- 7. **Create a mental checklist**:
136
- - [ ] I have read and understand the TestHelper source code
137
- - [ ] I understand TestHelper methods and configuration
138
- - [ ] I understand how to use graphQl() method (GraphQL queries/mutations)
139
- - [ ] I understand how to use rest() method (REST endpoints)
140
- - [ ] I understand when to use graphQl() vs rest()
141
- - [ ] I understand TestHelper authentication and error handling
142
- - [ ] I understand which test helpers/utilities are used
143
- - [ ] I understand the authentication/authorization pattern
144
- - [ ] I understand the test data lifecycle (create/cleanup)
145
- - [ ] I understand the assertion patterns
146
- - [ ] I understand the error testing approach
147
- - [ ] All existing tests pass before I make changes
148
-
149
- **Only after completing this analysis, proceed to create or modify tests.**
150
-
151
- ### Step 2.1.1: Understanding Permissions and User Rights in Tests
152
-
153
- **CRITICAL**: Before creating tests, you MUST understand the 3-layer permission system:
154
-
155
- **Important Definitions**:
156
-
157
- - **Admin User**: A user whose `roles` array contains `'admin'`
158
- ```typescript
159
- // Example admin user
160
- {
161
- id: '123',
162
- email: 'admin@test.com',
163
- roles: ['admin', 'user'] // ← Contains 'admin'
164
- }
165
- ```
166
-
167
- - **Creator**: The user who created an object, identified by matching IDs
168
- ```typescript
169
- // User who created the object
170
- const user = { id: 'user-123', email: 'creator@test.com' };
171
-
172
- // Object created by this user
173
- const product = {
174
- id: 'product-456',
175
- name: 'Test Product',
176
- createdBy: 'user-123' // ← Matches user.id → This user is the CREATOR
177
- };
178
-
179
- // Different user (NOT the creator)
180
- const otherUser = { id: 'user-789', email: 'other@test.com' };
181
- // otherUser.id !== product.createdBy → NOT the creator!
182
- ```
183
-
184
- **The Three Permission Layers**:
185
-
186
- 1. **Controller/Resolver Layer** (`@Roles()` decorator):
187
- - Controls WHO can call the endpoint
188
- - Example: `@Roles(RoleEnum.ADMIN)` → Only admins can call this endpoint
189
- - Example: `@Roles(RoleEnum.S_USER)` → All signed-in users can call
190
-
191
- 2. **Service Layer** (`serviceOptions.roles` parameter):
192
- - Controls what permissions are checked during service processing
193
- - Example: Update/Delete often require `[RoleEnum.ADMIN, RoleEnum.S_CREATOR]`
194
- - The creator can update/delete their own items
195
-
196
- 3. **Model Layer** (`securityCheck()` method):
197
- - Controls WHAT data is returned to the user
198
- - Standard implementation:
199
- ```typescript
200
- securityCheck(user: User, force?: boolean) {
201
- // Admins see everything (user.roles contains 'admin')
202
- if (force || user?.hasRole(RoleEnum.ADMIN)) {
203
- return this;
204
- }
205
- // Only creator can see their own data (user.id === this.createdBy)
206
- if (!equalIds(user, this.createdBy)) {
207
- return undefined; // Non-creator gets nothing!
208
- }
209
- return this;
210
- }
211
- ```
212
- - **Key checks**:
213
- - `user?.hasRole(RoleEnum.ADMIN)` → Returns `true` if `user.roles.includes('admin')`
214
- - `equalIds(user, this.createdBy)` → Returns `true` if `user.id === this.createdBy`
215
-
216
- **Default Permission Behavior**:
217
- - **Create**: Usually accessible to signed-in users (`RoleEnum.S_USER`)
218
- - **Read/List**: Usually accessible to signed-in users, but securityCheck filters results
219
- - **Update**: Only ADMIN or CREATOR (via `serviceOptions.roles` check)
220
- - **Delete**: Only ADMIN or CREATOR (via `serviceOptions.roles` check)
221
-
222
- **Analyzing Permissions Before Creating Tests**:
223
-
224
- Before writing tests, check these 3 locations:
225
-
226
- 1. **Check Controller/Resolver decorators**:
227
- ```typescript
228
- // In product.resolver.ts
229
- @Roles(RoleEnum.ADMIN) // ← WHO can call this?
230
- @Query(() => Product)
231
- async getProduct(@Args('id') id: string) { ... }
232
-
233
- @Roles(RoleEnum.S_USER) // ← All signed-in users
234
- @Mutation(() => Product)
235
- async createProduct(@Args('input') input: ProductCreateInput) { ... }
236
- ```
237
-
238
- 2. **Check Model/Object `@Restricted` decorators**:
239
- ```typescript
240
- // In product.model.ts
241
- @Restricted(RoleEnum.ADMIN) // ← Model-level restriction
242
- export class Product extends CoreModel {
243
-
244
- @Restricted(RoleEnum.ADMIN) // ← Property-level restriction
245
- @UnifiedField()
246
- internalNotes?: string;
247
- }
248
- ```
249
-
250
- 3. **Check Model `securityCheck()` logic**:
251
- ```typescript
252
- // In product.model.ts
253
- securityCheck(user: User, force?: boolean) {
254
- // Admin check: user.roles contains 'admin'
255
- if (force || user?.hasRole(RoleEnum.ADMIN)) {
256
- return this; // Admin sees all
257
- }
258
-
259
- // Custom logic: Allow public products for everyone
260
- if (this.isPublic) {
261
- return this;
262
- }
263
-
264
- // Creator check: user.id === this.createdBy
265
- if (!equalIds(user, this.createdBy)) {
266
- return undefined; // Non-creator gets nothing
267
- }
268
- return this; // Creator sees their own product
269
- }
270
- ```
271
-
272
- **Creating Appropriate Test Users**:
273
-
274
- Based on permission analysis, create appropriate test users:
275
-
276
- ```typescript
277
- describe('Product Module', () => {
278
- let testHelper: TestHelper;
279
- let adminToken: string;
280
- let userToken: string;
281
- let otherUserToken: string;
282
- let createdProductId: string;
283
-
284
- beforeAll(async () => {
285
- testHelper = new TestHelper(app);
286
-
287
- // Admin user (user.roles contains 'admin')
288
- const adminAuth = await testHelper.graphQl({
289
- name: 'signIn',
290
- type: TestGraphQLType.MUTATION,
291
- arguments: { email: 'admin@test.com', password: 'admin' },
292
- fields: ['token', 'user { id email roles }']
293
- });
294
- adminToken = adminAuth.token;
295
- // adminAuth.user.roles = ['admin', 'user'] ← Contains 'admin'
296
-
297
- // Regular user (will be the creator of test objects)
298
- const userAuth = await testHelper.graphQl({
299
- name: 'signIn',
300
- type: TestGraphQLType.MUTATION,
301
- arguments: { email: 'user@test.com', password: 'user' },
302
- fields: ['token', 'user { id email roles }']
303
- });
304
- userToken = userAuth.token;
305
- // When this user creates an object → object.createdBy = userAuth.user.id
306
-
307
- // Another regular user (will NOT be the creator)
308
- const otherUserAuth = await testHelper.graphQl({
309
- name: 'signIn',
310
- type: TestGraphQLType.MUTATION,
311
- arguments: { email: 'other@test.com', password: 'other' },
312
- fields: ['token', 'user { id email roles }']
313
- });
314
- otherUserToken = otherUserAuth.token;
315
- // otherUserAuth.user.id !== object.createdBy → NOT the creator
316
- });
317
- });
318
- ```
319
-
320
- **Test Structure Based on Permissions**:
321
-
322
- ```typescript
323
- describe('Product Module', () => {
324
- // ... setup with adminToken, userToken, otherUserToken
325
-
326
- describe('Create Product', () => {
327
- it('should create product as regular user', async () => {
328
- const result = await testHelper.graphQl({
329
- name: 'createProduct',
330
- type: TestGraphQLType.MUTATION,
331
- arguments: { input: { name: 'Test Product', price: 99.99 } },
332
- fields: ['id', 'name', 'createdBy { id }']
333
- }, { token: userToken }); // ← Created by userToken
334
-
335
- expect(result.name).toBe('Test Product');
336
- // result.createdBy.id now equals userAuth.user.id
337
- // → userToken is the CREATOR of this product
338
- createdProductId = result.id;
339
- });
340
- });
341
-
342
- describe('Update Product', () => {
343
- it('should update product as creator', async () => {
344
- const result = await testHelper.graphQl({
345
- name: 'updateProduct',
346
- type: TestGraphQLType.MUTATION,
347
- arguments: {
348
- id: createdProductId,
349
- input: { price: 89.99 }
350
- },
351
- fields: ['id', 'price']
352
- }, { token: userToken }); // ← Creator: userAuth.user.id === product.createdBy
353
-
354
- expect(result.price).toBe(89.99);
355
- });
356
-
357
- it('should update product as admin', async () => {
358
- const result = await testHelper.graphQl({
359
- name: 'updateProduct',
360
- type: TestGraphQLType.MUTATION,
361
- arguments: {
362
- id: createdProductId,
363
- input: { price: 79.99 }
364
- },
365
- fields: ['id', 'price']
366
- }, { token: adminToken }); // ← Admin: adminAuth.user.roles contains 'admin'
367
-
368
- expect(result.price).toBe(79.99);
369
- });
370
-
371
- it('should fail to update product as non-creator', async () => {
372
- const result = await testHelper.graphQl({
373
- name: 'updateProduct',
374
- type: TestGraphQLType.MUTATION,
375
- arguments: {
376
- id: createdProductId,
377
- input: { price: 69.99 }
378
- },
379
- fields: ['id']
380
- }, { token: otherUserToken, statusCode: 403 }); // ← Not creator: otherUserAuth.user.id !== product.createdBy
381
-
382
- expect(result.errors).toBeDefined();
383
- });
384
- });
385
-
386
- describe('Delete Product', () => {
387
- it('should delete product as creator', async () => {
388
- // First create a new product to delete
389
- const created = await testHelper.graphQl({
390
- name: 'createProduct',
391
- type: TestGraphQLType.MUTATION,
392
- arguments: { input: { name: 'To Delete', price: 50 } },
393
- fields: ['id']
394
- }, { token: userToken });
395
-
396
- // Delete as creator
397
- const result = await testHelper.graphQl({
398
- name: 'deleteProduct',
399
- type: TestGraphQLType.MUTATION,
400
- arguments: { id: created.id },
401
- fields: ['id']
402
- }, { token: userToken }); // ← Creator: userAuth.user.id === created.createdBy
403
-
404
- expect(result.id).toBe(created.id);
405
- });
406
-
407
- it('should fail to delete product as non-creator', async () => {
408
- const result = await testHelper.graphQl({
409
- name: 'deleteProduct',
410
- type: TestGraphQLType.MUTATION,
411
- arguments: { id: createdProductId },
412
- fields: ['id']
413
- }, { token: otherUserToken, statusCode: 403 }); // ← Not creator: otherUserAuth.user.id !== product.createdBy
414
-
415
- expect(result.errors).toBeDefined();
416
- });
417
-
418
- it('should delete any product as admin', async () => {
419
- const result = await testHelper.graphQl({
420
- name: 'deleteProduct',
421
- type: TestGraphQLType.MUTATION,
422
- arguments: { id: createdProductId },
423
- fields: ['id']
424
- }, { token: adminToken }); // ← Admin: adminAuth.user.roles contains 'admin'
425
-
426
- expect(result.id).toBe(createdProductId);
427
- });
428
- });
429
- });
430
- ```
431
-
432
- **Permission Testing Checklist**:
433
-
434
- Before creating tests, verify:
435
-
436
- - [ ] I have checked the `@Roles()` decorators in controllers/resolvers
437
- - [ ] I have checked the `@Restricted()` decorators in models/objects
438
- - [ ] I have reviewed the `securityCheck()` logic in models
439
- - [ ] I understand who can CREATE items (usually S_USER)
440
- - [ ] I understand who can READ items (S_USER + securityCheck filtering)
441
- - [ ] I understand who can UPDATE items (usually ADMIN + S_CREATOR)
442
- - [ ] I understand who can DELETE items (usually ADMIN + S_CREATOR)
443
- - [ ] I have created appropriate test users (admin, creator, non-creator)
444
- - [ ] My tests use the CREATOR token (user.id === object.createdBy) for update/delete operations
445
- - [ ] My tests verify that non-creators (user.id !== object.createdBy) CANNOT update/delete
446
- - [ ] My tests verify that admins (user.roles contains 'admin') CAN update/delete everything
447
-
448
- **Common Permission Test Patterns**:
449
-
450
- 1. **Test with creator** (user.id === object.createdBy) → Should succeed
451
- 2. **Test with admin** (user.roles contains 'admin') → Should succeed
452
- 3. **Test with other user** (user.id !== object.createdBy) → Should fail (403)
453
-
454
- **Only after understanding permissions, proceed to create tests.**
455
-
456
- ### Step 2.2: For Newly Created Modules
457
-
458
- **CRITICAL: Follow the correct test folder structure**:
459
-
460
- The project uses a specific test organization:
461
-
462
- 1. **Module tests** (for modules in `src/server/modules/`):
463
- ```
464
- tests/modules/<module-name>.e2e-spec.ts
465
- ```
466
- - Each module gets its own test file directly in `tests/modules/`
467
- - Examples: `tests/modules/user.e2e-spec.ts`, `tests/modules/book.e2e-spec.ts`
468
-
469
- 2. **Common tests** (for common functionality in `src/server/common/`):
470
- ```
471
- tests/common.e2e-spec.ts
472
- ```
473
- - All common functionality (enums, objects, helpers) tested here
474
- - Single file for all common-related tests
475
-
476
- 3. **Project tests** (for everything else - root level, config, etc.):
477
- ```
478
- tests/project.e2e-spec.ts
479
- ```
480
- - General project-level tests
481
- - Configuration tests
482
- - Integration tests
483
-
484
- **Determine correct test location**:
485
-
486
- ```bash
487
- # BEFORE creating a test, ask yourself:
488
- # - Is this a module in src/server/modules/? → tests/modules/<name>.e2e-spec.ts
489
- # - Is this common functionality? → Add to tests/common.e2e-spec.ts
490
- # - Is this project-level? → Add to tests/project.e2e-spec.ts
491
-
492
- # Check existing test structure to confirm:
493
- ls -la tests/
494
- ls tests/modules/
495
- ```
496
-
497
- **Create new test files** for modules following the patterns you identified:
498
-
499
- ```bash
500
- # For a new module (e.g., Book)
501
- tests/modules/book.e2e-spec.ts
502
- ```
503
-
504
- **IMPORTANT**: Your new test file MUST:
505
- 1. **Match the exact structure** of existing test files
506
- 2. **Use the same imports** as existing tests
507
- 3. **Follow the same setup/cleanup pattern** (beforeAll, afterAll)
508
- 4. **Use the same test helpers/utilities** you observed
509
- 5. **Follow the same authentication pattern**
510
- 6. **Use the same assertion style**
511
- 7. **Follow the same naming conventions** for describe/it blocks
512
-
513
- **Each new test file must include**:
514
- 1. All CRUD operations (create, find all, find by ID, update, delete)
515
- 2. Authorization tests (unauthorized should fail, authorized should succeed)
516
- 3. Required field validation (missing required fields should fail)
517
- 4. Proper test data setup and cleanup (beforeAll, afterAll)
518
- 5. Tests for any custom methods or relationships
519
-
520
- **Ensure all prerequisites are met by analyzing existing tests**:
521
-
522
- Before writing test code, identify ALL prerequisites from existing test files:
523
-
524
- ```bash
525
- # Read an existing module test to understand prerequisites
526
- cat tests/modules/user.e2e-spec.ts
527
- ```
528
-
529
- **Common prerequisites to check**:
530
- 1. **Test data dependencies**:
531
- - Does the module reference other modules? (e.g., Book → User for borrowedBy)
532
- - Do you need to create related test data first?
533
- - Example: To test Book with borrowedBy: User, create test User first
534
-
535
- 2. **Authentication requirements**:
536
- - What roles/permissions are needed?
537
- - Do test users need to be created with specific roles?
538
- - Example: Admin user for create operations, regular user for read operations
539
-
540
- 3. **Database setup**:
541
- - Are there database constraints or required collections?
542
- - Do embedded objects or enums need to exist?
543
-
544
- 4. **Configuration**:
545
- - Are environment variables or config values needed?
546
- - Example: JWT secrets, database connections
547
-
548
- **Pattern from existing tests**:
549
- ```typescript
550
- // Example structure you should follow:
551
- beforeAll(async () => {
552
- // 1. Initialize test app/module
553
- // 2. Set up database connection
554
- // 3. Create prerequisite test data (users, roles, etc.)
555
- // 4. Authenticate and get tokens
556
- });
557
-
558
- describe('Module Tests', () => {
559
- // Tests here
560
- });
561
-
562
- afterAll(async () => {
563
- // 1. Delete created test data (in reverse order)
564
- // 2. Clean up connections
565
- // 3. Close app
566
- });
567
- ```
568
-
569
- **CRITICAL**: Look at how existing tests handle prerequisites and replicate the exact same approach.
570
-
571
- ### Step 2.3: For Modified Existing Modules
572
-
573
- **Update existing test files** when you modify modules:
574
-
575
- 1. **FIRST: Read the existing test file completely**:
576
- ```bash
577
- # Find and read the test file for the module you modified
578
- find tests -name "*<module-name>*.e2e-spec.ts"
579
- cat tests/modules/<module-name>.e2e-spec.ts
580
- ```
581
-
582
- 2. **Understand what the existing tests cover**:
583
- - Which operations are tested?
584
- - Which properties are validated?
585
- - What edge cases are covered?
586
- - How is test data structured?
587
-
588
- 3. **Run existing tests to ensure they pass BEFORE your changes**:
589
- ```bash
590
- npm run test:e2e
591
- ```
592
-
593
- 4. **Review and update tests**:
594
- - **Added properties**: Add tests verifying new properties work correctly
595
- - **Changed validation**: Update tests to reflect new validation rules
596
- - **Added relationships**: Add tests for new references/embedded objects
597
- - **Changed required fields**: Update CreateInput tests accordingly
598
- - **Removed properties**: Remove related test assertions
599
-
600
- 5. **Verify test coverage**:
601
- - All new properties are tested
602
- - Changed behavior is verified
603
- - Edge cases are covered
604
- - Authorization still works correctly
605
-
606
- 6. **Run tests again to ensure your changes don't break anything**:
607
- ```bash
608
- npm run test:e2e
609
- ```
610
-
611
- ## Step 3: Compare with Existing Code
612
-
613
- **Compare generated code with existing project code**:
614
-
615
- 1. **Read existing similar modules** to understand project patterns:
616
- ```bash
617
- # Example: If you created a User module, check existing modules
618
- ls src/server/modules/
619
- ```
620
-
621
- 2. **Check for consistency**:
622
- - Code style (indentation, spacing, formatting)
623
- - Import ordering and organization
624
- - Naming conventions (camelCase, PascalCase, kebab-case)
625
- - File structure and directory organization
626
- - Comment style and documentation
627
- - Decorator usage (@Field, @Prop, etc.)
628
- - Error handling patterns
629
- - Validation patterns
630
-
631
- 3. **Review property ordering**:
632
- - Verify alphabetical order in models
633
- - Verify alphabetical order in inputs
634
- - Verify alphabetical order in outputs
635
- - Check decorator consistency
636
-
637
- ## Step 4: Critical Analysis
638
-
639
- **Analyze each file critically**:
640
-
641
- 1. **Style consistency**:
642
- - Does the code match the project's existing style?
643
- - Are imports grouped and ordered correctly?
644
- - Is indentation consistent with the project?
645
- - Are naming conventions followed?
646
-
647
- 2. **Structural consistency**:
648
- - Are decorators in the same order as existing code?
649
- - Is the file structure identical to existing modules?
650
- - Are descriptions formatted the same way?
651
- - Are relationships implemented consistently?
652
-
653
- 3. **Code quality**:
654
- - Are there any redundant imports?
655
- - Are there any missing imports?
656
- - Are descriptions meaningful and complete?
657
- - Are TypeScript types correctly used?
658
-
659
- 4. **Best practices**:
660
- - Are required fields properly marked?
661
- - Are nullable fields correctly configured?
662
- - Are references properly typed?
663
- - Are arrays correctly configured?
664
-
665
- ## Step 5: Automated Optimizations
666
-
667
- **Apply automatic improvements**:
668
-
669
- 1. **Fix import ordering**:
670
- - External imports first (alphabetically)
671
- - @lenne.tech/nest-server imports next
672
- - Local imports last (alphabetically by path depth)
673
-
674
- 2. **Fix property ordering**:
675
- - Reorder all properties alphabetically in models
676
- - Reorder all properties alphabetically in inputs
677
- - Reorder all properties alphabetically in outputs
678
-
679
- 3. **Fix formatting**:
680
- - Ensure consistent indentation
681
- - Remove extra blank lines
682
- - Add missing blank lines between sections
683
-
684
- 4. **Fix descriptions**:
685
- - Ensure all follow "ENGLISH (DEUTSCH)" format
686
- - Add missing descriptions
687
- - Improve unclear descriptions
688
-
689
- 5. **Fix common patterns**:
690
- - Standardize decorator usage
691
- - Standardize validation patterns
692
- - Standardize error handling
693
-
694
- ## Step 6: Pre-Report Testing
695
-
696
- **MANDATORY**: Run all tests before reporting:
697
-
698
- ```bash
699
- # Run TypeScript compilation
700
- npm run build
701
-
702
- # Run linting
703
- npm run lint
704
-
705
- # Run all tests
706
- npm run test:e2e
707
-
708
- # If any fail, fix issues and repeat
709
- ```
710
-
711
- **If tests fail**:
712
- 1. Analyze the error
713
- 2. Fix the issue
714
- 3. Re-run tests
715
- 4. Repeat until all tests pass
716
-
717
- ### Debugging Failed Tests - Important Guidelines
718
-
719
- **When tests fail, use systematic debugging with console.log statements:**
720
-
721
- 1. **Add debug messages in Controllers/Resolvers**:
722
- ```typescript
723
- // In controller/resolver - BEFORE service call
724
- console.log('🔵 [Controller] createProduct - Input:', input);
725
- console.log('🔵 [Controller] createProduct - User:', serviceOptions?.user);
726
-
727
- const result = await this.productService.create(input, serviceOptions);
728
-
729
- // AFTER service call
730
- console.log('🔵 [Controller] createProduct - Result:', result);
731
- ```
732
-
733
- 2. **Add debug messages in Services**:
734
- ```typescript
735
- // In service method
736
- console.log('🟢 [Service] create - Input:', input);
737
- console.log('🟢 [Service] create - ServiceOptions:', serviceOptions);
738
-
739
- const created = await super.create(input, serviceOptions);
740
-
741
- console.log('🟢 [Service] create - Created:', created);
742
- ```
743
-
744
- 3. **Understand the permissions system**:
745
- - **Controllers/Resolvers**: `@Roles()` decorator controls WHO can call the endpoint
746
- - **Services**: `serviceOptions.roles` controls what the service checks during processing
747
- - **Models**: `securityCheck()` method determines what data is returned to the user
748
-
749
- 4. **Default permission behavior**:
750
- - Only **Admin users** (user.roles contains 'admin') OR the **creator** (user.id === object.createdBy) of an element can access it
751
- - This is enforced in the `securityCheck()` method in models:
752
- ```typescript
753
- securityCheck(user: User, force?: boolean) {
754
- // Admin: user.roles contains 'admin'
755
- if (force || user?.hasRole(RoleEnum.ADMIN)) {
756
- return this; // Admin sees everything
757
- }
758
- // Creator: user.id === this.createdBy
759
- if (!equalIds(user, this.createdBy)) {
760
- return undefined; // Non-creator (user.id !== this.createdBy) gets nothing
761
- }
762
- return this; // Creator sees their own data
763
- }
764
- ```
765
-
766
- 5. **Debugging strategy for permission issues**:
767
-
768
- **Step 1**: Run failing test with Admin user first
769
- ```typescript
770
- // In test setup
771
- const adminToken = await testHelper.signIn('admin@test.com', 'admin-password');
772
-
773
- // Use admin token in test
774
- const result = await testHelper.graphQl({...}, { token: adminToken });
775
- ```
776
-
777
- **Step 2**: Analyze results
778
- - ✅ **Works with Admin, fails with normal user** → Permission issue (check Roles, securityCheck)
779
- - ❌ **Fails with Admin too** → Different issue (check logic, data, validation)
780
-
781
- 6. **Common permission issues and solutions**:
782
-
783
- | Problem | Cause | Solution |
784
- |---------|-------|----------|
785
- | 401/403 on endpoint | `@Roles()` too restrictive | Adjust decorator in controller/resolver |
786
- | Empty result despite data existing | `securityCheck()` returns undefined | Modify securityCheck logic or use Admin |
787
- | Service throws permission error | `serviceOptions.roles` check fails | Pass correct roles in serviceOptions |
788
-
789
- 7. **Remove debug messages after fixing**:
790
- ```bash
791
- # After tests pass, remove all console.log statements
792
- # Search for debug patterns
793
- grep -r "console.log" src/server/modules/your-module/
794
-
795
- # Remove them manually or with sed
796
- # Then verify tests still pass
797
- npm run test:e2e
798
- ```
799
-
800
- **Debugging workflow example**:
801
- ```typescript
802
- // 1. Test fails - add debugging
803
- @Mutation(() => Product)
804
- async createProduct(@Args('input') input: ProductCreateInput, @GraphQLServiceOptions() opts) {
805
- console.log('🔵 START createProduct', { input, user: opts?.user?.email });
806
-
807
- const result = await this.productService.create(input, opts);
808
-
809
- console.log('🔵 END createProduct', { result: result?.id });
810
- return result;
811
- }
812
-
813
- // In service
814
- async create(input: ProductCreateInput, serviceOptions?: ServiceOptions) {
815
- console.log('🟢 Service create', { input, user: serviceOptions?.user?.email });
816
-
817
- const created = await super.create(input, serviceOptions);
818
-
819
- console.log('🟢 Service created', { id: created?.id, createdBy: created?.createdBy });
820
- return created;
821
- }
822
-
823
- // 2. Run test - observe output:
824
- // 🔵 START createProduct { input: {...}, user: 'test@test.com' }
825
- // 🟢 Service create { input: {...}, user: 'test@test.com' }
826
- // 🟢 Service created { id: '123', createdBy: '456' }
827
- // 🔵 END createProduct { result: undefined } ← AHA! Result is undefined!
828
-
829
- // 3. Check model securityCheck() - likely returns undefined for non-creator (user.id !== object.createdBy)
830
- // 4. Fix: Either use Admin user (user.roles contains 'admin') or adjust securityCheck logic
831
- // 5. Test passes → Remove console.log statements
832
- // 6. Verify tests still pass
833
- ```
834
-
835
- **Do not proceed to final report if**:
836
- - TypeScript compilation fails
837
- - Linting fails
838
- - Any tests fail
839
- - Console shows errors or warnings
840
-
841
- ## Step 7: Final Verification
842
-
843
- Before reporting, verify:
844
-
845
- - [ ] All files compared with existing code
846
- - [ ] Code style matches project patterns
847
- - [ ] All imports properly ordered
848
- - [ ] All properties in alphabetical order
849
- - [ ] All descriptions follow format
850
- - [ ] **TestHelper source code read and understood**
851
- - [ ] **TestHelper methods and configuration understood**
852
- - [ ] **Existing tests analyzed BEFORE creating/modifying tests**
853
- - [ ] **Existing tests passed BEFORE making changes**
854
- - [ ] **Tests in correct location (tests/modules/<name>.e2e-spec.ts, tests/common.e2e-spec.ts, or tests/project.e2e-spec.ts)**
855
- - [ ] **New test files created for all new modules**
856
- - [ ] **Existing test files updated for all modified modules**
857
- - [ ] **All prerequisites identified and handled (test data dependencies, auth, etc.)**
858
- - [ ] **All new/modified tests follow exact patterns from existing tests**
859
- - [ ] TypeScript compiles without errors
860
- - [ ] Linter passes without warnings
861
- - [ ] **All tests pass AFTER changes**
862
- - [ ] No console errors or warnings
863
-
864
- **Only after ALL checks pass, proceed to Final Report.**