@lenne.tech/cli 0.0.124 → 1.0.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 (30) hide show
  1. package/bin/lt +145 -14
  2. package/build/commands/claude/claude.js +25 -0
  3. package/build/commands/claude/install-skills.js +622 -0
  4. package/build/commands/config/config.js +25 -0
  5. package/build/commands/config/help.js +167 -0
  6. package/build/commands/config/init.js +143 -0
  7. package/build/commands/config/show.js +68 -0
  8. package/build/commands/fullstack/init.js +38 -16
  9. package/build/commands/server/add-property.js +199 -36
  10. package/build/commands/server/create.js +66 -4
  11. package/build/commands/server/module.js +150 -27
  12. package/build/commands/server/object.js +38 -22
  13. package/build/extensions/config.js +157 -0
  14. package/build/extensions/parse-properties.js +119 -0
  15. package/build/extensions/server.js +82 -47
  16. package/build/interfaces/lt-config.interface.js +3 -0
  17. package/build/templates/claude-skills/lt-cli/SKILL.md +272 -0
  18. package/build/templates/claude-skills/lt-cli/examples.md +542 -0
  19. package/build/templates/claude-skills/lt-cli/reference.md +506 -0
  20. package/build/templates/claude-skills/nest-server-generator/SKILL.md +2833 -0
  21. package/build/templates/claude-skills/nest-server-generator/examples.md +760 -0
  22. package/build/templates/claude-skills/nest-server-generator/reference.md +417 -0
  23. package/build/templates/nest-server-module/inputs/template-create.input.ts.ejs +1 -3
  24. package/build/templates/nest-server-module/inputs/template.input.ts.ejs +1 -1
  25. package/build/templates/nest-server-module/template.controller.ts.ejs +24 -13
  26. package/build/templates/nest-server-module/template.model.ts.ejs +2 -2
  27. package/build/templates/nest-server-module/template.module.ts.ejs +4 -0
  28. package/build/templates/nest-server-module/template.service.ts.ejs +6 -6
  29. package/build/templates/nest-server-object/template.object.ts.ejs +2 -2
  30. package/package.json +13 -11
