@venizia/ignis-docs 0.0.4-1 → 0.0.4-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/package.json +1 -1
  2. package/wiki/best-practices/api-usage-examples.md +1 -0
  3. package/wiki/best-practices/code-style-standards/advanced-patterns.md +259 -0
  4. package/wiki/best-practices/code-style-standards/constants-configuration.md +225 -0
  5. package/wiki/best-practices/code-style-standards/control-flow.md +245 -0
  6. package/wiki/best-practices/code-style-standards/documentation.md +221 -0
  7. package/wiki/best-practices/code-style-standards/function-patterns.md +142 -0
  8. package/wiki/best-practices/code-style-standards/index.md +110 -0
  9. package/wiki/best-practices/code-style-standards/naming-conventions.md +174 -0
  10. package/wiki/best-practices/code-style-standards/route-definitions.md +150 -0
  11. package/wiki/best-practices/code-style-standards/tooling.md +155 -0
  12. package/wiki/best-practices/code-style-standards/type-safety.md +165 -0
  13. package/wiki/best-practices/common-pitfalls.md +164 -3
  14. package/wiki/best-practices/contribution-workflow.md +1 -1
  15. package/wiki/best-practices/data-modeling.md +102 -2
  16. package/wiki/best-practices/error-handling.md +468 -0
  17. package/wiki/best-practices/index.md +204 -21
  18. package/wiki/best-practices/performance-optimization.md +180 -0
  19. package/wiki/best-practices/security-guidelines.md +249 -0
  20. package/wiki/best-practices/testing-strategies.md +620 -0
  21. package/wiki/changelogs/2026-01-05-range-queries-content-range.md +184 -0
  22. package/wiki/changelogs/2026-01-06-basic-authentication.md +103 -0
  23. package/wiki/changelogs/2026-01-07-controller-route-customization.md +209 -0
  24. package/wiki/changelogs/index.md +3 -0
  25. package/wiki/guides/core-concepts/components-guide.md +1 -1
  26. package/wiki/guides/core-concepts/persistent/models.md +10 -0
  27. package/wiki/guides/tutorials/complete-installation.md +1 -1
  28. package/wiki/guides/tutorials/testing.md +1 -1
  29. package/wiki/references/base/components.md +47 -29
  30. package/wiki/references/base/controllers.md +215 -18
  31. package/wiki/references/base/filter-system/fields-order-pagination.md +84 -0
  32. package/wiki/references/base/middlewares.md +33 -1
  33. package/wiki/references/base/models.md +40 -2
  34. package/wiki/references/base/repositories/index.md +2 -0
  35. package/wiki/references/components/authentication.md +261 -247
  36. package/wiki/references/helpers/index.md +1 -1
  37. package/wiki/references/src-details/core.md +1 -1
  38. package/wiki/best-practices/code-style-standards.md +0 -1193
