@lenne.tech/nest-server 11.21.3 → 11.22.1
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/.claude/rules/architecture.md +79 -0
- package/.claude/rules/better-auth.md +262 -0
- package/.claude/rules/configurable-features.md +308 -0
- package/.claude/rules/core-modules.md +205 -0
- package/.claude/rules/framework-compatibility.md +79 -0
- package/.claude/rules/migration-guides.md +149 -0
- package/.claude/rules/module-deprecation.md +214 -0
- package/.claude/rules/module-inheritance.md +97 -0
- package/.claude/rules/package-management.md +112 -0
- package/.claude/rules/role-system.md +146 -0
- package/.claude/rules/testing.md +120 -0
- package/.claude/rules/versioning.md +53 -0
- package/CLAUDE.md +174 -0
- package/FRAMEWORK-API.md +231 -0
- package/dist/core/common/interfaces/server-options.interface.d.ts +10 -0
- package/dist/core/modules/error-code/error-code.module.js.map +1 -1
- package/dist/core.module.d.ts +3 -3
- package/dist/core.module.js +17 -4
- package/dist/core.module.js.map +1 -1
- package/dist/server/modules/file/file-info.model.d.ts +1 -5
- package/dist/server/modules/user/user.model.d.ts +1 -5
- package/dist/server/server.module.js +6 -6
- package/dist/server/server.module.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/docs/REQUEST-LIFECYCLE.md +1256 -0
- package/docs/error-codes.md +446 -0
- package/migration-guides/11.10.x-to-11.11.x.md +266 -0
- package/migration-guides/11.11.x-to-11.12.x.md +323 -0
- package/migration-guides/11.12.x-to-11.13.0.md +612 -0
- package/migration-guides/11.13.x-to-11.14.0.md +348 -0
- package/migration-guides/11.14.x-to-11.15.0.md +262 -0
- package/migration-guides/11.15.0-to-11.15.3.md +118 -0
- package/migration-guides/11.15.x-to-11.16.0.md +497 -0
- package/migration-guides/11.16.x-to-11.17.0.md +130 -0
- package/migration-guides/11.17.x-to-11.18.0.md +393 -0
- package/migration-guides/11.18.x-to-11.19.0.md +151 -0
- package/migration-guides/11.19.x-to-11.20.0.md +170 -0
- package/migration-guides/11.20.x-to-11.21.0.md +216 -0
- package/migration-guides/11.21.0-to-11.21.1.md +194 -0
- package/migration-guides/11.21.1-to-11.21.2.md +114 -0
- package/migration-guides/11.21.2-to-11.21.3.md +175 -0
- package/migration-guides/11.21.x-to-11.22.0.md +224 -0
- package/migration-guides/11.22.0-to-11.22.1.md +105 -0
- package/migration-guides/11.3.x-to-11.4.x.md +233 -0
- package/migration-guides/11.6.x-to-11.7.x.md +394 -0
- package/migration-guides/11.7.x-to-11.8.x.md +318 -0
- package/migration-guides/11.8.x-to-11.9.x.md +322 -0
- package/migration-guides/11.9.x-to-11.10.x.md +571 -0
- package/migration-guides/TEMPLATE.md +113 -0
- package/package.json +25 -18
- package/src/core/common/interfaces/server-options.interface.ts +83 -16
- package/src/core/modules/better-auth/CUSTOMIZATION.md +24 -17
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +5 -5
- package/src/core/modules/error-code/INTEGRATION-CHECKLIST.md +42 -12
- package/src/core/modules/error-code/error-code.module.ts +4 -9
- package/src/core.module.ts +52 -10
- package/src/server/server.module.ts +7 -9
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
# Migration Guide: 11.7.x → 11.8.x
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
| Category | Details |
|
|
6
|
+
|----------|---------|
|
|
7
|
+
| **Breaking Changes** | 1 (File download endpoint) |
|
|
8
|
+
| **New Features** | 2 (TUS Module, CoreFileController) |
|
|
9
|
+
| **Bugfixes** | None |
|
|
10
|
+
| **Migration Effort** | ~10 minutes |
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
### Node.js Version
|
|
17
|
+
|
|
18
|
+
**Node.js >= 20.19.0 is required** for `@tus/server` support.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Check your version
|
|
22
|
+
node --version
|
|
23
|
+
|
|
24
|
+
# Should output v20.19.0 or higher
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### New Dependencies
|
|
28
|
+
|
|
29
|
+
The following packages are automatically installed with nest-server 11.8.x:
|
|
30
|
+
|
|
31
|
+
| Package | Version | Purpose |
|
|
32
|
+
|---------|---------|---------|
|
|
33
|
+
| `@tus/server` | 2.3.0 | TUS protocol server implementation |
|
|
34
|
+
| `@tus/file-store` | 2.0.0 | File storage backend for TUS uploads |
|
|
35
|
+
|
|
36
|
+
These are production dependencies and will be installed automatically when updating nest-server.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Quick Migration
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Update package
|
|
44
|
+
npm install @lenne.tech/nest-server@11.8.x
|
|
45
|
+
|
|
46
|
+
# Install new TUS dependencies (automatically included)
|
|
47
|
+
npm install
|
|
48
|
+
|
|
49
|
+
# Verify build
|
|
50
|
+
npm run build
|
|
51
|
+
|
|
52
|
+
# Run tests
|
|
53
|
+
npm test
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Important:** If your project uses file downloads, see [Breaking Changes](#breaking-changes) below.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## What's New in 11.8.x
|
|
61
|
+
|
|
62
|
+
### 1. TUS Module (Resumable Uploads)
|
|
63
|
+
|
|
64
|
+
TUS is **enabled by default** - no configuration required! The module provides resumable file uploads using the [tus.io](https://tus.io) protocol.
|
|
65
|
+
|
|
66
|
+
**Endpoints (automatically available):**
|
|
67
|
+
|
|
68
|
+
| Method | Endpoint | Description |
|
|
69
|
+
|--------|----------|-------------|
|
|
70
|
+
| OPTIONS | `/tus` | Get server capabilities |
|
|
71
|
+
| POST | `/tus` | Create new upload |
|
|
72
|
+
| HEAD | `/tus/:id` | Get upload status |
|
|
73
|
+
| PATCH | `/tus/:id` | Continue upload |
|
|
74
|
+
| DELETE | `/tus/:id` | Terminate upload |
|
|
75
|
+
|
|
76
|
+
**Default Configuration:**
|
|
77
|
+
```typescript
|
|
78
|
+
{
|
|
79
|
+
enabled: true,
|
|
80
|
+
path: '/tus',
|
|
81
|
+
maxSize: 50 * 1024 * 1024 * 1024, // 50 GB
|
|
82
|
+
expiration: { expiresIn: '24h' },
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
> **Note:** `@tus/server` already includes all TUS protocol headers (Authorization, Content-Type, Tus-Resumable, Upload-Length, Upload-Metadata, Upload-Offset, etc.). The `allowedHeaders` option is only for project-specific custom headers.
|
|
87
|
+
|
|
88
|
+
**Add custom headers (if needed):**
|
|
89
|
+
```typescript
|
|
90
|
+
// config.env.ts
|
|
91
|
+
tus: {
|
|
92
|
+
allowedHeaders: ['X-Custom-Header'], // Only additional project-specific headers
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Disable TUS (if needed):**
|
|
97
|
+
```typescript
|
|
98
|
+
// server.module.ts
|
|
99
|
+
TusModule.forRoot({ config: false })
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Client Usage:**
|
|
103
|
+
```typescript
|
|
104
|
+
import { Upload } from 'tus-js-client';
|
|
105
|
+
|
|
106
|
+
const upload = new Upload(file, {
|
|
107
|
+
endpoint: 'http://localhost:3000/tus',
|
|
108
|
+
metadata: { filename: file.name, filetype: file.type },
|
|
109
|
+
onSuccess: () => console.log('Upload complete!'),
|
|
110
|
+
});
|
|
111
|
+
upload.start();
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 2. CoreFileController (Public Download Endpoints)
|
|
115
|
+
|
|
116
|
+
New abstract controller providing public file download endpoints:
|
|
117
|
+
|
|
118
|
+
| Endpoint | Description | Permission |
|
|
119
|
+
|----------|-------------|------------|
|
|
120
|
+
| `GET /files/id/:id` | Download by ID | S_EVERYONE |
|
|
121
|
+
| `GET /files/:filename` | Download by filename | S_EVERYONE |
|
|
122
|
+
|
|
123
|
+
Projects extending `CoreFileController` automatically get these endpoints.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Breaking Changes
|
|
128
|
+
|
|
129
|
+
### Change 1: File Download Endpoint Pattern
|
|
130
|
+
|
|
131
|
+
The file download by ID endpoint has changed from `/files/:id` to `/files/id/:id`.
|
|
132
|
+
|
|
133
|
+
**Before (11.7.x):**
|
|
134
|
+
```typescript
|
|
135
|
+
// FileController with custom download endpoint
|
|
136
|
+
@Get(':id')
|
|
137
|
+
@Roles(RoleEnum.ADMIN)
|
|
138
|
+
async getFile(@Param('id') id: string, @Res() res: Response) { }
|
|
139
|
+
|
|
140
|
+
// Client usage
|
|
141
|
+
GET /files/abc123 → Downloads file by ID (admin only)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**After (11.8.x):**
|
|
145
|
+
```typescript
|
|
146
|
+
// FileController extends CoreFileController
|
|
147
|
+
export class FileController extends CoreFileController {
|
|
148
|
+
constructor(protected override readonly fileService: FileService) {
|
|
149
|
+
super(fileService);
|
|
150
|
+
}
|
|
151
|
+
// Inherited: GET /files/id/:id (public)
|
|
152
|
+
// Inherited: GET /files/:filename (public)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Client usage
|
|
156
|
+
GET /files/id/abc123 → Downloads file by ID (public)
|
|
157
|
+
GET /files/example.pdf → Downloads file by filename (public)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Migration Steps:**
|
|
161
|
+
|
|
162
|
+
1. **Update FileController** to extend `CoreFileController`:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// src/server/modules/file/file.controller.ts
|
|
166
|
+
import { Controller, Delete, Get, Param, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
|
|
167
|
+
import { CoreFileController, Roles, RoleEnum } from '@lenne.tech/nest-server';
|
|
168
|
+
import { FileService } from './file.service';
|
|
169
|
+
|
|
170
|
+
@Controller('files')
|
|
171
|
+
@Roles(RoleEnum.ADMIN)
|
|
172
|
+
export class FileController extends CoreFileController {
|
|
173
|
+
constructor(protected override readonly fileService: FileService) {
|
|
174
|
+
super(fileService);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Keep your admin-only endpoints (upload, info, delete)
|
|
178
|
+
@Post('upload')
|
|
179
|
+
@Roles(RoleEnum.ADMIN)
|
|
180
|
+
@UseInterceptors(FileInterceptor('file'))
|
|
181
|
+
async uploadFile(@UploadedFile() file: Express.Multer.File) { /* ... */ }
|
|
182
|
+
|
|
183
|
+
@Get('info/:id')
|
|
184
|
+
@Roles(RoleEnum.ADMIN)
|
|
185
|
+
async getFileInfo(@Param('id') id: string) { /* ... */ }
|
|
186
|
+
|
|
187
|
+
@Delete(':id')
|
|
188
|
+
@Roles(RoleEnum.ADMIN)
|
|
189
|
+
async deleteFile(@Param('id') id: string) { /* ... */ }
|
|
190
|
+
|
|
191
|
+
// REMOVE your old getFile() method - CoreFileController handles downloads
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
2. **Update client-side download URLs:**
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
// Before
|
|
199
|
+
const downloadUrl = `/files/${fileId}`;
|
|
200
|
+
|
|
201
|
+
// After
|
|
202
|
+
const downloadUrl = `/files/id/${fileId}`;
|
|
203
|
+
// Or by filename:
|
|
204
|
+
const downloadUrl = `/files/${filename}`;
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
3. **Optional: Restrict download access** (if you need authentication):
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
@Controller('files')
|
|
211
|
+
@Roles(RoleEnum.ADMIN)
|
|
212
|
+
export class FileController extends CoreFileController {
|
|
213
|
+
// Override to require authentication
|
|
214
|
+
@Get('id/:id')
|
|
215
|
+
@Roles(RoleEnum.S_USER) // Require logged-in user
|
|
216
|
+
override async getFileById(@Param('id') id: string, @Res() res: Response) {
|
|
217
|
+
return super.getFileById(id, res);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
@Get(':filename')
|
|
221
|
+
@Roles(RoleEnum.S_USER)
|
|
222
|
+
override async getFile(@Param('filename') filename: string, @Res() res: Response) {
|
|
223
|
+
return super.getFile(filename, res);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Compatibility Notes
|
|
231
|
+
|
|
232
|
+
### Pattern: Custom FileController without CoreFileController
|
|
233
|
+
|
|
234
|
+
If you want to keep the old behavior exactly:
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
// This still works - don't extend CoreFileController
|
|
238
|
+
@Controller('files')
|
|
239
|
+
@Roles(RoleEnum.ADMIN)
|
|
240
|
+
export class FileController {
|
|
241
|
+
constructor(private readonly fileService: FileService) {}
|
|
242
|
+
|
|
243
|
+
@Get(':id')
|
|
244
|
+
@Roles(RoleEnum.ADMIN)
|
|
245
|
+
async getFile(@Param('id') id: string, @Res() res: Response) {
|
|
246
|
+
// Your existing implementation
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Pattern: TUS with Authentication
|
|
252
|
+
|
|
253
|
+
By default, TUS allows everyone to upload. To require authentication:
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
// src/server/modules/tus/tus.controller.ts
|
|
257
|
+
import { Controller } from '@nestjs/common';
|
|
258
|
+
import { CoreTusController, Roles, RoleEnum } from '@lenne.tech/nest-server';
|
|
259
|
+
|
|
260
|
+
@Controller('tus')
|
|
261
|
+
@Roles(RoleEnum.S_USER) // Require logged-in user
|
|
262
|
+
export class TusController extends CoreTusController {}
|
|
263
|
+
|
|
264
|
+
// server.module.ts
|
|
265
|
+
TusModule.forRoot({ controller: TusController })
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Troubleshooting
|
|
271
|
+
|
|
272
|
+
### Download returns 404 after migration
|
|
273
|
+
|
|
274
|
+
**Cause:** Using old endpoint pattern `/files/:id` instead of `/files/id/:id`
|
|
275
|
+
|
|
276
|
+
**Solution:** Update client to use `/files/id/:id` or `/files/:filename`
|
|
277
|
+
|
|
278
|
+
### TUS uploads not working
|
|
279
|
+
|
|
280
|
+
**Cause:** TUS might be disabled in config
|
|
281
|
+
|
|
282
|
+
**Solution:** Check that `tus: false` is not set in your config. TUS is enabled by default.
|
|
283
|
+
|
|
284
|
+
### TypeScript error: "must have an 'override' modifier"
|
|
285
|
+
|
|
286
|
+
**Cause:** `fileService` in constructor needs `override` when extending CoreFileController
|
|
287
|
+
|
|
288
|
+
**Solution:**
|
|
289
|
+
```typescript
|
|
290
|
+
// Add 'override' keyword
|
|
291
|
+
constructor(protected override readonly fileService: FileService) {
|
|
292
|
+
super(fileService);
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Module Documentation
|
|
299
|
+
|
|
300
|
+
### TUS Module
|
|
301
|
+
|
|
302
|
+
- **README:** [src/core/modules/tus/README.md](../src/core/modules/tus/README.md)
|
|
303
|
+
- **Integration Checklist:** [src/core/modules/tus/INTEGRATION-CHECKLIST.md](../src/core/modules/tus/INTEGRATION-CHECKLIST.md)
|
|
304
|
+
- **Reference Implementation:** `src/server/server.module.ts`
|
|
305
|
+
|
|
306
|
+
### File Module
|
|
307
|
+
|
|
308
|
+
- **README:** [src/core/modules/file/README.md](../src/core/modules/file/README.md)
|
|
309
|
+
- **Reference Implementation:** `src/server/modules/file/file.controller.ts`
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## References
|
|
314
|
+
|
|
315
|
+
- [TUS Protocol](https://tus.io/protocols/resumable-upload)
|
|
316
|
+
- [tus-js-client](https://github.com/tus/tus-js-client)
|
|
317
|
+
- [@tus/server](https://github.com/tus/tus-node-server)
|
|
318
|
+
- [nest-server-starter](https://github.com/lenneTech/nest-server-starter) (reference implementation)
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# Migration Guide: 11.8.x → 11.9.x
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
| Category | Details |
|
|
6
|
+
|----------|---------|
|
|
7
|
+
| **Breaking Changes** | None |
|
|
8
|
+
| **New Features** | ErrorCodeModule for centralized error handling with i18n translations |
|
|
9
|
+
| **Bugfixes** | None |
|
|
10
|
+
| **Migration Effort** | Minimal (~5 minutes for basic update, optional feature adoption) |
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Quick Migration (No Breaking Changes)
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Update package
|
|
18
|
+
npm install @lenne.tech/nest-server@11.9.x
|
|
19
|
+
|
|
20
|
+
# Verify build
|
|
21
|
+
npm run build
|
|
22
|
+
|
|
23
|
+
# Run tests
|
|
24
|
+
npm test
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**That's it!** The ErrorCodeModule is automatically registered and provides error translations at `/api/i18n/errors/:locale`.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## What's New in 11.9.x
|
|
32
|
+
|
|
33
|
+
### 1. ErrorCodeModule - Centralized Error Handling with i18n
|
|
34
|
+
|
|
35
|
+
The new ErrorCodeModule provides a centralized system for error codes with internationalization support.
|
|
36
|
+
|
|
37
|
+
#### Features
|
|
38
|
+
|
|
39
|
+
- **REST API** for error translations (Nuxt i18n compatible)
|
|
40
|
+
- **Type-safe error codes** with `ErrorCode` constant
|
|
41
|
+
- **Extensible** for project-specific error codes
|
|
42
|
+
- **Auto-registered** in CoreModule by default
|
|
43
|
+
|
|
44
|
+
#### New REST Endpoints
|
|
45
|
+
|
|
46
|
+
| Endpoint | Method | Description |
|
|
47
|
+
|----------|--------|-------------|
|
|
48
|
+
| `/api/i18n/errors/de` | GET | German error translations |
|
|
49
|
+
| `/api/i18n/errors/en` | GET | English error translations |
|
|
50
|
+
|
|
51
|
+
#### Response Format (Nuxt i18n compatible)
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"errors": {
|
|
56
|
+
"LTNS_0001": "Benutzer wurde nicht gefunden.",
|
|
57
|
+
"LTNS_0002": "Das eingegebene Passwort ist ungültig.",
|
|
58
|
+
"LTNS_0100": "Sie sind nicht angemeldet.",
|
|
59
|
+
"LTNS_0101": "Zugriff verweigert - Unzureichende Berechtigungen."
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
> **Note:** The translations returned by the i18n API are user-friendly messages intended for end users. They may differ from the technical error messages used in exceptions (e.g., `#LTNS_0100: Unauthorized - User is not logged in`).
|
|
65
|
+
|
|
66
|
+
#### Error Code Ranges
|
|
67
|
+
|
|
68
|
+
| Range | Category |
|
|
69
|
+
|-------|----------|
|
|
70
|
+
| LTNS_0001-0099 | Authentication errors |
|
|
71
|
+
| LTNS_0100-0199 | Authorization errors |
|
|
72
|
+
| LTNS_0200-0299 | User errors |
|
|
73
|
+
| LTNS_0300-0399 | Validation errors |
|
|
74
|
+
| LTNS_0400-0499 | Resource errors |
|
|
75
|
+
| LTNS_0500-0599 | File errors |
|
|
76
|
+
| LTNS_0900-0999 | Internal errors |
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Using Error Codes in Your Code
|
|
81
|
+
|
|
82
|
+
### Basic Usage
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { UnauthorizedException, BadRequestException } from '@nestjs/common';
|
|
86
|
+
import { ErrorCode } from '@lenne.tech/nest-server';
|
|
87
|
+
|
|
88
|
+
// Throw with standardized error code
|
|
89
|
+
throw new UnauthorizedException(ErrorCode.UNAUTHORIZED);
|
|
90
|
+
// Response: { statusCode: 401, message: "#LTNS_0100: Unauthorized - User is not logged in" }
|
|
91
|
+
|
|
92
|
+
throw new BadRequestException(ErrorCode.VALIDATION_FAILED);
|
|
93
|
+
// Response: { statusCode: 400, message: "#LTNS_0300: Validation failed" }
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Available Error Codes
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
ErrorCode.USER_NOT_FOUND // #LTNS_0001: User not found
|
|
100
|
+
ErrorCode.INVALID_PASSWORD // #LTNS_0002: Invalid password
|
|
101
|
+
ErrorCode.INVALID_TOKEN // #LTNS_0003: Invalid or malformed token
|
|
102
|
+
ErrorCode.TOKEN_EXPIRED // #LTNS_0004: Token has expired
|
|
103
|
+
ErrorCode.REFRESH_TOKEN_REQUIRED // #LTNS_0005: Refresh token required
|
|
104
|
+
ErrorCode.USER_NOT_VERIFIED // #LTNS_0006: User email not verified
|
|
105
|
+
ErrorCode.UNAUTHORIZED // #LTNS_0100: Unauthorized - User is not logged in
|
|
106
|
+
ErrorCode.ACCESS_DENIED // #LTNS_0101: Access denied - Insufficient permissions
|
|
107
|
+
ErrorCode.RESOURCE_FORBIDDEN // #LTNS_0102: Resource access forbidden
|
|
108
|
+
ErrorCode.EMAIL_ALREADY_EXISTS // #LTNS_0200: Email already registered
|
|
109
|
+
ErrorCode.USERNAME_ALREADY_EXISTS // #LTNS_0201: Username already taken
|
|
110
|
+
ErrorCode.VALIDATION_FAILED // #LTNS_0300: Validation failed
|
|
111
|
+
ErrorCode.REQUIRED_FIELD_MISSING // #LTNS_0301: Required field missing
|
|
112
|
+
ErrorCode.INVALID_FIELD_FORMAT // #LTNS_0302: Invalid field format
|
|
113
|
+
ErrorCode.RESOURCE_NOT_FOUND // #LTNS_0400: Resource not found
|
|
114
|
+
ErrorCode.RESOURCE_ALREADY_EXISTS // #LTNS_0401: Resource already exists
|
|
115
|
+
ErrorCode.FILE_NOT_FOUND // #LTNS_0500: File not found
|
|
116
|
+
ErrorCode.FILE_UPLOAD_FAILED // #LTNS_0501: File upload failed
|
|
117
|
+
ErrorCode.FILE_TYPE_NOT_ALLOWED // #LTNS_0502: File type not allowed
|
|
118
|
+
ErrorCode.INTERNAL_ERROR // #LTNS_0900: Internal server error
|
|
119
|
+
ErrorCode.SERVICE_UNAVAILABLE // #LTNS_0901: Service temporarily unavailable
|
|
120
|
+
ErrorCode.LEGACY_AUTH_DISABLED // #LTNS_0902: Legacy authentication is disabled
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Adding Project-Specific Error Codes (Optional)
|
|
126
|
+
|
|
127
|
+
### Scenario A: Simple Addition via Config (Recommended)
|
|
128
|
+
|
|
129
|
+
The easiest way to add project-specific error codes.
|
|
130
|
+
|
|
131
|
+
**1. Create error codes file:**
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
// src/server/common/errors/project-errors.ts
|
|
135
|
+
import { IErrorRegistry, mergeErrorCodes } from '@lenne.tech/nest-server';
|
|
136
|
+
|
|
137
|
+
export const ProjectErrors = {
|
|
138
|
+
ORDER_NOT_FOUND: {
|
|
139
|
+
code: 'PROJ_0001',
|
|
140
|
+
message: 'Order not found',
|
|
141
|
+
translations: {
|
|
142
|
+
de: 'Bestellung mit ID {orderId} wurde nicht gefunden.',
|
|
143
|
+
en: 'Order with ID {orderId} was not found.',
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
PAYMENT_FAILED: {
|
|
147
|
+
code: 'PROJ_0002',
|
|
148
|
+
message: 'Payment processing failed',
|
|
149
|
+
translations: {
|
|
150
|
+
de: 'Die Zahlung konnte nicht verarbeitet werden: {reason}',
|
|
151
|
+
en: 'Payment processing failed: {reason}',
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
} as const satisfies IErrorRegistry;
|
|
155
|
+
|
|
156
|
+
// Merged error codes for type-safe usage
|
|
157
|
+
export const ErrorCode = mergeErrorCodes(ProjectErrors);
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**2. Add to config.env.ts:**
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
import { ProjectErrors } from './server/common/errors/project-errors';
|
|
164
|
+
|
|
165
|
+
const config = {
|
|
166
|
+
// ... other config ...
|
|
167
|
+
errorCode: {
|
|
168
|
+
additionalErrorRegistry: ProjectErrors,
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Done!** Your project errors are now available via `/api/i18n/errors/:locale`.
|
|
174
|
+
|
|
175
|
+
### Scenario B: Custom Service (For Additional Locales)
|
|
176
|
+
|
|
177
|
+
Use this when you need additional locales beyond German and English.
|
|
178
|
+
|
|
179
|
+
See [INTEGRATION-CHECKLIST.md](../src/core/modules/error-code/INTEGRATION-CHECKLIST.md) for detailed instructions.
|
|
180
|
+
|
|
181
|
+
### Scenario C: Custom Controller (For Custom Routes)
|
|
182
|
+
|
|
183
|
+
Use this when you need custom endpoints like `/codes` listing.
|
|
184
|
+
|
|
185
|
+
See [INTEGRATION-CHECKLIST.md](../src/core/modules/error-code/INTEGRATION-CHECKLIST.md) for detailed instructions.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Configuration Reference
|
|
190
|
+
|
|
191
|
+
### New Config Option: errorCode
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
// config.env.ts
|
|
195
|
+
const config: IServerOptions = {
|
|
196
|
+
// ... other config ...
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* ErrorCodeModule configuration (new in 11.9.0)
|
|
200
|
+
*/
|
|
201
|
+
errorCode: {
|
|
202
|
+
/**
|
|
203
|
+
* Additional error registry to merge with core LTNS_* errors
|
|
204
|
+
* @optional
|
|
205
|
+
*/
|
|
206
|
+
additionalErrorRegistry: ProjectErrors,
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Auto-register ErrorCodeModule in CoreModule
|
|
210
|
+
* Set to false to provide your own module with custom controller/service
|
|
211
|
+
* @default true
|
|
212
|
+
*/
|
|
213
|
+
autoRegister: true,
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Compatibility Notes
|
|
221
|
+
|
|
222
|
+
### Existing Projects
|
|
223
|
+
|
|
224
|
+
- **No changes required** - ErrorCodeModule is auto-registered and provides translations immediately
|
|
225
|
+
- **Existing error handling** continues to work unchanged
|
|
226
|
+
- **New error codes** are opt-in and can be adopted gradually
|
|
227
|
+
|
|
228
|
+
### Custom Auth Implementations
|
|
229
|
+
|
|
230
|
+
If your project extends CoreAuthService or CoreAuthResolver, you can now use standardized error codes:
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
// Before (still works)
|
|
234
|
+
throw new UnauthorizedException('Invalid password');
|
|
235
|
+
|
|
236
|
+
// After (recommended)
|
|
237
|
+
import { ErrorCode } from '@lenne.tech/nest-server';
|
|
238
|
+
throw new UnauthorizedException(ErrorCode.INVALID_PASSWORD);
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Troubleshooting
|
|
244
|
+
|
|
245
|
+
### Error translations not loading
|
|
246
|
+
|
|
247
|
+
**Symptom:** `/api/i18n/errors/de` returns 404
|
|
248
|
+
|
|
249
|
+
**Solution:** Ensure you're on version 11.9.x and the server has been restarted:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
npm install @lenne.tech/nest-server@11.9.x
|
|
253
|
+
npm run build
|
|
254
|
+
npm run start:dev
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Custom errors not appearing
|
|
258
|
+
|
|
259
|
+
**Symptom:** Project-specific errors not in translation response
|
|
260
|
+
|
|
261
|
+
**Solution:** Verify your config.env.ts includes the additionalErrorRegistry:
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
import { ProjectErrors } from './server/common/errors/project-errors';
|
|
265
|
+
|
|
266
|
+
errorCode: {
|
|
267
|
+
additionalErrorRegistry: ProjectErrors,
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Route conflict with custom controller
|
|
272
|
+
|
|
273
|
+
**Symptom:** `/codes` endpoint returns locale error
|
|
274
|
+
|
|
275
|
+
**Solution:** Use a standalone controller (not extending CoreErrorCodeController). See the INTEGRATION-CHECKLIST.md for details.
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Module Documentation
|
|
280
|
+
|
|
281
|
+
### ErrorCodeModule
|
|
282
|
+
|
|
283
|
+
- **Integration Checklist:** [src/core/modules/error-code/INTEGRATION-CHECKLIST.md](../src/core/modules/error-code/INTEGRATION-CHECKLIST.md)
|
|
284
|
+
- **Reference Implementation:** `src/server/modules/error-code/`
|
|
285
|
+
- **Key Files:**
|
|
286
|
+
- `error-codes.ts` - Core error definitions and ErrorCode constant
|
|
287
|
+
- `core-error-code.service.ts` - Service for translation handling
|
|
288
|
+
- `core-error-code.controller.ts` - REST controller
|
|
289
|
+
- `interfaces/error-code.interfaces.ts` - Type definitions
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## New Exports
|
|
294
|
+
|
|
295
|
+
The following are now exported from `@lenne.tech/nest-server`:
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
// Error Code types and constants
|
|
299
|
+
export { ErrorCode } from './core/modules/error-code/error-codes';
|
|
300
|
+
export { LtnsErrors } from './core/modules/error-code/error-codes';
|
|
301
|
+
export { IErrorDefinition, IErrorRegistry, ErrorCodeKey, ErrorCodeType, RawErrorCode } from './core/modules/error-code/error-codes';
|
|
302
|
+
export { getAllErrorDefinitions, mergeErrorCodes } from './core/modules/error-code/error-codes';
|
|
303
|
+
|
|
304
|
+
// Module and services
|
|
305
|
+
export { ErrorCodeModule } from './core/modules/error-code/error-code.module';
|
|
306
|
+
export { CoreErrorCodeService } from './core/modules/error-code/core-error-code.service';
|
|
307
|
+
export { CoreErrorCodeController } from './core/modules/error-code/core-error-code.controller';
|
|
308
|
+
|
|
309
|
+
// Interfaces
|
|
310
|
+
export { IErrorCodeModuleConfig, IErrorTranslationResponse, SupportedLocale } from './core/modules/error-code/interfaces/error-code.interfaces';
|
|
311
|
+
|
|
312
|
+
// Config interface
|
|
313
|
+
export { IErrorCode } from './core/common/interfaces/server-options.interface';
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## References
|
|
319
|
+
|
|
320
|
+
- [ErrorCodeModule Integration Checklist](../src/core/modules/error-code/INTEGRATION-CHECKLIST.md)
|
|
321
|
+
- [nest-server-starter](https://github.com/lenneTech/nest-server-starter) (reference implementation)
|
|
322
|
+
- [Error Code Documentation](../docs/error-codes.md) (if available)
|