@@ -0,0 +1,760 @@
1
+ ---
2
+ name: nest-server-generator-examples
3
+ version: 1.0.0
4
+ description: Complete examples for generating NestJS server structures from specifications
5
+ ---
6
+
7
+ # NestJS Server Generator Examples
8
+
9
+ ## Example 1: Library Management System
10
+
11
+ This example demonstrates all features:
12
+ - SubObjects (embedded data)
13
+ - Objects (base models)
14
+ - Modules with inheritance
15
+ - ENUMs
16
+ - Arrays
17
+ - Optional properties
18
+ - References between modules
19
+ - German/English descriptions
20
+
21
+ ### Complete Specification
22
+
23
+ ```
24
+ ===========
25
+
26
+ SubObject: Author // Author information
27
+ - firstName: string // First name
28
+ - lastName: string // Last name
29
+ - birthDate?: Date // Date of birth
30
+ - nationality?: string // Nationality
31
+
32
+ ===
33
+
34
+ SubObject: Publisher // Publisher details
35
+ - name: string // Publisher name
36
+ - city: string // City
37
+ - country: string // Country
38
+ - foundedYear?: number // Year founded
39
+
40
+ ===
41
+
42
+ SubObject: Review // Book review
43
+ - rating: number // Rating (1-5)
44
+ - comment?: string // Review comment
45
+ - reviewerName: string // Name of reviewer
46
+ - reviewDate: Date // Review date
47
+
48
+ ===
49
+
50
+ Object: BaseItem // Base library item
51
+ Properties:
52
+ - title: string // Titel
53
+ - description?: string // Beschreibung
54
+ - available: boolean // Verfügbar
55
+ - location: string // Standort
56
+
57
+ ===
58
+
59
+ Module: Book // Book module
60
+
61
+ Model: Book // Buch
62
+ Extends: BaseItem
63
+ - isbn: string // ISBN-Nummer
64
+ - authors: Author[] // Autoren
65
+ - publisher: Publisher // Verlag
66
+ - publishYear: number // Erscheinungsjahr
67
+ - pageCount: number // Seitenzahl
68
+ - language: ENUM (ENGLISH, GERMAN, FRENCH, SPANISH, OTHER) // Sprache
69
+ - genre: ENUM (FICTION, NON_FICTION, SCIENCE, HISTORY, BIOGRAPHY, CHILDREN, FANTASY, MYSTERY, ROMANCE) // Genre
70
+ - coverImage?: string // Cover image URL
71
+ - reviews?: Review[] // Bewertungen
72
+ - borrowedBy?: Member // Current borrower
73
+
74
+ ===
75
+
76
+ Module: Member // Library member module
77
+
78
+ Model: Member // Bibliotheksmitglied
79
+ - memberNumber: string // Mitgliedsnummer
80
+ - firstName: string // Vorname
81
+ - lastName: string // Nachname
82
+ - email: string // E-Mail-Adresse
83
+ - phone?: string // Telefonnummer
84
+ - joinDate: Date // Beitrittsdatum
85
+ - status: ENUM (ACTIVE, SUSPENDED, EXPIRED) // Status
86
+ - currentLoans: Book[] // Currently borrowed books
87
+
88
+ ===
89
+
90
+ Module: Loan // Loan tracking module
91
+
92
+ Model: Loan // Ausleihe
93
+ - member: Member // Mitglied
94
+ - book: Book // Buch
95
+ - loanDate: Date // Ausleihdatum
96
+ - dueDate: Date // Fälligkeitsdatum
97
+ - returnDate?: Date // Rückgabedatum
98
+ - status: ENUM (ACTIVE, OVERDUE, RETURNED, LOST) // Status
99
+ - renewalCount: number // Anzahl der Verlängerungen
100
+ - fine?: number // Gebühr bei Verspätung
101
+
102
+ ===========
103
+ ```
104
+
105
+ ### Generated Commands Sequence
106
+
107
+ #### Step 1: Create SubObjects
108
+
109
+ ```bash
110
+ # Author SubObject
111
+ lt server object --name Author \
112
+ --prop-name-0 birthDate --prop-type-0 Date --prop-nullable-0 true \
113
+ --prop-name-1 firstName --prop-type-1 string \
114
+ --prop-name-2 lastName --prop-type-2 string \
115
+ --prop-name-3 nationality --prop-type-3 string --prop-nullable-3 true
116
+
117
+ # Publisher SubObject
118
+ lt server object --name Publisher \
119
+ --prop-name-0 city --prop-type-0 string \
120
+ --prop-name-1 country --prop-type-1 string \
121
+ --prop-name-2 foundedYear --prop-type-2 number --prop-nullable-2 true \
122
+ --prop-name-3 name --prop-type-3 string
123
+
124
+ # Review SubObject
125
+ lt server object --name Review \
126
+ --prop-name-0 comment --prop-type-0 string --prop-nullable-0 true \
127
+ --prop-name-1 rating --prop-type-1 number \
128
+ --prop-name-2 reviewDate --prop-type-2 Date \
129
+ --prop-name-3 reviewerName --prop-type-3 string
130
+ ```
131
+
132
+ #### Step 2: Create Base Object
133
+
134
+ ```bash
135
+ # BaseItem Object
136
+ lt server object --name BaseItem \
137
+ --prop-name-0 available --prop-type-0 boolean \
138
+ --prop-name-1 description --prop-type-1 string --prop-nullable-1 true \
139
+ --prop-name-2 location --prop-type-2 string \
140
+ --prop-name-3 title --prop-type-3 string
141
+ ```
142
+
143
+ #### Step 3: Create Modules
144
+
145
+ ```bash
146
+ # Member Module (create first as it's referenced by Book)
147
+ lt server module --name Member --controller Both \
148
+ --prop-name-0 email --prop-type-0 string \
149
+ --prop-name-1 firstName --prop-type-1 string \
150
+ --prop-name-2 joinDate --prop-type-2 Date \
151
+ --prop-name-3 lastName --prop-type-3 string \
152
+ --prop-name-4 memberNumber --prop-type-4 string \
153
+ --prop-name-5 phone --prop-type-5 string --prop-nullable-5 true \
154
+ --prop-name-6 status --prop-enum-6 MemberStatusEnum
155
+
156
+ # Book Module (references Member)
157
+ lt server module --name Book --controller Both \
158
+ --prop-name-0 authors --prop-schema-0 Author --prop-array-0 true \
159
+ --prop-name-1 borrowedBy --prop-type-1 ObjectId --prop-reference-1 Member --prop-nullable-1 true \
160
+ --prop-name-2 coverImage --prop-type-2 string --prop-nullable-2 true \
161
+ --prop-name-3 genre --prop-enum-3 BookGenreEnum \
162
+ --prop-name-4 isbn --prop-type-4 string \
163
+ --prop-name-5 language --prop-enum-5 BookLanguageEnum \
164
+ --prop-name-6 pageCount --prop-type-6 number \
165
+ --prop-name-7 publishYear --prop-type-7 number \
166
+ --prop-name-8 publisher --prop-schema-8 Publisher \
167
+ --prop-name-9 reviews --prop-schema-9 Review --prop-array-9 true --prop-nullable-9 true
168
+
169
+ # Add currentLoans to Member (after Book is created)
170
+ lt server addProp --type Module --element Member \
171
+ --prop-name-0 currentLoans --prop-type-0 ObjectId --prop-reference-0 Book --prop-array-0 true
172
+
173
+ # Loan Module (references both Member and Book)
174
+ lt server module --name Loan --controller Both \
175
+ --prop-name-0 book --prop-type-0 ObjectId --prop-reference-0 Book \
176
+ --prop-name-1 dueDate --prop-type-1 Date \
177
+ --prop-name-2 fine --prop-type-2 number --prop-nullable-2 true \
178
+ --prop-name-3 loanDate --prop-type-3 Date \
179
+ --prop-name-4 member --prop-type-4 ObjectId --prop-reference-4 Member \
180
+ --prop-name-5 renewalCount --prop-type-5 number \
181
+ --prop-name-6 returnDate --prop-type-6 Date --prop-nullable-6 true \
182
+ --prop-name-7 status --prop-enum-7 LoanStatusEnum
183
+ ```
184
+
185
+ #### Step 4: Handle Inheritance
186
+
187
+ Manually modify `book.model.ts`:
188
+
189
+ ```typescript
190
+ // Change from:
191
+ import { CoreModel } from '@lenne.tech/nest-server';
192
+ export class Book extends CoreModel { ... }
193
+
194
+ // To:
195
+ import { BaseItem } from '../../common/objects/base-item/base-item.object';
196
+ export class Book extends BaseItem { ... }
197
+ ```
198
+
199
+ Manually update `book.input.ts` and `book-create.input.ts`:
200
+
201
+ ```typescript
202
+ // book-create.input.ts
203
+ // Add required fields from BaseItem:
204
+ // - title (required in BaseItem)
205
+ // - available (required in BaseItem)
206
+ // - location (required in BaseItem)
207
+ // - description (optional in BaseItem)
208
+ ```
209
+
210
+ #### Step 5: Update Descriptions
211
+
212
+ Update all generated files to follow pattern: `"ENGLISH (DEUTSCH)"`:
213
+
214
+ ```typescript
215
+ // Before:
216
+ @UnifiedField({ description: 'ISBN number' })
217
+ isbn: string;
218
+
219
+ // After:
220
+ @UnifiedField({ description: 'ISBN number (ISBN-Nummer)' })
221
+ isbn: string;
222
+ ```
223
+
224
+ #### Step 6: Create Enum Files
225
+
226
+ ```typescript
227
+ // src/server/common/enums/book-language.enum.ts
228
+ export enum BookLanguageEnum {
229
+ ENGLISH = 'ENGLISH',
230
+ GERMAN = 'GERMAN',
231
+ FRENCH = 'FRENCH',
232
+ SPANISH = 'SPANISH',
233
+ OTHER = 'OTHER',
234
+ }
235
+
236
+ // src/server/common/enums/book-genre.enum.ts
237
+ export enum BookGenreEnum {
238
+ FICTION = 'FICTION',
239
+ NON_FICTION = 'NON_FICTION',
240
+ SCIENCE = 'SCIENCE',
241
+ HISTORY = 'HISTORY',
242
+ BIOGRAPHY = 'BIOGRAPHY',
243
+ CHILDREN = 'CHILDREN',
244
+ FANTASY = 'FANTASY',
245
+ MYSTERY = 'MYSTERY',
246
+ ROMANCE = 'ROMANCE',
247
+ }
248
+
249
+ // src/server/common/enums/member-status.enum.ts
250
+ export enum MemberStatusEnum {
251
+ ACTIVE = 'ACTIVE',
252
+ SUSPENDED = 'SUSPENDED',
253
+ EXPIRED = 'EXPIRED',
254
+ }
255
+
256
+ // src/server/common/enums/loan-status.enum.ts
257
+ export enum LoanStatusEnum {
258
+ ACTIVE = 'ACTIVE',
259
+ OVERDUE = 'OVERDUE',
260
+ RETURNED = 'RETURNED',
261
+ LOST = 'LOST',
262
+ }
263
+ ```
264
+
265
+ #### Step 7: Create API Tests
266
+
267
+ ```typescript
268
+ // test/book/book.controller.test.ts
269
+ import { TestHelper, TestGraphQLType } from '@lenne.tech/nest-server';
270
+
271
+ describe('Book Controller', () => {
272
+ let testHelper: TestHelper;
273
+ let adminToken: string;
274
+ let createdBookId: string;
275
+
276
+ beforeAll(async () => {
277
+ testHelper = new TestHelper(app);
278
+
279
+ // Sign in as admin
280
+ const authResult = await testHelper.graphQl({
281
+ name: 'signIn',
282
+ type: TestGraphQLType.MUTATION,
283
+ arguments: { email: 'admin@test.com', password: 'password' },
284
+ fields: ['token']
285
+ });
286
+ adminToken = authResult.token;
287
+ });
288
+
289
+ afterAll(async () => {
290
+ // Clean up created book
291
+ if (createdBookId) {
292
+ await testHelper.graphQl({
293
+ name: 'deleteBook',
294
+ type: TestGraphQLType.MUTATION,
295
+ arguments: { id: createdBookId },
296
+ fields: ['id']
297
+ }, { token: adminToken });
298
+ }
299
+ });
300
+
301
+ it('should create book with all required fields', async () => {
302
+ const result = await testHelper.graphQl({
303
+ name: 'createBook',
304
+ type: TestGraphQLType.MUTATION,
305
+ arguments: {
306
+ input: {
307
+ isbn: '978-3-16-148410-0',
308
+ title: 'Test Book',
309
+ description: 'A test book',
310
+ available: true,
311
+ location: 'Shelf A1',
312
+ authors: [{
313
+ firstName: 'John',
314
+ lastName: 'Doe'
315
+ }],
316
+ publisher: {
317
+ name: 'Test Publisher',
318
+ city: 'Berlin',
319
+ country: 'Germany'
320
+ },
321
+ publishYear: 2023,
322
+ pageCount: 300,
323
+ language: 'ENGLISH',
324
+ genre: 'FICTION'
325
+ }
326
+ },
327
+ fields: ['id', 'isbn', 'title', 'pageCount']
328
+ }, { token: adminToken });
329
+
330
+ expect(result.isbn).toBe('978-3-16-148410-0');
331
+ createdBookId = result.id;
332
+ });
333
+
334
+ it('should fail without required fields', async () => {
335
+ const result = await testHelper.graphQl({
336
+ name: 'createBook',
337
+ type: TestGraphQLType.MUTATION,
338
+ arguments: {
339
+ input: {
340
+ isbn: '978-3-16-148410-1'
341
+ // Missing required fields
342
+ }
343
+ },
344
+ fields: ['id']
345
+ }, { token: adminToken, statusCode: 400 });
346
+
347
+ expect(result.errors).toBeDefined();
348
+ });
349
+
350
+ it('should get all books', async () => {
351
+ const result = await testHelper.graphQl({
352
+ name: 'books',
353
+ type: TestGraphQLType.QUERY,
354
+ fields: ['id', 'isbn', 'title']
355
+ }, { token: adminToken });
356
+
357
+ expect(Array.isArray(result)).toBe(true);
358
+ });
359
+
360
+ it('should update book', async () => {
361
+ const result = await testHelper.graphQl({
362
+ name: 'updateBook',
363
+ type: TestGraphQLType.MUTATION,
364
+ arguments: {
365
+ id: createdBookId,
366
+ input: { pageCount: 350 }
367
+ },
368
+ fields: ['id', 'pageCount']
369
+ }, { token: adminToken });
370
+
371
+ expect(result.pageCount).toBe(350);
372
+ });
373
+
374
+ it('should delete book', async () => {
375
+ const result = await testHelper.graphQl({
376
+ name: 'deleteBook',
377
+ type: TestGraphQLType.MUTATION,
378
+ arguments: { id: createdBookId },
379
+ fields: ['id']
380
+ }, { token: adminToken });
381
+
382
+ expect(result.id).toBe(createdBookId);
383
+ createdBookId = null;
384
+ });
385
+ });
386
+
387
+ // For REST API tests
388
+ // test/book/book.controller.rest.test.ts
389
+ describe('Book Controller (REST)', () => {
390
+ let testHelper: TestHelper;
391
+ let adminToken: string;
392
+ let createdBookId: string;
393
+
394
+ beforeAll(async () => {
395
+ testHelper = new TestHelper(app);
396
+ const authResult = await testHelper.rest('/auth/sign-in', {
397
+ method: 'POST',
398
+ payload: { email: 'admin@test.com', password: 'password' }
399
+ });
400
+ adminToken = authResult.token;
401
+ });
402
+
403
+ it('should create book via REST', async () => {
404
+ const result = await testHelper.rest('/books', {
405
+ method: 'POST',
406
+ payload: {
407
+ isbn: '978-3-16-148410-0',
408
+ title: 'Test Book',
409
+ available: true,
410
+ location: 'Shelf A1',
411
+ // ... other required fields
412
+ },
413
+ token: adminToken
414
+ });
415
+
416
+ expect(result.isbn).toBe('978-3-16-148410-0');
417
+ createdBookId = result.id;
418
+ });
419
+
420
+ it('should get all books via REST', async () => {
421
+ const result = await testHelper.rest('/books', { token: adminToken });
422
+ expect(Array.isArray(result)).toBe(true);
423
+ });
424
+
425
+ afterAll(async () => {
426
+ if (createdBookId) {
427
+ await testHelper.rest(`/books/${createdBookId}`, {
428
+ method: 'DELETE',
429
+ token: adminToken
430
+ });
431
+ }
432
+ });
433
+ });
434
+ ```
435
+
436
+ ### Execution Todo List Example
437
+
438
+ When processing this specification, create this todo list:
439
+
440
+ ```
441
+ 1. Create Author SubObject
442
+ 2. Create Publisher SubObject
443
+ 3. Create Review SubObject
444
+ 4. Create BaseItem Object
445
+ 5. Create Member Module
446
+ 6. Create Book Module
447
+ 7. Add currentLoans property to Member
448
+ 8. Create Loan Module
449
+ 9. Modify Book model to extend BaseItem
450
+ 10. Update Book CreateInput with BaseItem required fields
451
+ 11. Update all descriptions to "ENGLISH (DEUTSCH)" format
452
+ 12. Create BookLanguageEnum file
453
+ 13. Create BookGenreEnum file
454
+ 14. Create MemberStatusEnum file
455
+ 15. Create LoanStatusEnum file
456
+ 16. Create Book controller tests
457
+ 17. Create Book resolver tests
458
+ 18. Create Member controller tests
459
+ 19. Create Member resolver tests
460
+ 20. Create Loan controller tests
461
+ 21. Create Loan resolver tests
462
+ 22. Run all tests
463
+ 23. Verify all tests pass
464
+ 24. Verify no TypeScript errors
465
+ 25. Run lint and fix
466
+ 26. Provide summary
467
+ ```
468
+
469
+ ## Example 2: Hotel Booking System (Minimal)
470
+
471
+ A simpler example focusing on basic features:
472
+
473
+ ```
474
+ ===========
475
+
476
+ SubObject: ContactDetails // Contact information
477
+ - email: string // Email address
478
+ - phone: string // Phone number
479
+
480
+ ===
481
+
482
+ Module: Guest // Guest module
483
+
484
+ Model: Guest // Hotel guest
485
+ - name: string // Full name
486
+ - contact: ContactDetails // Contact information
487
+ - checkInDate: Date // Check-in date
488
+ - checkOutDate: Date // Check-out date
489
+ - roomNumber: string // Room number
490
+ - status: ENUM (CHECKED_IN, CHECKED_OUT, RESERVED, CANCELLED) // Booking status
491
+
492
+ ===========
493
+ ```
494
+
495
+ ### Commands
496
+
497
+ ```bash
498
+ # SubObject
499
+ lt server object --name ContactDetails \
500
+ --prop-name-0 email --prop-type-0 string \
501
+ --prop-name-1 phone --prop-type-1 string
502
+
503
+ # Module
504
+ lt server module --name Guest --controller Both \
505
+ --prop-name-0 checkInDate --prop-type-0 Date \
506
+ --prop-name-1 checkOutDate --prop-type-1 Date \
507
+ --prop-name-2 contact --prop-schema-2 ContactDetails \
508
+ --prop-name-3 name --prop-type-3 string \
509
+ --prop-name-4 roomNumber --prop-type-4 string \
510
+ --prop-name-5 status --prop-enum-5 GuestStatusEnum
511
+
512
+ # Enum file
513
+ # src/server/common/enums/guest-status.enum.ts
514
+ export enum GuestStatusEnum {
515
+ CHECKED_IN = 'CHECKED_IN',
516
+ CHECKED_OUT = 'CHECKED_OUT',
517
+ RESERVED = 'RESERVED',
518
+ CANCELLED = 'CANCELLED',
519
+ }
520
+ ```
521
+
522
+ ## Key Patterns Demonstrated
523
+
524
+ ### 1. SubObject with Arrays
525
+ ```
526
+ - authors: Author[] // Multiple authors
527
+ ```
528
+ → `--prop-schema-X Author --prop-array-X true`
529
+
530
+ ### 2. Optional Fields
531
+ ```
532
+ - description?: string // Optional description
533
+ ```
534
+ → `--prop-nullable-X true`
535
+
536
+ ### 3. Enum Properties
537
+ ```
538
+ - status: ENUM (ACTIVE, INACTIVE) // Status
539
+ ```
540
+ → `--prop-enum-X StatusEnum` + create enum file
541
+
542
+ ### 4. Module References
543
+ ```
544
+ - borrowedBy?: Member // Reference to member
545
+ ```
546
+ → `--prop-type-X ObjectId --prop-reference-X Member --prop-nullable-X true`
547
+
548
+ ### 5. Inheritance
549
+ ```
550
+ Extends: BaseItem
551
+ ```
552
+ → Manually change model to extend BaseItem and update inputs
553
+
554
+ ### 6. Circular References
555
+ ```
556
+ Member has currentLoans: Book[]
557
+ Book has borrowedBy?: Member
558
+ ```
559
+ → Create both modules first, then use `addProp` for the second reference
560
+
561
+ ## Best Practices from Examples
562
+
563
+ 1. **Create SubObjects first**: Author, Publisher, Review before Book
564
+ 2. **Create referenced modules early**: Member before Book (for borrowedBy)
565
+ 3. **Handle circular refs with addProp**: Add currentLoans to Member after Book exists
566
+ 4. **Alphabetical ordering**: All properties sorted in final files
567
+ 5. **Proper descriptions**: "ENGLISH (DEUTSCH)" format throughout
568
+ 6. **Complete enum files**: Create all enums immediately after modules
569
+ 7. **Comprehensive tests**: Cover all CRUD operations and edge cases
570
+ 8. **Quality review before reporting**: ALWAYS perform comprehensive quality review
571
+
572
+ ## Quality Review Workflow Example
573
+
574
+ **CRITICAL**: Before creating the final report, ALWAYS perform this quality review:
575
+
576
+ ```bash
577
+ # Step 1: Identify all changes
578
+ git status --short
579
+ git diff --name-only
580
+
581
+ # Step 2: Test Management
582
+
583
+ # Step 2.1: FIRST - Analyze existing tests thoroughly
584
+ ls -la tests/
585
+ ls -la tests/modules/
586
+ find tests -name "*.e2e-spec.ts" -type f
587
+
588
+ # Understand the test folder structure:
589
+ # - tests/modules/<module-name>.e2e-spec.ts - for modules
590
+ # - tests/common.e2e-spec.ts - for common functionality
591
+ # - tests/project.e2e-spec.ts - for project-level tests
592
+
593
+ # Read multiple test files to understand patterns
594
+ cat tests/modules/user.e2e-spec.ts
595
+ cat tests/modules/<another-module>.e2e-spec.ts
596
+ cat tests/common.e2e-spec.ts
597
+ cat tests/project.e2e-spec.ts
598
+
599
+ # CRITICAL: Read and understand TestHelper source code
600
+ cat node_modules/@lenne.tech/nest-server/src/test/test.helper.ts
601
+
602
+ # Document TestHelper understanding:
603
+ # - Available methods: graphQl(), rest(), constructor, initialization
604
+ # - graphQl() signature: (options: GraphQLOptions, config?: RequestConfig)
605
+ # - GraphQLOptions: { name, type (QUERY/MUTATION), arguments, fields }
606
+ # - RequestConfig: { token, statusCode, headers }
607
+ # - rest() signature: (method: HttpMethod, path: string, options?: RestOptions)
608
+ # - HttpMethod: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
609
+ # - RestOptions: { body, token, statusCode, headers }
610
+ # - Authentication: Pass token via config.token (both methods)
611
+ # - Error handling: Specify expected statusCode for error cases
612
+ # - Response: Returns parsed data directly
613
+ # - When to use: graphQl() for GraphQL endpoints, rest() for REST endpoints
614
+
615
+ # Document observed patterns:
616
+ # - Test framework: Jest
617
+ # - Test helper: TestHelper from @lenne.tech/nest-server
618
+ # - Auth: Token-based via signIn mutation
619
+ # - Setup: beforeAll initializes app and gets admin token
620
+ # - Cleanup: afterAll deletes test data
621
+ # - Assertions: expect() with Jest matchers
622
+ # - Prerequisites: How are test users/related data created?
623
+
624
+ # Verify existing tests pass BEFORE making changes
625
+ npm run test:e2e
626
+
627
+ # Step 2.2: For new modules - create test files in correct location
628
+ # Example: Created Book module, need to create tests
629
+
630
+ # IMPORTANT: Determine correct test location first!
631
+ # - Module in src/server/modules/book? → tests/modules/book.e2e-spec.ts
632
+ # - Common object/enum? → Add to tests/common.e2e-spec.ts
633
+ # - Project-level? → Add to tests/project.e2e-spec.ts
634
+
635
+ # Create new test file EXACTLY matching the pattern observed
636
+ # tests/modules/book.e2e-spec.ts with:
637
+ # - Same imports as existing tests
638
+ # - Same beforeAll/afterAll structure
639
+ # - Same authentication pattern
640
+ # - Same prerequisite handling (e.g., create User first if Book needs User)
641
+ # - Same assertion style
642
+ # - All CRUD operations
643
+ # - Authorization tests
644
+ # - Required field validation
645
+
646
+ # Step 2.3: For modified modules - update existing tests
647
+ find tests -name "*user*.e2e-spec.ts"
648
+ cat tests/modules/user.e2e-spec.ts # Read first!
649
+
650
+ # Run tests before modifying
651
+ npm run test:e2e
652
+
653
+ # If you added a property to User, update tests to verify it
654
+ # Run tests after modifying to ensure nothing broke
655
+ npm run test:e2e
656
+
657
+ # Step 3: Compare with existing code
658
+ # Read existing modules to understand project patterns
659
+ cat src/server/modules/user/user.model.ts
660
+ cat src/server/modules/user/inputs/user-create.input.ts
661
+
662
+ # Step 3: Critical analysis
663
+ # For each generated file, check:
664
+ # - Import ordering matches existing code
665
+ # - Property ordering is alphabetical
666
+ # - Decorator patterns match existing code
667
+ # - Description format matches project style
668
+ # - Indentation and formatting is consistent
669
+
670
+ # Step 4: Apply optimizations
671
+ # Fix any inconsistencies found:
672
+ # - Reorder imports
673
+ # - Reorder properties
674
+ # - Fix formatting
675
+ # - Improve descriptions
676
+
677
+ # Step 5: Run all tests
678
+ npm run build
679
+ npm run lint
680
+ npm run test:e2e
681
+
682
+ # Step 6: Fix any failures and repeat
683
+ # If tests fail:
684
+ # - Analyze error
685
+ # - Fix issue
686
+ # - Re-run tests
687
+ # - Repeat until all pass
688
+
689
+ # Only after ALL checks pass → Create Final Report
690
+ ```
691
+
692
+ **Example findings during quality review**:
693
+
694
+ ```
695
+ Step 2.1: Analyzed existing tests
696
+ ✅ Listed test structure: tests/modules/, tests/common.e2e-spec.ts, tests/project.e2e-spec.ts
697
+ ✅ Read 3 existing test files (user, role, profile)
698
+ ✅ Read and analyzed TestHelper source code (node_modules/@lenne.tech/nest-server/src/test/test.helper.ts)
699
+ ✅ Documented TestHelper:
700
+ - graphQl() method: signature, GraphQLOptions, RequestConfig
701
+ - rest() method: signature, HttpMethod, RestOptions
702
+ - When to use graphQl() vs rest()
703
+ - Authentication handling (token in config for both methods)
704
+ - Error handling (statusCode parameter)
705
+ - Response format and parsing
706
+ ✅ Documented patterns: Jest + TestHelper, token auth, beforeAll/afterAll cleanup
707
+ ✅ Documented prerequisites: Test users created first, then module-specific data
708
+ ✅ Verified all existing tests pass (23/23 passing)
709
+
710
+ ❌ Found: New Book module created but no test file exists
711
+ ✅ Fixed: Created tests/modules/book.e2e-spec.ts following exact pattern
712
+ - Placed in correct location: tests/modules/book.e2e-spec.ts (not tests/book/ or tests/modules/book/)
713
+ - Matched imports structure
714
+ - Matched beforeAll/afterAll pattern
715
+ - Identified prerequisites: Book references User for borrowedBy
716
+ - Created test User first in beforeAll
717
+ - Matched authentication approach
718
+ - Matched assertion style
719
+
720
+ ❌ Found: Modified User module (added 'phone' property) but tests not updated
721
+ ✅ Fixed:
722
+ - Read existing tests/modules/user.e2e-spec.ts first
723
+ - Ran tests before changes (all passing)
724
+ - Updated test to verify 'phone' property in create/update operations
725
+ - Ran tests after changes (all passing)
726
+
727
+ ❌ Found: Import ordering differs from existing modules
728
+ ✅ Fixed: Reordered imports to match project pattern
729
+
730
+ ❌ Found: Properties not alphabetically ordered in Book model
731
+ ✅ Fixed: Reordered all properties alphabetically
732
+
733
+ ❌ Found: Description format inconsistent ("German only" vs "ENGLISH (DEUTSCH)")
734
+ ✅ Fixed: Updated all descriptions to "ENGLISH (DEUTSCH)" format
735
+
736
+ ❌ Found: Test missing required field validation
737
+ ✅ Fixed: Added test case for missing required fields
738
+
739
+ ❌ Found: Test cleanup not following project pattern
740
+ ✅ Fixed: Updated afterAll hook to match existing test cleanup patterns
741
+
742
+ ✅ All tests passing
743
+ ✅ Linter passing
744
+ ✅ TypeScript compiling without errors
745
+
746
+ → Ready for Final Report
747
+ ```
748
+
749
+ **This quality review ensures**:
750
+ - Generated code matches project patterns perfectly
751
+ - No style inconsistencies
752
+ - **TestHelper thoroughly understood before creating tests**
753
+ - **TestHelper used correctly (graphQl() and rest() methods, authentication, error handling)**
754
+ - **Tests in correct folder structure (tests/modules/<name>.e2e-spec.ts, tests/common.e2e-spec.ts, tests/project.e2e-spec.ts)**
755
+ - **All new modules have corresponding test files**
756
+ - **All modified modules have updated tests**
757
+ - **All test prerequisites identified and handled correctly**
758
+ - **Tests follow existing project test patterns exactly**
759
+ - All tests pass before reporting
760
+ - Professional, production-ready code