@@ -0,0 +1,468 @@
1
+ # Error Handling
2
+
3
+ Comprehensive guide to handling errors gracefully in Ignis applications.
4
+
5
+ ## Error Handling Philosophy
6
+
7
+ | Principle | Description |
8
+ |-----------|-------------|
9
+ | **Fail Fast** | Detect and report errors as early as possible |
10
+ | **Don't Swallow** | Never catch errors without logging or re-throwing |
11
+ | **User-Friendly** | Return clear, actionable messages to clients |
12
+ | **Debuggable** | Include context for debugging in logs |
13
+
14
+ ## 1. Using `getError` Helper
15
+
16
+ Ignis provides `getError` for creating consistent, structured errors.
17
+
18
+ ```typescript
19
+ import { getError, HTTP } from '@venizia/ignis';
20
+
21
+ // Basic error
22
+ throw getError({
23
+ statusCode: HTTP.ResultCodes.RS_4.NotFound,
24
+ message: 'User not found',
25
+ });
26
+
27
+ // Error with details
28
+ throw getError({
29
+ statusCode: HTTP.ResultCodes.RS_4.BadRequest,
30
+ message: 'Invalid request',
31
+ details: {
32
+ field: 'email',
33
+ reason: 'Must be a valid email address',
34
+ },
35
+ });
36
+
37
+ // Error with context (for logging)
38
+ throw getError({
39
+ statusCode: HTTP.ResultCodes.RS_5.InternalServerError,
40
+ message: '[UserService][create] Database connection failed',
41
+ details: { userId: requestedId },
42
+ });
43
+ ```
44
+
45
+ ## 2. HTTP Status Code Reference
46
+
47
+ Use the correct status code for each error type:
48
+
49
+ | Code | Constant | Use When |
50
+ |------|----------|----------|
51
+ | 400 | `RS_4.BadRequest` | Invalid input format, missing required fields, database constraint violations (auto-handled) |
52
+ | 401 | `RS_4.Unauthorized` | Missing or invalid authentication |
53
+ | 403 | `RS_4.Forbidden` | Authenticated but insufficient permissions |
54
+ | 404 | `RS_4.NotFound` | Resource does not exist |
55
+ | 409 | `RS_4.Conflict` | Resource already exists (custom duplicate handling) |
56
+ | 422 | `RS_4.UnprocessableEntity` | Validation failed (Zod errors) |
57
+ | 429 | `RS_4.TooManyRequests` | Rate limit exceeded |
58
+ | 500 | `RS_5.InternalServerError` | Unexpected server error |
59
+ | 502 | `RS_5.BadGateway` | External service failed |
60
+ | 503 | `RS_5.ServiceUnavailable` | Service temporarily down |
61
+
62
+ :::tip Automatic Database Error Handling
63
+ Database constraint violations (unique, foreign key, not null, check) are automatically converted to HTTP 400 by the global error middleware. You don't need to catch these errors manually.
64
+ :::
65
+
66
+ ## 3. Error Handling Patterns
67
+
68
+ ### Service Layer Errors
69
+
70
+ ```typescript
71
+ import { BaseService, getError, HTTP } from '@venizia/ignis';
72
+
73
+ export class UserService extends BaseService {
74
+ async createUser(data: TCreateUserRequest): Promise<TUser> {
75
+ // Validate business rules
76
+ const existingUser = await this.userRepo.findOne({
77
+ filter: { where: { email: data.email } },
78
+ });
79
+
80
+ if (existingUser.data) {
81
+ throw getError({
82
+ statusCode: HTTP.ResultCodes.RS_4.Conflict,
83
+ message: 'Email already registered',
84
+ details: { email: data.email },
85
+ });
86
+ }
87
+
88
+ // Handle external service errors
89
+ try {
90
+ await this.emailService.sendWelcome(data.email);
91
+ } catch (error) {
92
+ // Log but don't fail user creation
93
+ this.logger.error('[createUser] Failed to send welcome email | email: %s | error: %s',
94
+ data.email, error.message);
95
+ }
96
+
97
+ return this.userRepo.create({ data });
98
+ }
99
+
100
+ async getUserOrFail(id: string): Promise<TUser> {
101
+ const user = await this.userRepo.findById({ id });
102
+
103
+ if (!user.data) {
104
+ throw getError({
105
+ statusCode: HTTP.ResultCodes.RS_4.NotFound,
106
+ message: 'User not found',
107
+ details: { id },
108
+ });
109
+ }
110
+
111
+ return user.data;
112
+ }
113
+ }
114
+ ```
115
+
116
+ ### Controller Layer Errors
117
+
118
+ Controllers should delegate to services and let the global error handler catch exceptions:
119
+
120
+ ```typescript
121
+ import { BaseController, controller, get, post } from '@venizia/ignis';
122
+
123
+ @controller({ path: '/users' })
124
+ export class UserController extends BaseController {
125
+
126
+ @post({ configs: RouteConfigs.CREATE_USER })
127
+ async createUser(c: Context) {
128
+ const data = c.req.valid('json');
129
+
130
+ // Service throws appropriate errors
131
+ const user = await this.userService.createUser(data);
132
+
133
+ return c.json(user, HTTP.ResultCodes.RS_2.Created);
134
+ }
135
+
136
+ @get({ configs: RouteConfigs.GET_USER })
137
+ async getUser(c: Context) {
138
+ const { id } = c.req.valid('param');
139
+
140
+ // Service throws 404 if not found
141
+ const user = await this.userService.getUserOrFail(id);
142
+
143
+ return c.json(user, HTTP.ResultCodes.RS_2.Ok);
144
+ }
145
+ }
146
+ ```
147
+
148
+ ### Repository Layer Errors
149
+
150
+ Database constraint violations (unique, foreign key, not null, check) are **automatically handled** by the global error middleware. They return HTTP 400 with a human-readable message:
151
+
152
+ ```json
153
+ {
154
+ "message": "Unique constraint violation\nDetail: Key (email)=(test@example.com) already exists.\nTable: User\nConstraint: UQ_User_email",
155
+ "statusCode": 400,
156
+ "requestId": "abc123"
157
+ }
158
+ ```
159
+
160
+ You don't need to wrap repository calls in try-catch for constraint errors. If you need custom error messages, you can still handle them explicitly:
161
+
162
+ ```typescript
163
+ import { BaseRepository, getError, HTTP } from '@venizia/ignis';
164
+
165
+ export class UserRepository extends BaseRepository<typeof User.schema> {
166
+ async createWithCustomError(data: TCreateUser): Promise<TCreateResult<TUser>> {
167
+ try {
168
+ return await this.create({ data });
169
+ } catch (error) {
170
+ // Custom message for specific constraint
171
+ if (error.cause?.code === '23505' && error.cause?.constraint === 'UQ_User_email') {
172
+ throw getError({
173
+ statusCode: HTTP.ResultCodes.RS_4.Conflict,
174
+ message: 'This email is already registered. Please use a different email or login.',
175
+ });
176
+ }
177
+ throw error; // Re-throw for automatic handling
178
+ }
179
+ }
180
+ }
181
+ ```
182
+
183
+ ## 4. Global Error Handler
184
+
185
+ Ignis includes a built-in error handler. Customize behavior in your application:
186
+
187
+ ```typescript
188
+ import { BaseApplication, ApplicationError } from '@venizia/ignis';
189
+
190
+ export class Application extends BaseApplication {
191
+ override setupMiddlewares(): void {
192
+ super.setupMiddlewares();
193
+
194
+ // Custom error handler (optional)
195
+ this.server.onError((error, c) => {
196
+ const requestId = c.get('requestId') ?? 'unknown';
197
+
198
+ // Log all errors
199
+ this.logger.error('[%s] Error | %s', requestId, error.message);
200
+
201
+ // Handle known application errors
202
+ if (error instanceof ApplicationError) {
203
+ return c.json({
204
+ statusCode: error.statusCode,
205
+ message: error.message,
206
+ details: error.details,
207
+ requestId,
208
+ }, error.statusCode as StatusCode);
209
+ }
210
+
211
+ // Handle Zod validation errors
212
+ if (error.name === 'ZodError') {
213
+ return c.json({
214
+ statusCode: 422,
215
+ message: 'Validation failed',
216
+ details: { cause: error.errors },
217
+ requestId,
218
+ }, 422);
219
+ }
220
+
221
+ // Unknown errors - don't expose details
222
+ return c.json({
223
+ statusCode: 500,
224
+ message: 'Internal server error',
225
+ requestId,
226
+ }, 500);
227
+ });
228
+ }
229
+ }
230
+ ```
231
+
232
+ ## 5. Error Response Format
233
+
234
+ All errors should follow a consistent format:
235
+
236
+ ```typescript
237
+ interface ErrorResponse {
238
+ statusCode: number;
239
+ message: string;
240
+ requestId: string;
241
+ details?: {
242
+ cause?: Array<{
243
+ path: string;
244
+ message: string;
245
+ code: string;
246
+ }>;
247
+ [key: string]: unknown;
248
+ };
249
+ }
250
+ ```
251
+
252
+ **Example Responses:**
253
+
254
+ ```json
255
+ // 400 Bad Request
256
+ {
257
+ "statusCode": 400,
258
+ "message": "Invalid request body",
259
+ "requestId": "abc123"
260
+ }
261
+
262
+ // 404 Not Found
263
+ {
264
+ "statusCode": 404,
265
+ "message": "User not found",
266
+ "requestId": "abc123",
267
+ "details": { "id": "user-uuid" }
268
+ }
269
+
270
+ // 422 Validation Error
271
+ {
272
+ "statusCode": 422,
273
+ "message": "Validation failed",
274
+ "requestId": "abc123",
275
+ "details": {
276
+ "cause": [
277
+ {
278
+ "path": "email",
279
+ "message": "Invalid email format",
280
+ "code": "invalid_string"
281
+ }
282
+ ]
283
+ }
284
+ }
285
+
286
+ // 500 Internal Error (production)
287
+ {
288
+ "statusCode": 500,
289
+ "message": "Internal server error",
290
+ "requestId": "abc123"
291
+ }
292
+ ```
293
+
294
+ ## 6. Logging Errors
295
+
296
+ ### What to Log
297
+
298
+ ```typescript
299
+ // ✅ Good - Context for debugging
300
+ this.logger.error('[createOrder] Failed | userId: %s | orderId: %s | error: %s',
301
+ userId, orderId, error.message);
302
+
303
+ // ✅ Good - Include stack trace for unexpected errors
304
+ this.logger.error('[createOrder] Unexpected error | %s', error.stack);
305
+
306
+ // ❌ Bad - No context
307
+ this.logger.error(error.message);
308
+
309
+ // ❌ Bad - Sensitive data
310
+ this.logger.error('Login failed for user | password: %s', password);
311
+ ```
312
+
313
+ ### Log Levels
314
+
315
+ | Level | Use For |
316
+ |-------|---------|
317
+ | `error` | Exceptions that need attention |
318
+ | `warn` | Recoverable issues, deprecation warnings |
319
+ | `info` | Important business events |
320
+ | `debug` | Detailed debugging information |
321
+
322
+ ```typescript
323
+ // Error - requires attention
324
+ this.logger.error('[payment] Transaction failed | orderId: %s', orderId);
325
+
326
+ // Warn - recovered but should investigate
327
+ this.logger.warn('[cache] Redis unavailable, falling back to memory');
328
+
329
+ // Info - business event
330
+ this.logger.info('[order] Created | orderId: %s | userId: %s', orderId, userId);
331
+
332
+ // Debug - detailed trace
333
+ this.logger.debug('[query] Executing | sql: %s | params: %j', sql, params);
334
+ ```
335
+
336
+ ## 7. Async Error Handling
337
+
338
+ ### Promises
339
+
340
+ ```typescript
341
+ // ✅ Good - Errors propagate naturally with async/await
342
+ async function processOrder(orderId: string) {
343
+ const order = await orderRepo.findById({ id: orderId }); // Throws if fails
344
+ const payment = await paymentService.charge(order); // Throws if fails
345
+ return payment;
346
+ }
347
+
348
+ // ✅ Good - Explicit catch when you need to handle
349
+ async function processOrderWithFallback(orderId: string) {
350
+ try {
351
+ return await paymentService.charge(order);
352
+ } catch (error) {
353
+ this.logger.warn('[processOrder] Primary payment failed, trying backup');
354
+ return await backupPaymentService.charge(order);
355
+ }
356
+ }
357
+
358
+ // ❌ Bad - Swallowing errors
359
+ async function processOrder(orderId: string) {
360
+ try {
361
+ await dangerousOperation();
362
+ } catch (error) {
363
+ // Error is swallowed - no one knows it happened!
364
+ }
365
+ }
366
+ ```
367
+
368
+ ### Fire-and-Forget with Error Handling
369
+
370
+ ```typescript
371
+ // ✅ Good - Log errors from fire-and-forget operations
372
+ this.sendNotification(userId).catch(error => {
373
+ this.logger.error('[notify] Failed | userId: %s | error: %s', userId, error.message);
374
+ });
375
+
376
+ // ✅ Good - Use void to indicate intentional fire-and-forget
377
+ void this.analytics.track('order_created', { orderId });
378
+
379
+ // ❌ Bad - Unhandled promise rejection
380
+ this.sendNotification(userId); // If this rejects, crash!
381
+ ```
382
+
383
+ ## 8. Transaction Error Handling
384
+
385
+ ```typescript
386
+ async function transferFunds(from: string, to: string, amount: number) {
387
+ const tx = await accountRepo.beginTransaction();
388
+
389
+ try {
390
+ await accountRepo.debit({ id: from, amount }, { transaction: tx });
391
+ await accountRepo.credit({ id: to, amount }, { transaction: tx });
392
+
393
+ await tx.commit();
394
+ return { success: true };
395
+ } catch (error) {
396
+ await tx.rollback();
397
+
398
+ // Re-throw with context
399
+ throw getError({
400
+ statusCode: HTTP.ResultCodes.RS_5.InternalServerError,
401
+ message: '[transferFunds] Transaction failed',
402
+ details: { from, to, amount, originalError: error.message },
403
+ });
404
+ }
405
+ }
406
+ ```
407
+
408
+ ## 9. Client-Side Error Handling
409
+
410
+ Guide for API consumers:
411
+
412
+ ```typescript
413
+ // TypeScript client example
414
+ async function createUser(data: CreateUserRequest): Promise<User> {
415
+ const response = await fetch('/api/users', {
416
+ method: 'POST',
417
+ headers: { 'Content-Type': 'application/json' },
418
+ body: JSON.stringify(data),
419
+ });
420
+
421
+ if (!response.ok) {
422
+ const error = await response.json();
423
+
424
+ switch (response.status) {
425
+ case 400:
426
+ throw new ValidationError(error.message, error.details);
427
+ case 401:
428
+ // Redirect to login
429
+ window.location.href = '/login';
430
+ throw new AuthError('Please log in');
431
+ case 404:
432
+ throw new NotFoundError(error.message);
433
+ case 422:
434
+ // Handle field-level errors
435
+ const fieldErrors = error.details?.cause?.reduce((acc, e) => {
436
+ acc[e.path] = e.message;
437
+ return acc;
438
+ }, {});
439
+ throw new ValidationError('Validation failed', fieldErrors);
440
+ case 429:
441
+ throw new RateLimitError('Too many requests. Try again later.');
442
+ default:
443
+ throw new ApiError(error.message || 'Something went wrong');
444
+ }
445
+ }
446
+
447
+ return response.json();
448
+ }
449
+ ```
450
+
451
+ ## Error Handling Checklist
452
+
453
+ | Category | Check |
454
+ |----------|-------|
455
+ | **Services** | Business rule violations throw appropriate errors |
456
+ | **Repositories** | Database errors are caught and wrapped |
457
+ | **Controllers** | Errors propagate to global handler |
458
+ | **Async** | All promises have error handling |
459
+ | **Transactions** | Always rollback on error |
460
+ | **Logging** | Errors logged with context |
461
+ | **Responses** | Consistent error format returned |
462
+ | **Security** | No sensitive data in error messages |
463
+
464
+ ## See Also
465
+
466
+ - [Common Pitfalls](./common-pitfalls) - Error handling mistakes
467
+ - [Testing Strategies](./testing-strategies) - Testing error scenarios
468
+ - [Troubleshooting Tips](./troubleshooting-tips) - Debugging errors
@@ -1,27 +1,210 @@
1
1
  # Best Practices
