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