@venizia/ignis-docs 0.0.4-2 → 0.0.5-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/dist/mcp-server/helpers/docs.helper.js +1 -1
- package/dist/mcp-server/helpers/docs.helper.js.map +1 -1
- package/package.json +2 -1
- package/wiki/best-practices/api-usage-examples.md +9 -9
- package/wiki/best-practices/code-style-standards/function-patterns.md +31 -5
- package/wiki/best-practices/code-style-standards/route-definitions.md +3 -3
- package/wiki/best-practices/common-pitfalls.md +2 -2
- package/wiki/best-practices/error-handling.md +4 -4
- package/wiki/best-practices/performance-optimization.md +39 -0
- package/wiki/best-practices/troubleshooting-tips.md +24 -3
- package/wiki/guides/core-concepts/components-guide.md +2 -2
- package/wiki/guides/core-concepts/controllers.md +15 -14
- package/wiki/guides/core-concepts/persistent/transactions.md +2 -2
- package/wiki/guides/reference/glossary.md +5 -5
- package/wiki/guides/tutorials/building-a-crud-api.md +1 -1
- package/wiki/guides/tutorials/ecommerce-api.md +19 -19
- package/wiki/guides/tutorials/realtime-chat.md +10 -10
- package/wiki/references/base/controllers.md +26 -50
- package/wiki/references/base/datasources.md +1 -1
- package/wiki/references/base/filter-system/index.md +1 -1
- package/wiki/references/base/filter-system/json-filtering.md +4 -2
- package/wiki/references/base/middlewares.md +3 -3
- package/wiki/references/base/repositories/advanced.md +83 -0
- package/wiki/references/base/repositories/index.md +1 -1
- package/wiki/references/components/health-check.md +4 -4
- package/wiki/references/helpers/logger.md +222 -43
- package/wiki/references/helpers/network.md +273 -31
- package/wiki/references/utilities/jsx.md +13 -13
- package/wiki/changelogs/2025-12-16-initial-architecture.md +0 -145
- package/wiki/changelogs/2025-12-16-model-repo-datasource-refactor.md +0 -300
- package/wiki/changelogs/2025-12-17-refactor.md +0 -90
- package/wiki/changelogs/2025-12-18-performance-optimizations.md +0 -130
- package/wiki/changelogs/2025-12-18-repository-validation-security.md +0 -255
- package/wiki/changelogs/2025-12-26-nested-relations-and-generics.md +0 -86
- package/wiki/changelogs/2025-12-26-transaction-support.md +0 -57
- package/wiki/changelogs/2025-12-29-dynamic-binding-registration.md +0 -104
- package/wiki/changelogs/2025-12-29-snowflake-uid-helper.md +0 -100
- package/wiki/changelogs/2025-12-30-repository-enhancements.md +0 -214
- package/wiki/changelogs/2025-12-31-json-path-filtering-array-operators.md +0 -214
- package/wiki/changelogs/2025-12-31-string-id-custom-generator.md +0 -137
- package/wiki/changelogs/2026-01-02-default-filter-and-repository-mixins.md +0 -418
- package/wiki/changelogs/2026-01-05-range-queries-content-range.md +0 -184
- package/wiki/changelogs/2026-01-06-basic-authentication.md +0 -103
- package/wiki/changelogs/2026-01-07-controller-route-customization.md +0 -209
- package/wiki/changelogs/index.md +0 -44
- package/wiki/changelogs/planned-schema-migrator.md +0 -553
- package/wiki/changelogs/template.md +0 -123
- package/wiki/references/base/repositories.md +0 -62
|
@@ -26,7 +26,7 @@ class DocsHelper {
|
|
|
26
26
|
const files = await (0, fast_glob_1.default)('**/*.md', {
|
|
27
27
|
cwd: common_1.Paths.WIKI,
|
|
28
28
|
absolute: true,
|
|
29
|
-
ignore: ['node_modules'],
|
|
29
|
+
ignore: ['node_modules', 'changelogs/**'],
|
|
30
30
|
});
|
|
31
31
|
if (files.length === 0) {
|
|
32
32
|
logger_helper_1.Logger.warn(`No documentation files found in ${common_1.Paths.WIKI}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.helper.js","sourceRoot":"","sources":["../../../mcp-server/helpers/docs.helper.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA2B;AAC3B,sDAA2B;AAC3B,8DAAiC;AACjC,gEAAkC;AAClC,0DAA6B;AAC7B,sCAA8C;AAC9C,mDAAyC;AAezC,qGAAqG;AACrG,MAAa,UAAU;aACN,UAAK,GAAW,EAAE,CAAC;aACnB,UAAK,GAAsB,IAAI,CAAC;IAE/C;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,IAAI;QACf,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,KAAK,CAAC;QACpB,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAA,mBAAE,EAAC,SAAS,EAAE;gBAChC,GAAG,EAAE,cAAK,CAAC,IAAI;gBACf,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"docs.helper.js","sourceRoot":"","sources":["../../../mcp-server/helpers/docs.helper.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@venizia/ignis-docs",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5-0",
|
|
4
4
|
"description": "Documentation and MCP Server for Ignis Framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ignis",
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"LICENSE.md",
|
|
56
56
|
"dist/mcp-server",
|
|
57
57
|
"wiki",
|
|
58
|
+
"!wiki/changelogs",
|
|
58
59
|
"!**/*.tsbuildinfo"
|
|
59
60
|
],
|
|
60
61
|
"publishConfig": {
|
|
@@ -42,7 +42,7 @@ export const RouteConfigs = {
|
|
|
42
42
|
} as const;
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
Then, use the decorators in your controller class.
|
|
45
|
+
Then, use the decorators in your controller class.
|
|
46
46
|
|
|
47
47
|
**`src/controllers/test/controller.ts`**
|
|
48
48
|
```typescript
|
|
@@ -61,15 +61,15 @@ export class TestController extends BaseController {
|
|
|
61
61
|
// ...
|
|
62
62
|
|
|
63
63
|
@get({ configs: RouteConfigs.GET_TEST })
|
|
64
|
-
getWithDecorator(context: TRouteContext
|
|
64
|
+
getWithDecorator(context: TRouteContext) {
|
|
65
65
|
// context is fully typed!
|
|
66
66
|
return context.json({ message: 'Hello from decorator', method: 'GET' }, HTTP.ResultCodes.RS_2.Ok);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
@post({ configs: RouteConfigs.CREATE_ITEM })
|
|
70
|
-
createWithDecorator(context: TRouteContext
|
|
71
|
-
// context.req.valid('json')
|
|
72
|
-
const body = context.req.valid('json');
|
|
70
|
+
createWithDecorator(context: TRouteContext) {
|
|
71
|
+
// context.req.valid('json') can be explicitly typed
|
|
72
|
+
const body = context.req.valid<{ name: string; age: number }>('json');
|
|
73
73
|
|
|
74
74
|
// The response is validated against the schema
|
|
75
75
|
return context.json(
|
|
@@ -424,8 +424,8 @@ export class UserController extends BaseController {
|
|
|
424
424
|
}
|
|
425
425
|
|
|
426
426
|
@get({ configs: RouteConfigs.GET_USER_WITH_ORDERS })
|
|
427
|
-
async getUserWithOrders(c: TRouteContext
|
|
428
|
-
const { id } = c.req.valid('param');
|
|
427
|
+
async getUserWithOrders(c: TRouteContext) {
|
|
428
|
+
const { id } = c.req.valid<{ id: string }>('param');
|
|
429
429
|
const result = await this.userService.getUserWithOrders(id);
|
|
430
430
|
|
|
431
431
|
if (!result) {
|
|
@@ -520,8 +520,8 @@ throw getError({
|
|
|
520
520
|
|
|
521
521
|
```typescript
|
|
522
522
|
@get({ configs: RouteConfigs.GET_USER })
|
|
523
|
-
async getUser(c: TRouteContext
|
|
524
|
-
const { id } = c.req.valid('param');
|
|
523
|
+
async getUser(c: TRouteContext) {
|
|
524
|
+
const { id } = c.req.valid<{ id: string }>('param');
|
|
525
525
|
|
|
526
526
|
const user = await this.userRepository.findById({ id });
|
|
527
527
|
|
|
@@ -109,14 +109,17 @@ export class UserController extends BaseController {
|
|
|
109
109
|
|
|
110
110
|
## Performance Logging Pattern
|
|
111
111
|
|
|
112
|
-
Use `performance.now()` for timing critical operations:
|
|
112
|
+
Use `performance.now()` for timing critical operations with method-scoped logging:
|
|
113
113
|
|
|
114
114
|
```typescript
|
|
115
|
-
|
|
115
|
+
async syncData() {
|
|
116
|
+
const t = performance.now();
|
|
117
|
+
this.logger.for('syncData').info('START | Syncing data...');
|
|
116
118
|
|
|
117
|
-
// ... operation to measure ...
|
|
119
|
+
// ... operation to measure ...
|
|
118
120
|
|
|
119
|
-
this.logger.info('
|
|
121
|
+
this.logger.for('syncData').info('DONE | Took: %s (ms)', performance.now() - t);
|
|
122
|
+
}
|
|
120
123
|
```
|
|
121
124
|
|
|
122
125
|
**With the helper utility:**
|
|
@@ -125,7 +128,7 @@ this.logger.info('[methodName] DONE | Took: %s (ms)', performance.now() - t);
|
|
|
125
128
|
import { executeWithPerformanceMeasure } from '@venizia/ignis';
|
|
126
129
|
|
|
127
130
|
await executeWithPerformanceMeasure({
|
|
128
|
-
logger: this.logger,
|
|
131
|
+
logger: this.logger.for('syncData'),
|
|
129
132
|
scope: 'DataSync',
|
|
130
133
|
description: 'Sync user records',
|
|
131
134
|
task: async () => {
|
|
@@ -135,6 +138,29 @@ await executeWithPerformanceMeasure({
|
|
|
135
138
|
// Logs: [DataSync] Sync user records | Took: 1234.56 (ms)
|
|
136
139
|
```
|
|
137
140
|
|
|
141
|
+
**Method-scoped logging pattern:**
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
class UserService {
|
|
145
|
+
private logger = Logger.get('UserService');
|
|
146
|
+
|
|
147
|
+
async createUser(data: CreateUserDto) {
|
|
148
|
+
// Use .for() to add method context to all logs
|
|
149
|
+
this.logger.for('createUser').info('Creating user: %j', data);
|
|
150
|
+
// Output: [UserService-createUser] Creating user: {...}
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
const user = await this.userRepo.create({ data });
|
|
154
|
+
this.logger.for('createUser').info('User created: %s', user.id);
|
|
155
|
+
return user;
|
|
156
|
+
} catch (error) {
|
|
157
|
+
this.logger.for('createUser').error('Failed: %s', error);
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
138
164
|
## See Also
|
|
139
165
|
|
|
140
166
|
- [Naming Conventions](./naming-conventions) - Class and file naming
|
|
@@ -44,13 +44,13 @@ export const RouteConfigs = {
|
|
|
44
44
|
export class UserController extends BaseController {
|
|
45
45
|
|
|
46
46
|
@api({ configs: RouteConfigs.GET_USERS })
|
|
47
|
-
list(context: TRouteContext
|
|
47
|
+
list(context: TRouteContext) {
|
|
48
48
|
return context.json({ users: [] }, HTTP.ResultCodes.RS_2.Ok);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
@api({ configs: RouteConfigs.GET_USER_BY_ID })
|
|
52
|
-
getById(context: TRouteContext
|
|
53
|
-
const { id } = context.req.valid('param');
|
|
52
|
+
getById(context: TRouteContext) {
|
|
53
|
+
const { id } = context.req.valid<{ id: string }>('param');
|
|
54
54
|
return context.json({ id, name: 'User' }, HTTP.ResultCodes.RS_2.Ok);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
@@ -125,7 +125,7 @@ APP_ENV_POSTGRES_DATABASE=db
|
|
|
125
125
|
|
|
126
126
|
## 5. Not Using `as const` for Route Definitions
|
|
127
127
|
|
|
128
|
-
**Pitfall:** When using the decorator-based routing with a shared `RouteConfigs` object, you forget to add `as const` to the object definition. TypeScript will infer the types too broadly
|
|
128
|
+
**Pitfall:** When using the decorator-based routing with a shared `RouteConfigs` object, you forget to add `as const` to the object definition. TypeScript will infer the types too broadly.
|
|
129
129
|
|
|
130
130
|
**Solution:** Always use `as const` when exporting a shared route configuration object.
|
|
131
131
|
|
|
@@ -136,7 +136,7 @@ export const RouteConfigs = {
|
|
|
136
136
|
GET_USER_BY_ID: { /* ... */ },
|
|
137
137
|
} as const; // <-- This is crucial!
|
|
138
138
|
```
|
|
139
|
-
This ensures that
|
|
139
|
+
This ensures that the route configuration object is treated as a readonly literal, which is important for type safety throughout your application.
|
|
140
140
|
|
|
141
141
|
## 6. Bulk Operations Without WHERE Clause
|
|
142
142
|
|
|
@@ -124,8 +124,8 @@ import { BaseController, controller, get, post } from '@venizia/ignis';
|
|
|
124
124
|
export class UserController extends BaseController {
|
|
125
125
|
|
|
126
126
|
@post({ configs: RouteConfigs.CREATE_USER })
|
|
127
|
-
async createUser(c:
|
|
128
|
-
const data = c.req.valid('json');
|
|
127
|
+
async createUser(c: TRouteContext) {
|
|
128
|
+
const data = c.req.valid<{ name: string; email: string }>('json');
|
|
129
129
|
|
|
130
130
|
// Service throws appropriate errors
|
|
131
131
|
const user = await this.userService.createUser(data);
|
|
@@ -134,8 +134,8 @@ export class UserController extends BaseController {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
@get({ configs: RouteConfigs.GET_USER })
|
|
137
|
-
async getUser(c:
|
|
138
|
-
const { id } = c.req.valid('param');
|
|
137
|
+
async getUser(c: TRouteContext) {
|
|
138
|
+
const { id } = c.req.valid<{ id: string }>('param');
|
|
139
139
|
|
|
140
140
|
// Service throws 404 if not found
|
|
141
141
|
const user = await this.userService.getUserOrFail(id);
|
|
@@ -354,6 +354,44 @@ setInterval(() => {
|
|
|
354
354
|
}, 3600000); // Every hour
|
|
355
355
|
```
|
|
356
356
|
|
|
357
|
+
## 10. High-Frequency Logging
|
|
358
|
+
|
|
359
|
+
For performance-critical applications like HFT systems, use `HfLogger` instead of standard logging.
|
|
360
|
+
|
|
361
|
+
### Standard Logger vs HfLogger
|
|
362
|
+
|
|
363
|
+
| Feature | Standard Logger | HfLogger |
|
|
364
|
+
|---------|-----------------|----------|
|
|
365
|
+
| Latency | ~1-10 microseconds | ~100-300 nanoseconds |
|
|
366
|
+
| Allocation | Per-call string formatting | Zero in hot path |
|
|
367
|
+
| Use case | General application | Trading, real-time systems |
|
|
368
|
+
|
|
369
|
+
### HfLogger Usage
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
import { HfLogger, HfLogFlusher } from '@venizia/ignis-helpers';
|
|
373
|
+
|
|
374
|
+
// At initialization (once):
|
|
375
|
+
const logger = HfLogger.get('OrderEngine');
|
|
376
|
+
const MSG_ORDER_SENT = HfLogger.encodeMessage('Order sent');
|
|
377
|
+
const MSG_ORDER_FILLED = HfLogger.encodeMessage('Order filled');
|
|
378
|
+
|
|
379
|
+
// Start background flusher
|
|
380
|
+
const flusher = new HfLogFlusher();
|
|
381
|
+
flusher.start(100); // Flush every 100ms
|
|
382
|
+
|
|
383
|
+
// In hot path (~100-300ns, zero allocation):
|
|
384
|
+
logger.log('info', MSG_ORDER_SENT);
|
|
385
|
+
logger.log('info', MSG_ORDER_FILLED);
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Key points:**
|
|
389
|
+
- Pre-encode messages at initialization, not in hot path
|
|
390
|
+
- Use background flushing to avoid I/O blocking
|
|
391
|
+
- HfLogger uses a lock-free ring buffer (64K entries, 16MB)
|
|
392
|
+
|
|
393
|
+
> **Deep Dive:** See [Logger Helper](../references/helpers/logger.md) for complete HfLogger API.
|
|
394
|
+
|
|
357
395
|
## Performance Checklist
|
|
358
396
|
|
|
359
397
|
| Category | Check | Impact |
|
|
@@ -367,6 +405,7 @@ setInterval(() => {
|
|
|
367
405
|
| **Memory** | Large datasets processed in batches | High |
|
|
368
406
|
| **Caching** | Expensive queries cached | High |
|
|
369
407
|
| **Workers** | CPU-intensive tasks offloaded | High |
|
|
408
|
+
| **Logging** | HfLogger for hot paths (HFT) | High |
|
|
370
409
|
| **Monitoring** | Performance logging enabled | Low |
|
|
371
410
|
|
|
372
411
|
## See Also
|
|
@@ -75,9 +75,30 @@ curl -H "Authorization: Bearer YOUR_TOKEN" \
|
|
|
75
75
|
## 5. General Debugging Tips
|
|
76
76
|
|
|
77
77
|
**Enable detailed logging:**
|
|
78
|
+
```bash
|
|
79
|
+
# Enable debug mode via environment variable
|
|
80
|
+
DEBUG=true
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Use method-scoped logging with `.for()`:**
|
|
78
84
|
```typescript
|
|
79
|
-
|
|
80
|
-
|
|
85
|
+
class UserService {
|
|
86
|
+
private logger = Logger.get('UserService');
|
|
87
|
+
|
|
88
|
+
async createUser(data: CreateUserDto) {
|
|
89
|
+
this.logger.for('createUser').info('Creating user: %j', data);
|
|
90
|
+
// Output: [UserService-createUser] Creating user: {...}
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const user = await this.userRepo.create({ data });
|
|
94
|
+
this.logger.for('createUser').info('User created: %s', user.id);
|
|
95
|
+
return user;
|
|
96
|
+
} catch (error) {
|
|
97
|
+
this.logger.for('createUser').error('Failed: %s', error);
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
81
102
|
```
|
|
82
103
|
|
|
83
104
|
**Common debugging commands:**
|
|
@@ -93,7 +114,7 @@ cat .env | grep APP_ENV
|
|
|
93
114
|
```
|
|
94
115
|
|
|
95
116
|
**Useful debugging patterns:**
|
|
96
|
-
-
|
|
117
|
+
- Use `logger.for('methodName')` to trace execution with method context
|
|
97
118
|
- Use `try-catch` blocks to catch and log errors
|
|
98
119
|
- Check database queries with Drizzle's logging: `{ logger: true }`
|
|
99
120
|
|
|
@@ -169,8 +169,8 @@ export class NotificationController extends BaseController {
|
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
@post({ configs: NotificationRoutes.SEND })
|
|
172
|
-
async send(c: TRouteContext
|
|
173
|
-
const body = c.req.valid('json');
|
|
172
|
+
async send(c: TRouteContext) {
|
|
173
|
+
const body = c.req.valid<{ userId: string; message: string }>('json');
|
|
174
174
|
const result = await this._notificationService.send({
|
|
175
175
|
userId: body.userId,
|
|
176
176
|
message: body.message,
|
|
@@ -106,17 +106,18 @@ export class MyItemsController extends BaseController {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
@get({ configs: TestRoutes.GET_DATA })
|
|
109
|
-
getData(c: TRouteContext
|
|
109
|
+
getData(c: TRouteContext) {
|
|
110
110
|
// 'c' is fully typed here, including c.req.valid and c.json return type
|
|
111
111
|
return c.json({ message: 'Hello from decorator', method: 'GET' }, HTTP.ResultCodes.RS_2.Ok);
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
@post({ configs: TestRoutes.CREATE_ITEM })
|
|
115
|
-
createItem(c: TRouteContext
|
|
116
|
-
// c.req.valid('json') is automatically typed based on CREATE_ITEM.request.body.content['application/json']
|
|
117
|
-
|
|
115
|
+
createItem(c: TRouteContext) {
|
|
116
|
+
// c.req.valid('json') is automatically typed based on CREATE_ITEM.request.body.content['application/json']['schema']
|
|
117
|
+
// You can also provide an explicit type for stricter checking:
|
|
118
|
+
const body = c.req.valid<{ name: string; value: number }>('json');
|
|
118
119
|
|
|
119
|
-
// Return type is automatically validated against CREATE_ITEM.responses[200].content['application/json']
|
|
120
|
+
// Return type is automatically validated against CREATE_ITEM.responses[200].content['application/json']['schema']
|
|
120
121
|
return c.json(
|
|
121
122
|
{
|
|
122
123
|
id: 'some-uuid',
|
|
@@ -176,7 +177,7 @@ const GetUsersRoute = {
|
|
|
176
177
|
|
|
177
178
|
this.defineRoute({
|
|
178
179
|
configs: GetUsersRoute,
|
|
179
|
-
handler: (c: TRouteContext
|
|
180
|
+
handler: (c: TRouteContext) => {
|
|
180
181
|
return c.json([{ id: 1, name: 'John Doe' }], HTTP.ResultCodes.RS_2.Ok);
|
|
181
182
|
},
|
|
182
183
|
});
|
|
@@ -203,8 +204,8 @@ const GetUserByIdRoute = {
|
|
|
203
204
|
this.bindRoute({
|
|
204
205
|
configs: GetUserByIdRoute,
|
|
205
206
|
}).to({
|
|
206
|
-
handler: (c: TRouteContext
|
|
207
|
-
const { id } = c.req.valid('param'); // Use valid() for type-safe validated params
|
|
207
|
+
handler: (c: TRouteContext) => {
|
|
208
|
+
const { id } = c.req.valid<{ id: string }>('param'); // Use valid<T>() for type-safe validated params
|
|
208
209
|
return c.json({ id: id, name: 'John Doe' }, HTTP.ResultCodes.RS_2.Ok);
|
|
209
210
|
},
|
|
210
211
|
});
|
|
@@ -423,11 +424,11 @@ const UpdateUserConfig = {
|
|
|
423
424
|
} as const; // Use 'as const' for strict type inference
|
|
424
425
|
|
|
425
426
|
@put({ configs: UpdateUserConfig })
|
|
426
|
-
updateUser(c: TRouteContext
|
|
427
|
-
// Access validated data from the request
|
|
428
|
-
const { id } = c.req.valid('param');
|
|
429
|
-
const { notify } = c.req.valid('query');
|
|
430
|
-
const userUpdateData = c.req.valid('json'); // for body
|
|
427
|
+
updateUser(c: TRouteContext) {
|
|
428
|
+
// Access validated data from the request with explicit types
|
|
429
|
+
const { id } = c.req.valid<{ id: string }>('param');
|
|
430
|
+
const { notify } = c.req.valid<{ notify?: string }>('query');
|
|
431
|
+
const userUpdateData = c.req.valid<{ name: string; email: string }>('json'); // for body
|
|
431
432
|
|
|
432
433
|
console.log(`Updating user ${id} with data:`, userUpdateData);
|
|
433
434
|
if (notify) {
|
|
@@ -438,7 +439,7 @@ updateUser(c: TRouteContext<typeof UpdateUserConfig>) {
|
|
|
438
439
|
}
|
|
439
440
|
```
|
|
440
441
|
|
|
441
|
-
Using `TRouteContext` provides
|
|
442
|
+
Using `TRouteContext` provides a typed context object. By using `c.req.valid<T>()`, you ensure that the data you are accessing matches your expectations and provides autocomplete in your editor.
|
|
442
443
|
|
|
443
444
|
## See Also
|
|
444
445
|
|
|
@@ -120,8 +120,8 @@ export class OrderController extends BaseController {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
@post({ configs: OrderRoutes.CREATE })
|
|
123
|
-
async createOrder(c: TRouteContext
|
|
124
|
-
const body = c.req.valid('json');
|
|
123
|
+
async createOrder(c: TRouteContext) {
|
|
124
|
+
const body = c.req.valid<{ order: any; items: any[] }>('json'); // Use explicit types for better safety
|
|
125
125
|
|
|
126
126
|
const tx = await this._orderRepository.beginTransaction({
|
|
127
127
|
isolationLevel: 'SERIALIZABLE',
|
|
@@ -38,7 +38,7 @@ const TodoRoutes = {
|
|
|
38
38
|
@controller({ path: '/todos' })
|
|
39
39
|
export class TodoController extends BaseController {
|
|
40
40
|
@get({ configs: TodoRoutes.GET_ALL })
|
|
41
|
-
async getAll(c: TRouteContext
|
|
41
|
+
async getAll(c: TRouteContext) {
|
|
42
42
|
const todos = await this.repository.find({});
|
|
43
43
|
return c.json(todos, HTTP.ResultCodes.RS_2.Ok);
|
|
44
44
|
}
|
|
@@ -196,16 +196,16 @@ const TodoRoutes = {
|
|
|
196
196
|
@controller({ path: '/todos' })
|
|
197
197
|
class TodoController {
|
|
198
198
|
@get({ configs: TodoRoutes.GET_ALL })
|
|
199
|
-
async getAll(c: TRouteContext
|
|
199
|
+
async getAll(c: TRouteContext) { ... }
|
|
200
200
|
|
|
201
201
|
@get({ configs: TodoRoutes.GET_BY_ID })
|
|
202
|
-
async getById(c: TRouteContext
|
|
203
|
-
const { id } = c.req.valid('param');
|
|
202
|
+
async getById(c: TRouteContext) {
|
|
203
|
+
const { id } = c.req.valid<{ id: string }>('param');
|
|
204
204
|
...
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
@post({ configs: TodoRoutes.CREATE })
|
|
208
|
-
async create(c: TRouteContext
|
|
208
|
+
async create(c: TRouteContext) {
|
|
209
209
|
const data = c.req.valid('json');
|
|
210
210
|
...
|
|
211
211
|
}
|
|
@@ -289,7 +289,7 @@ export class TodoRepository extends DefaultCRUDRepository<typeof Todo.schema> {
|
|
|
289
289
|
| `deleteAll()` | Delete multiple records |
|
|
290
290
|
| `count()` | Count matching records |
|
|
291
291
|
|
|
292
|
-
> **Deep Dive:** See [Repositories Reference](/references/base/repositories) for query options and advanced filtering.
|
|
292
|
+
> **Deep Dive:** See [Repositories Reference](/references/base/repositories/) for query options and advanced filtering.
|
|
293
293
|
|
|
294
294
|
## Step 5: Create the Controller
|
|
295
295
|
|
|
@@ -979,8 +979,8 @@ export class ProductController extends BaseController {
|
|
|
979
979
|
override binding() {}
|
|
980
980
|
|
|
981
981
|
@get({ configs: ProductRoutes.LIST })
|
|
982
|
-
async listProducts(c: TRouteContext
|
|
983
|
-
const { category, limit, offset } = c.req.valid('query');
|
|
982
|
+
async listProducts(c: TRouteContext) {
|
|
983
|
+
const { category, limit, offset } = c.req.valid<{ category?: string; limit?: string; offset?: string }>('query');
|
|
984
984
|
|
|
985
985
|
const products = await this._productService.getActiveProducts({
|
|
986
986
|
categoryId: category,
|
|
@@ -992,8 +992,8 @@ export class ProductController extends BaseController {
|
|
|
992
992
|
}
|
|
993
993
|
|
|
994
994
|
@get({ configs: ProductRoutes.GET_BY_ID })
|
|
995
|
-
async getProduct(c: TRouteContext
|
|
996
|
-
const { id } = c.req.valid('param');
|
|
995
|
+
async getProduct(c: TRouteContext) {
|
|
996
|
+
const { id } = c.req.valid<{ id: string }>('param');
|
|
997
997
|
const product = await this._productService.getProductById({ id });
|
|
998
998
|
return c.json(product);
|
|
999
999
|
}
|
|
@@ -1094,7 +1094,7 @@ export class CartController extends BaseController {
|
|
|
1094
1094
|
override binding() {}
|
|
1095
1095
|
|
|
1096
1096
|
@get({ configs: CartRoutes.GET })
|
|
1097
|
-
async getCart(c: TRouteContext
|
|
1097
|
+
async getCart(c: TRouteContext) {
|
|
1098
1098
|
const sessionId = c.req.header('X-Session-ID') ?? 'guest';
|
|
1099
1099
|
const cart = await this._cartService.getOrCreateCart({ sessionId });
|
|
1100
1100
|
const cartWithItems = await this._cartService.getCartWithItems({ cartId: cart.id });
|
|
@@ -1102,9 +1102,9 @@ export class CartController extends BaseController {
|
|
|
1102
1102
|
}
|
|
1103
1103
|
|
|
1104
1104
|
@post({ configs: CartRoutes.ADD_ITEM })
|
|
1105
|
-
async addToCart(c: TRouteContext
|
|
1105
|
+
async addToCart(c: TRouteContext) {
|
|
1106
1106
|
const sessionId = c.req.header('X-Session-ID') ?? 'guest';
|
|
1107
|
-
const { productId, quantity } = c.req.valid('json');
|
|
1107
|
+
const { productId, quantity } = c.req.valid<{ productId: string; quantity: number }>('json');
|
|
1108
1108
|
|
|
1109
1109
|
const cart = await this._cartService.getOrCreateCart({ sessionId });
|
|
1110
1110
|
await this._cartService.addItem({ cartId: cart.id, productId, quantity });
|
|
@@ -1114,10 +1114,10 @@ export class CartController extends BaseController {
|
|
|
1114
1114
|
}
|
|
1115
1115
|
|
|
1116
1116
|
@put({ configs: CartRoutes.UPDATE_ITEM })
|
|
1117
|
-
async updateCartItem(c: TRouteContext
|
|
1117
|
+
async updateCartItem(c: TRouteContext) {
|
|
1118
1118
|
const sessionId = c.req.header('X-Session-ID') ?? 'guest';
|
|
1119
|
-
const { productId } = c.req.valid('param');
|
|
1120
|
-
const { quantity } = c.req.valid('json');
|
|
1119
|
+
const { productId } = c.req.valid<{ productId: string }>('param');
|
|
1120
|
+
const { quantity } = c.req.valid<{ quantity: number }>('json');
|
|
1121
1121
|
|
|
1122
1122
|
const cart = await this._cartService.getOrCreateCart({ sessionId });
|
|
1123
1123
|
await this._cartService.updateItemQuantity({ cartId: cart.id, productId, quantity });
|
|
@@ -1127,9 +1127,9 @@ export class CartController extends BaseController {
|
|
|
1127
1127
|
}
|
|
1128
1128
|
|
|
1129
1129
|
@del({ configs: CartRoutes.REMOVE_ITEM })
|
|
1130
|
-
async removeFromCart(c: TRouteContext
|
|
1130
|
+
async removeFromCart(c: TRouteContext) {
|
|
1131
1131
|
const sessionId = c.req.header('X-Session-ID') ?? 'guest';
|
|
1132
|
-
const { productId } = c.req.valid('param');
|
|
1132
|
+
const { productId } = c.req.valid<{ productId: string }>('param');
|
|
1133
1133
|
|
|
1134
1134
|
const cart = await this._cartService.getOrCreateCart({ sessionId });
|
|
1135
1135
|
await this._cartService.removeItem({ cartId: cart.id, productId });
|
|
@@ -1234,24 +1234,24 @@ export class OrderController extends BaseController {
|
|
|
1234
1234
|
override binding() {}
|
|
1235
1235
|
|
|
1236
1236
|
@post({ configs: OrderRoutes.CREATE })
|
|
1237
|
-
async createOrder(c: TRouteContext
|
|
1238
|
-
const body = c.req.valid('json');
|
|
1237
|
+
async createOrder(c: TRouteContext) {
|
|
1238
|
+
const body = c.req.valid<any>('json'); // Use explicit type if available
|
|
1239
1239
|
const result = await this._orderService.createOrder({ input: body });
|
|
1240
1240
|
return c.json(result, HTTP.ResultCodes.RS_2.Created);
|
|
1241
1241
|
}
|
|
1242
1242
|
|
|
1243
1243
|
@post({ configs: OrderRoutes.CONFIRM })
|
|
1244
|
-
async confirmOrder(c: TRouteContext
|
|
1245
|
-
const { id: orderId } = c.req.valid('param');
|
|
1246
|
-
const { paymentIntentId } = c.req.valid('json');
|
|
1244
|
+
async confirmOrder(c: TRouteContext) {
|
|
1245
|
+
const { id: orderId } = c.req.valid<{ id: string }>('param');
|
|
1246
|
+
const { paymentIntentId } = c.req.valid<{ paymentIntentId: string }>('json');
|
|
1247
1247
|
|
|
1248
1248
|
const order = await this._orderService.confirmPayment({ orderId, paymentIntentId });
|
|
1249
1249
|
return c.json(order);
|
|
1250
1250
|
}
|
|
1251
1251
|
|
|
1252
1252
|
@get({ configs: OrderRoutes.GET_BY_ID })
|
|
1253
|
-
async getOrder(c: TRouteContext
|
|
1254
|
-
const { id: orderId } = c.req.valid('param');
|
|
1253
|
+
async getOrder(c: TRouteContext) {
|
|
1254
|
+
const { id: orderId } = c.req.valid<{ id: string }>('param');
|
|
1255
1255
|
const order = await this._orderService.getOrderById({ orderId });
|
|
1256
1256
|
return c.json(order);
|
|
1257
1257
|
}
|
|
@@ -1073,16 +1073,16 @@ export class ChatController extends BaseController {
|
|
|
1073
1073
|
override binding() {}
|
|
1074
1074
|
|
|
1075
1075
|
@get({ configs: ChatRoutes.GET_ROOMS })
|
|
1076
|
-
async getRooms(c: TRouteContext
|
|
1076
|
+
async getRooms(c: TRouteContext) {
|
|
1077
1077
|
const userId = c.get('userId');
|
|
1078
1078
|
const rooms = await this._chatService.getUserRooms({ userId });
|
|
1079
1079
|
return c.json(rooms);
|
|
1080
1080
|
}
|
|
1081
1081
|
|
|
1082
1082
|
@post({ configs: ChatRoutes.CREATE_ROOM })
|
|
1083
|
-
async createRoom(c: TRouteContext
|
|
1083
|
+
async createRoom(c: TRouteContext) {
|
|
1084
1084
|
const userId = c.get('userId');
|
|
1085
|
-
const data = c.req.valid('json');
|
|
1085
|
+
const data = c.req.valid<{ name: string; description?: string; isPrivate: boolean }>('json');
|
|
1086
1086
|
|
|
1087
1087
|
const room = await this._chatService.createRoom({
|
|
1088
1088
|
...data,
|
|
@@ -1093,9 +1093,9 @@ export class ChatController extends BaseController {
|
|
|
1093
1093
|
}
|
|
1094
1094
|
|
|
1095
1095
|
@get({ configs: ChatRoutes.GET_MESSAGES })
|
|
1096
|
-
async getMessages(c: TRouteContext
|
|
1097
|
-
const { roomId } = c.req.valid('param');
|
|
1098
|
-
const { limit, before } = c.req.valid('query');
|
|
1096
|
+
async getMessages(c: TRouteContext) {
|
|
1097
|
+
const { roomId } = c.req.valid<{ roomId: string }>('param');
|
|
1098
|
+
const { limit, before } = c.req.valid<{ limit?: string; before?: string }>('query');
|
|
1099
1099
|
|
|
1100
1100
|
const messages = await this._chatService.getMessages({
|
|
1101
1101
|
roomId,
|
|
@@ -1107,17 +1107,17 @@ export class ChatController extends BaseController {
|
|
|
1107
1107
|
}
|
|
1108
1108
|
|
|
1109
1109
|
@get({ configs: ChatRoutes.GET_CONVERSATIONS })
|
|
1110
|
-
async getConversations(c: TRouteContext
|
|
1110
|
+
async getConversations(c: TRouteContext) {
|
|
1111
1111
|
const userId = c.get('userId');
|
|
1112
1112
|
const conversations = await this._chatService.getConversations({ userId });
|
|
1113
1113
|
return c.json(conversations);
|
|
1114
1114
|
}
|
|
1115
1115
|
|
|
1116
1116
|
@get({ configs: ChatRoutes.GET_DIRECT_MESSAGES })
|
|
1117
|
-
async getDirectMessages(c: TRouteContext
|
|
1117
|
+
async getDirectMessages(c: TRouteContext) {
|
|
1118
1118
|
const currentUserId = c.get('userId');
|
|
1119
|
-
const { userId: otherUserId } = c.req.valid('param');
|
|
1120
|
-
const { limit, before } = c.req.valid('query');
|
|
1119
|
+
const { userId: otherUserId } = c.req.valid<{ userId: string }>('param');
|
|
1120
|
+
const { limit, before } = c.req.valid<{ limit?: string; before?: string }>('query');
|
|
1121
1121
|
|
|
1122
1122
|
const messages = await this._chatService.getDirectMessages({
|
|
1123
1123
|
userId1: currentUserId,
|