2
2
 
3
- Guidelines and recommendations for building production-ready Ignis applications.
3
+ Production-ready patterns, security guidelines, and optimization strategies for building robust Ignis applications. These best practices are distilled from real-world experience building enterprise applications.
4
4
 
5
- ## Overview
5
+ <div class="guide-cards">
6
+
7
+ <a href="./architectural-patterns" class="guide-card highlight">
8
+ <span class="guide-icon">🏗️</span>
9
+ <h3>Architecture</h3>
10
+ <p>Layered architecture, DI, components, lifecycle hooks</p>
11
+ </a>
12
+
13
+ <a href="./code-style-standards/" class="guide-card">
14
+ <span class="guide-icon">📝</span>
15
+ <h3>Code Standards</h3>
16
+ <p>Naming, types, patterns, ESLint, Prettier</p>
17
+ </a>
18
+
19
+ <a href="./security-guidelines" class="guide-card highlight">
20
+ <span class="guide-icon">🔒</span>
21
+ <h3>Security</h3>
22
+ <p>Auth, validation, secrets, CORS, rate limiting</p>
23
+ </a>
24
+
25
+ <a href="./data-modeling" class="guide-card">
26
+ <span class="guide-icon">🗄️</span>
27
+ <h3>Data Modeling</h3>
28
+ <p>Schemas, enrichers, relations, migrations</p>
29
+ </a>
30
+
31
+ <a href="./testing-strategies" class="guide-card">
32
+ <span class="guide-icon">🧪</span>
33
+ <h3>Testing</h3>
34
+ <p>Unit tests, integration tests, mocking</p>
35
+ </a>
36
+
37
+ <a href="./performance-optimization" class="guide-card">
38
+ <span class="guide-icon">⚡</span>
39
+ <h3>Performance</h3>
40
+ <p>Query optimization, caching, pooling</p>
41
+ </a>
42
+
43
+ <a href="./error-handling" class="guide-card">
44
+ <span class="guide-icon">🚨</span>
45
+ <h3>Error Handling</h3>
46
+ <p>Error patterns, logging, user-friendly messages</p>
47
+ </a>
48
+
49
+ <a href="./deployment-strategies" class="guide-card">
50
+ <span class="guide-icon">🚀</span>
51
+ <h3>Deployment</h3>
52
+ <p>Docker, Kubernetes, cloud platforms, CI/CD</p>
53
+ </a>
54
+
55
+ </div>
56
+
57
+ ## Learning Path
58
+
59
+ <div class="roadmap">
60
+
61
+ <div class="roadmap-stage">
62
+ <div class="stage-header">
63
+ <span class="stage-num">1</span>
64
+ <h4>Foundation</h4>
65
+ </div>
66
+ <p><a href="./architectural-patterns">Architecture</a> → <a href="./architecture-decisions">Decisions Guide</a> → <a href="./code-style-standards/">Code Standards</a></p>
67
+ <span class="stage-desc">Understand patterns and establish coding conventions</span>
68
+ </div>
69
+
70
+ <div class="roadmap-stage">
71
+ <div class="stage-header">
72
+ <span class="stage-num">2</span>
73
+ <h4>Data Layer</h4>
74
+ </div>
75
+ <p><a href="./data-modeling">Data Modeling</a> → <a href="./api-usage-examples">API Patterns</a> → <a href="./error-handling">Error Handling</a></p>
76
+ <span class="stage-desc">Design your data layer and handle edge cases</span>
77
+ </div>
78
+
79
+ <div class="roadmap-stage">
80
+ <div class="stage-header">
81
+ <span class="stage-num">3</span>
82
+ <h4>Quality Assurance</h4>
83
+ </div>
84
+ <p><a href="./testing-strategies">Testing</a> → <a href="./common-pitfalls">Avoid Pitfalls</a> → <a href="./troubleshooting-tips">Troubleshooting</a></p>
85
+ <span class="stage-desc">Write tests and prevent common mistakes</span>
86
+ </div>
87
+
88
+ <div class="roadmap-stage">
89
+ <div class="stage-header">
90
+ <span class="stage-num">4</span>
91
+ <h4>Production Ready</h4>
92
+ </div>
93
+ <p><a href="./security-guidelines">Security</a> → <a href="./performance-optimization">Performance</a> → <a href="./deployment-strategies">Deployment</a></p>
94
+ <span class="stage-desc">Secure, optimize, and deploy your application</span>
95
+ </div>
96
+
97
+ </div>
98
+
99
+ ## Quick Reference
100
+
101
+ ### Essential Patterns
102
+
103
+ ```typescript
104
+ // ✅ Layered Architecture
105
+ Controller → Service → Repository → DataSource
106
+
107
+ // ✅ Dependency Injection
108
+ @inject({ key: BindingKeys.build({ namespace: BindingNamespaces.SERVICE, key: UserService.name }) })
109
+
110
+ // ✅ Error Handling
111
+ throw getError({ statusCode: 404, message: 'User not found' });
112
+
113
+ // ✅ Input Validation
114
+ request: { body: jsonContent({ schema: z.object({ email: z.string().email() }) }) }
115
+ ```
116
+
117
+ ### Anti-Patterns to Avoid
118
+
119
+ ```typescript
120
+ // ❌ Business logic in controllers
121
+ @get({ configs: RouteConfigs.GET_USER })
122
+ async getUser(c: Context) {
123
+ const user = await this.userRepo.findById(id);
124
+ if (user.lastLogin < cutoff) await this.sendReminder(user); // Move to service!
125
+ return c.json(user);
126
+ }
127
+
128
+ // ❌ Catching all errors silently
129
+ try { await riskyOperation(); } catch (e) { /* swallowed */ }
130
+
131
+ // ❌ Using `any` type
132
+ const data: any = await fetchData(); // Use proper types!
133
+ ```
134
+
135
+ ### Security Checklist
136
+
137
+ | Check | Action |
138
+ |-------|--------|
139
+ | Secrets | Store in environment variables, never in code |
140
+ | Input | Validate with Zod schemas at API boundaries |
141
+ | Auth | Protect routes with `authStrategies: [Authentication.STRATEGY_JWT]` |
142
+ | Sensitive data | Use `hiddenProperties` in model settings |
143
+ | File uploads | Use `sanitizeFilename()` for all user-provided filenames |
144
+ | CORS | Configure allowed origins explicitly |
145
+
146
+ ### Performance Checklist
147
+
148
+ | Check | Action |
149
+ |-------|--------|
150
+ | Queries | Use `fields` to select only needed columns |
151
+ | Pagination | Always set `limit` on find operations |
152
+ | Relations | Limit `include` depth to 2 levels max |
153
+ | Connection pool | Configure pool size based on load |
154
+ | Background jobs | Offload CPU-intensive tasks to workers |
155
+ | Caching | Cache expensive queries with Redis |
156
+
157
+ ## All Best Practices
158
+
159
+ ### Architecture & Design
160
+
161
+ | Guide | Description |
162
+ |-------|-------------|
163
+ | [Architectural Patterns](./architectural-patterns) | Layered architecture, DI, components, mixins |
164
+ | [Architecture Decisions](./architecture-decisions) | When to use services, repositories, components |
165
+
166
+ ### Development
167
+
168
+ | Guide | Description |
169
+ |-------|-------------|
170
+ | [Code Style Standards](./code-style-standards/) | Naming conventions, types, ESLint, Prettier |
171
+ | [Data Modeling](./data-modeling) | Schema design, enrichers, relations, migrations |
172
+ | [API Usage Examples](./api-usage-examples) | Routing, repositories, middleware, services |
173
+
174
+ ### Quality
6
175
 
7
176
  | Guide | Description |
8
177
  |-------|-------------|
9
- | [Architectural Patterns](./architectural-patterns.md) | Layered architecture, project structure |
10
- | [Architecture Decisions](./architecture-decisions.md) | When to use services, repositories, components |
11
- | [Data Modeling](./data-modeling.md) | Database design, relations, migrations |
12
- | [Performance Optimization](./performance-optimization.md) | Speed up your application |
13
- | [Security Guidelines](./security-guidelines.md) | Protect your API and data |
14
- | [Code Style Standards](./code-style-standards.md) | ESLint, Prettier, naming conventions |
15
- | [Deployment Strategies](./deployment-strategies.md) | Docker, cloud platforms, CI/CD |
16
- | [Common Pitfalls](./common-pitfalls.md) | Mistakes to avoid |
17
- | [Troubleshooting Tips](./troubleshooting-tips.md) | Debug common issues |
18
- | [API Usage Examples](./api-usage-examples.md) | Real-world code patterns |
19
- | [Contribution Workflow](./contribution-workflow.md) | Contributing to Ignis |
20
-
21
- ## Quick Tips
22
-
23
- - **Start simple** - Don't over-engineer. Add complexity only when needed.
24
- - **Use the layered architecture** - Controllers → Services → Repositories
25
- - **Validate early** - Use Zod schemas at API boundaries
26
- - **Type everything** - Leverage TypeScript for safety
27
- - **Test critical paths** - Focus on business logic and edge cases
178
+ | [Testing Strategies](./testing-strategies) | Unit tests, integration tests, mocking, E2E |
179
+ | [Error Handling](./error-handling) | Error patterns, structured errors, logging |
180
+ | [Common Pitfalls](./common-pitfalls) | Mistakes to avoid and how to fix them |
181
+ | [Troubleshooting Tips](./troubleshooting-tips) | Debug common issues quickly |
182
+
183
+ ### Production
184
+
185
+ | Guide | Description |
186
+ |-------|-------------|
187
+ | [Security Guidelines](./security-guidelines) | Authentication, validation, secrets, CORS |
188
+ | [Performance Optimization](./performance-optimization) | Query optimization, caching, connection pooling |
189
+ | [Deployment Strategies](./deployment-strategies) | Docker, Kubernetes, cloud platforms, CI/CD |
190
+
191
+ ### Contributing
192
+
193
+ | Guide | Description |
194
+ |-------|-------------|
195
+ | [Contribution Workflow](./contribution-workflow) | Git workflow, PR guidelines, code review |
196
+
197
+ ::: tip New to Ignis?
198
+ Start with the [Getting Started Guide](/guides/) for tutorials, then return here for production-ready patterns.
199
+ :::
200
+
201
+ ::: warning Production Deployment?
202
+ Before deploying, review the [Security Guidelines](./security-guidelines) and [Deployment Strategies](./deployment-strategies) thoroughly.
203
+ :::
204
+
205
+ ## See Also
206
+
207
+ - [Getting Started](/guides/) - New to Ignis? Start here
208
+ - [API Reference](/references/) - Detailed API documentation
209
+ - [Core Concepts](/guides/core-concepts/application/) - Deep dive into architecture
210
+ - [Changelogs](/changelogs/) - Version history and updates