@takentrade/takentrade-libs 1.2.79 → 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/README.md CHANGED
@@ -1,62 +1,53 @@
1
1
  # TakeNTrade Microservices Libraries
2
2
 
3
- This directory contains shared libraries used across the TakeNTrade microservices architecture. Below is a guide on how to use each library in your services.
3
+ This package contains shared libraries used across the TakeNTrade microservices architecture. It provides authentication, caching, messaging, notifications, utilities, and common functionality to all services.
4
4
 
5
- ## Cache Library (`@/libs/cache`)
6
-
7
- Redis-based caching implementation for the microservices.
5
+ ## Installation
8
6
 
9
- ### Environment Variables
10
-
11
- Each service should have these Redis-related environment variables:
7
+ ```bash
8
+ npm install @takentrade/takentrade-libs
9
+ ```
12
10
 
13
- - REDIS_HOST: Defaults to localhost
14
- - REDIS_PORT: Default to 6379
15
- - REDIS_USERNAME (Optional)
16
- - REDIS_PASSWORD (Optional)
11
+ ## Table of Contents
17
12
 
18
- ### Usage
13
+ - [Authentication & Authorization](#authentication--authorization)
14
+ - [Cache Library (`@/libs/cache`)](#cache-library-libscache)
15
+ - [BullMQ Library (`@/libs/bullmq`)](#bullmq-library-libsbullmq)
16
+ - [NATS Library (`@/libs/nats`)](#nats-library-libsnats)
17
+ - [Notification Client](#notification-client)
18
+ - [Prisma Module](#prisma-module)
19
+ - [RPC Utilities](#rpc-utilities)
20
+ - [Common Utilities](#common-utilities)
21
+ - [Utils Module](#utils-module)
22
+ - [Configuration](#configuration)
19
23
 
20
- ```typescript
21
- import { CacheModule, CacheService } from '@/libs/cache';
24
+ ---
22
25
 
23
- @Module({
24
- imports: [
25
- CacheModule.register()
26
- ]
27
- })
26
+ ## Authentication & Authorization
28
27
 
29
- // In your service:
30
- constructor(private readonly cacheService: CacheService) {}
28
+ ### TNTBaseAuthGuard
31
29
 
32
- // Basic cache operations
33
- await this.cacheService.set('key', 'value', ttlSeconds);
34
- const value = await this.cacheService.get('key');
35
- await this.cacheService.del('key');
30
+ A base implementation of the auth guard to be used across each service in the system.
36
31
 
37
- // Hash operations
38
- await this.cacheService.hset('key', 'field', 'value');
39
- const hashValue = await this.cacheService.hget('key', 'field');
40
- const allValues = await this.cacheService.hgetall('key');
41
- ```
32
+ #### Dependencies
42
33
 
43
- ## TNTBaseAuthGuard
34
+ - A JWT secret (provided via `ConfigService` or environment variable)
44
35
 
45
- A base implementation of the auth guard to be used across each service in the system
46
-
47
- ### Dependencies:
48
-
49
- - A JWT secret.
50
-
51
- ### Basic Usage
36
+ #### Usage
52
37
 
53
38
  ```typescript
54
- import { TNTBaseAuthGuard } from '@takentrade/takentrade-libs';
39
+ import {
40
+ TNTBaseAuthGuard,
41
+ Public,
42
+ Roles,
43
+ ROLES_KEY,
44
+ } from '@takentrade/takentrade-libs';
45
+ import { Reflector } from '@nestjs/core';
46
+ import { ConfigService } from '@nestjs/config';
55
47
 
56
48
  /**
57
- * Create your own auth guard extending the TNTBaseAuthGuard. We
58
- * do this to put the TNTBaseAuthGuard in the same context as the
59
- * current NestJs application for better error capturing.
49
+ * Create your own auth guard extending the TNTBaseAuthGuard.
50
+ * This ensures the guard is in the same context as your NestJS application for better error capturing.
60
51
  */
61
52
  export class AuthGuard extends TNTBaseAuthGuard {
62
53
  constructor(
@@ -74,16 +65,116 @@ export class AuthGuard extends TNTBaseAuthGuard {
74
65
  return result;
75
66
  }
76
67
  }
68
+
69
+ // In your controller
70
+ @Controller('example')
71
+ @UseGuards(AuthGuard)
72
+ export class ExampleController {
73
+ // Public endpoint (no authentication required)
74
+ @Public()
75
+ @Get('public')
76
+ publicEndpoint() {
77
+ return { message: 'This is public' };
78
+ }
79
+
80
+ // Protected endpoint (authentication required)
81
+ @Get('protected')
82
+ protectedEndpoint() {
83
+ return { message: 'This requires authentication' };
84
+ }
85
+
86
+ // Role-based access control
87
+ @Roles('admin', 'moderator')
88
+ @Get('admin')
89
+ adminEndpoint() {
90
+ return { message: 'This requires admin or moderator role' };
91
+ }
92
+ }
93
+ ```
94
+
95
+ #### Decorators
96
+
97
+ - **`@Public()`**: Marks a route as publicly accessible (bypasses authentication)
98
+ - **`@Roles(...roles: string[])`**: Restricts access to routes based on user roles
99
+
100
+ ---
101
+
102
+ ## Cache Library (`@/libs/cache`)
103
+
104
+ Redis-based caching implementation for the microservices.
105
+
106
+ ### Cache Environment Variables
107
+
108
+ ```env
109
+ REDIS_HOST=localhost # Default: localhost
110
+ REDIS_PORT=6379 # Default: 6379
111
+ REDIS_USERNAME= # Optional
112
+ REDIS_PASSWORD= # Optional
77
113
  ```
78
114
 
115
+ ### Cache Usage
116
+
117
+ ```typescript
118
+ import { CacheModule, CacheService } from '@takentrade/takentrade-libs';
119
+
120
+ @Module({
121
+ imports: [CacheModule.register()],
122
+ })
123
+ export class AppModule {}
124
+
125
+ // In your service
126
+ @Injectable()
127
+ export class MyService {
128
+ constructor(private readonly cacheService: CacheService) {}
129
+
130
+ // Basic cache operations
131
+ async example() {
132
+ // Set with TTL (time to live in seconds)
133
+ await this.cacheService.set('key', 'value', 3600); // expires in 1 hour
134
+
135
+ // Get value
136
+ const value = await this.cacheService.get('key');
137
+
138
+ // Delete key
139
+ await this.cacheService.del('key');
140
+
141
+ // Hash operations (Redis hashes)
142
+ await this.cacheService.hset('hash-key', 'field', 'value');
143
+ const hashValue = await this.cacheService.hget('hash-key', 'field');
144
+ const allValues = await this.cacheService.hgetall('hash-key');
145
+ }
146
+ }
147
+ ```
148
+
149
+ ### Cache Methods
150
+
151
+ - `set(key: string, value: any, ttlSeconds?: number)`: Set a key-value pair with optional TTL
152
+ - `get(key: string)`: Get a value by key
153
+ - `del(key: string)`: Delete a key
154
+ - `hset(key: string, field: string, value: any)`: Set a hash field
155
+ - `hget(key: string, field: string)`: Get a hash field value
156
+ - `hgetall(key: string)`: Get all fields and values from a hash
157
+
158
+ ---
159
+
79
160
  ## BullMQ Library (`@/libs/bullmq`)
80
161
 
81
162
  Background job processing library for handling long-running tasks, retries, and scheduled jobs.
82
163
 
83
- ### Usage
164
+ ### BullMQ Environment Variables
165
+
166
+ ```env
167
+ REDIS_HOST=localhost
168
+ REDIS_PORT=6379
169
+ REDIS_PASSWORD=your_password
170
+ ```
171
+
172
+ ### BullMQ Usage
84
173
 
85
174
  ```typescript
86
- import { BullmqModule } from '@/libs/bullmq';
175
+ import { BullmqModule } from '@takentrade/takentrade-libs';
176
+ import { Queue, Job } from 'bullmq';
177
+ import { Inject } from '@nestjs/common';
87
178
  import { join } from 'path';
88
179
 
89
180
  // Register in your module
@@ -103,10 +194,9 @@ import { join } from 'path';
103
194
  }),
104
195
  ],
105
196
  })
197
+ export class AppModule {}
106
198
 
107
199
  // Create a job processor (my.processor.ts)
108
- import { Job } from 'bullmq';
109
-
110
200
  export default async function myProcessor(job: Job) {
111
201
  try {
112
202
  console.log(`Processing job ${job.id}`);
@@ -124,19 +214,19 @@ export default async function myProcessor(job: Job) {
124
214
  export class MyService {
125
215
  constructor(
126
216
  @Inject('BullQueue_my-queue')
127
- private myQueue: Queue,
217
+ private myQueue: Queue
128
218
  ) {}
129
219
 
130
220
  async addJob(data: any) {
131
221
  // Regular job
132
222
  await this.myQueue.add('job-name', data);
133
223
 
134
- // Delayed job
224
+ // Delayed job (executes after 5 seconds)
135
225
  await this.myQueue.add('delayed-job', data, {
136
- delay: 5000, // 5 seconds
226
+ delay: 5000,
137
227
  });
138
228
 
139
- // Repeatable job
229
+ // Repeatable job (executes every minute)
140
230
  await this.myQueue.add('repeatable-job', data, {
141
231
  repeat: {
142
232
  every: 1000 * 60, // Every minute
@@ -146,7 +236,7 @@ export class MyService {
146
236
  }
147
237
  ```
148
238
 
149
- ### Features
239
+ ### BullMQ Features
150
240
 
151
241
  1. **Queue Management**: Create, pause, resume, and clean queues
152
242
  2. **Job Processing**: Handle long-running tasks with progress tracking
@@ -155,62 +245,571 @@ export class MyService {
155
245
  5. **Event Handling**: Monitor job completion and failures
156
246
  6. **Resource Cleanup**: Automatic cleanup on application shutdown
157
247
 
158
- ### Environment Variables
248
+ ---
249
+
250
+ ## NATS Library (`@/libs/nats`)
251
+
252
+ NATS messaging utilities for microservice communication.
253
+
254
+ ### NATS Environment Variables
159
255
 
160
256
  ```env
161
- # BullMQ Configuration
162
- REDIS_HOST=localhost
163
- REDIS_PORT=6379
164
- REDIS_PASSWORD=your_password
257
+ NATS_URL=nats://localhost:4222
258
+ NATS_SERVICE_QUEUE=service_queue # Replace 'service' with your service name (e.g., payment_queue)
259
+ ```
260
+
261
+ ### NATS Usage
262
+
263
+ ```typescript
264
+ import {
265
+ NatsSubjects,
266
+ NatsEventPattern,
267
+ NatsMessageDto,
268
+ NatsLoggingInterceptor,
269
+ NATS_CLIENT,
270
+ DEFAULT_NATS_CONFIG,
271
+ } from '@takentrade/takentrade-libs';
272
+ import { ClientProxy, Inject } from '@nestjs/common';
273
+
274
+ // Event handler (listening to events)
275
+ @Controller()
276
+ export class MyController {
277
+ @NatsEventPattern(NatsSubjects.USER_CREATED)
278
+ async handleUserCreated(@Payload() data: NatsMessageDto) {
279
+ console.log('User created:', data);
280
+ // Handle the event
281
+ }
282
+
283
+ // Using the standard EventPattern with logging
284
+ @EventPattern('custom.event')
285
+ @UseInterceptors(NatsLoggingInterceptor)
286
+ async handleCustomEvent(@Payload() data: any) {
287
+ // Handle event
288
+ }
289
+ }
290
+
291
+ // Event publisher (sending events)
292
+ @Injectable()
293
+ export class MyService {
294
+ constructor(@Inject(NATS_CLIENT) private readonly natsClient: ClientProxy) {}
295
+
296
+ async publishEvent() {
297
+ this.natsClient.emit(NatsSubjects.USER_CREATED, {
298
+ userId: '123',
299
+ email: 'user@example.com',
300
+ });
301
+ }
302
+
303
+ // RPC request-response pattern
304
+ async requestData() {
305
+ const response = await this.natsClient
306
+ .send(NatsSubjects.GET_USER_BY_ID, { userId: '123' })
307
+ .toPromise();
308
+ return response;
309
+ }
310
+ }
165
311
  ```
166
312
 
313
+ ### NATS Subjects
314
+
315
+ The library provides a comprehensive enum of NATS subjects:
316
+
317
+ ```typescript
318
+ import { NatsSubjects } from '@takentrade/takentrade-libs';
319
+
320
+ // Available subjects include:
321
+ NatsSubjects.USER_CREATED;
322
+ NatsSubjects.SUBACCOUNT_UPDATE_AMOUNT;
323
+ NatsSubjects.NOTIFICATION_SEND;
324
+ NatsSubjects.AJO_CREATE;
325
+ NatsSubjects.CHAT_GET_CONVERSATIONS;
326
+ // ... and many more
327
+ ```
328
+
329
+ ### NATS Decorators
330
+
331
+ - **`@NatsEventPattern(pattern: string)`**: Decorator for NATS event handlers with automatic logging
332
+ - **`NatsLoggingInterceptor`**: Interceptor for logging NATS events
333
+
334
+ ---
335
+
167
336
  ## Notification Client
168
337
 
169
- Shared utilities, constants, interfaces, and enums used across services.
338
+ Service for sending notifications via email, SMS, and push notifications.
339
+
340
+ ### Notification Client Usage
341
+
342
+ ```typescript
343
+ import {
344
+ NotificationClientModule,
345
+ NotificationClient,
346
+ } from '@takentrade/takentrade-libs';
347
+
348
+ @Module({
349
+ imports: [NotificationClientModule],
350
+ })
351
+ export class AppModule {}
352
+
353
+ // In your service
354
+ @Injectable()
355
+ export class MyService {
356
+ constructor(private readonly notificationClient: NotificationClient) {}
357
+
358
+ async sendNotifications() {
359
+ // Send SMS
360
+ await this.notificationClient.sendSms(
361
+ '+2341234567890',
362
+ 'Your OTP is 123456'
363
+ );
364
+
365
+ // Send Email
366
+ await this.notificationClient.sendEmailVerificationMail(
367
+ 'user@example.com',
368
+ {
369
+ name: 'John Doe',
370
+ verificationLink: 'https://example.com/verify?token=abc123',
371
+ }
372
+ );
373
+
374
+ // Send OTP Email
375
+ await this.notificationClient.sendOTPMail('user@example.com', {
376
+ name: 'John Doe',
377
+ otp: '123456',
378
+ purpose: 'phone_verification',
379
+ });
380
+
381
+ // Send Password Reset Email
382
+ await this.notificationClient.sendPasswordResetMail('user@example.com', {
383
+ name: 'John Doe',
384
+ resetLink: 'https://example.com/reset?token=abc123',
385
+ });
386
+
387
+ // Send Push Notification
388
+ await this.notificationClient.sendPushNotification({
389
+ userId: '123',
390
+ title: 'New Message',
391
+ body: 'You have a new message',
392
+ data: { messageId: '456' },
393
+ });
394
+ }
395
+ }
396
+ ```
397
+
398
+ ### Notification Client Methods
399
+
400
+ The `NotificationClient` provides numerous methods for different notification types:
401
+
402
+ - Email notifications (verification, OTP, password reset, transaction alerts, etc.)
403
+ - SMS notifications
404
+ - Push notifications
405
+ - Custom notifications
406
+
407
+ ---
408
+
409
+ ## Prisma Module
410
+
411
+ Global Prisma service module for database access.
412
+
413
+ ### Prisma Usage
414
+
415
+ ```typescript
416
+ import { PrismaModule, PrismaService } from '@takentrade/takentrade-libs';
417
+
418
+ @Module({
419
+ imports: [PrismaModule], // Global module, available everywhere
420
+ })
421
+ export class AppModule {}
422
+
423
+ // In your service
424
+ @Injectable()
425
+ export class MyService {
426
+ constructor(private readonly prisma: PrismaService) {}
427
+
428
+ async getUsers() {
429
+ return this.prisma.user.findMany();
430
+ }
431
+ }
432
+ ```
433
+
434
+ ---
435
+
436
+ ## RPC Utilities
437
+
438
+ Utilities for handling RPC (Request-Response) patterns in NATS.
439
+
440
+ ### RPC Usage
441
+
442
+ ```typescript
443
+ import { TakeNTradeRpc, TakeNTradeRpcV2 } from '@takentrade/takentrade-libs';
444
+ import { NatsContext } from '@nestjs/microservices';
445
+
446
+ // RPC handler with automatic error handling
447
+ @Controller()
448
+ export class MyController {
449
+ @MessagePattern('get.user.by.id')
450
+ async getUserById(@Payload() data: any, @Ctx() ctx: NatsContext) {
451
+ return TakeNTradeRpc.handleRequest(
452
+ this.userService.findById(data.userId),
453
+ ctx
454
+ );
455
+ }
456
+
457
+ // Alternative version that returns error directly instead of RpcException
458
+ @MessagePattern('get.user.balance')
459
+ async getUserBalance(@Payload() data: any, @Ctx() ctx: NatsContext) {
460
+ return TakeNTradeRpcV2.handleRequest(
461
+ this.userService.getBalance(data.userId),
462
+ ctx
463
+ );
464
+ }
465
+ }
170
466
 
171
- ### Usage
467
+ // RPC client (sending requests)
468
+ @Injectable()
469
+ export class MyService {
470
+ constructor(@Inject(NATS_CLIENT) private readonly natsClient: ClientProxy) {}
471
+
472
+ async getUserData(userId: string) {
473
+ const response = await TakeNTradeRpc.withReply(
474
+ this.natsClient.send('get.user.by.id', { userId })
475
+ );
476
+ return response.data;
477
+ }
478
+ }
479
+ ```
480
+
481
+ ### RPC Classes
482
+
483
+ - **`TakeNTradeRpc`**: Main RPC utility with automatic error handling that throws `RpcException`
484
+ - **`TakeNTradeRpcV2`**: Alternative RPC utility that returns error objects instead of throwing exceptions
485
+
486
+ ---
487
+
488
+ ## Common Utilities
489
+
490
+ ### Common Constants
172
491
 
173
492
  ```typescript
174
493
  import {
175
494
  NOTIFICATION_QUEUE,
176
- generateRandomString,
177
- formatPhoneNumber,
495
+ AJO_QUEUE,
496
+ PAYMENT_QUEUE,
497
+ // ... and other queue constants
498
+ } from '@takentrade/takentrade-libs';
499
+
500
+ // Queue names for BullMQ
501
+ const queueName = NOTIFICATION_QUEUE; // 'notification_queue'
502
+ ```
503
+
504
+ ### Common Enums
505
+
506
+ ```typescript
507
+ import {
178
508
  OtpPurpose,
179
- SwaggerConfig,
180
- } from '@/libs/common';
509
+ SubAccountType,
510
+ TicketStatus, // from common/enums
511
+ SupportActionType, // from common/enums
512
+ } from '@takentrade/takentrade-libs';
513
+
514
+ // OTP purposes
515
+ const purpose: OtpPurpose = OtpPurpose.PHONE_VERIFICATION;
516
+
517
+ // Subaccount types
518
+ const accountType: SubAccountType = SubAccountType.SAVINGS_ACCOUNT;
519
+ ```
520
+
521
+ ### String Utilities
181
522
 
182
- // Use constants
183
- console.log(NOTIFICATION_QUEUE); // 'notification'
523
+ ```typescript
524
+ import {
525
+ formatPhoneNumber,
526
+ maskPhoneNumber,
527
+ } from '@takentrade/takentrade-libs';
184
528
 
185
- // Use utility functions
186
- const randomStr = generateRandomString();
187
- const formattedPhone = formatPhoneNumber('+2341234567890');
529
+ // Format phone number to international format
530
+ const formatted = formatPhoneNumber('08123456789'); // '2348123456789'
188
531
 
189
- // Use enums and interfaces
190
- const purpose: OtpPurpose = OtpPurpose.REGISTRATION;
532
+ // Mask phone number for display
533
+ const masked = maskPhoneNumber('+2348123456789'); // '2348******789'
191
534
  ```
192
535
 
193
- ## Best Practices
536
+ ### Random Utilities
537
+
538
+ ```typescript
539
+ import {
540
+ generateRandomString,
541
+ RandomStringOptions,
542
+ } from '@takentrade/takentrade-libs';
543
+
544
+ // Generate random string (default: 6 digits)
545
+ const randomCode = generateRandomString(); // '123456'
546
+
547
+ // Custom options
548
+ const randomPassword = generateRandomString({
549
+ length: 12,
550
+ digits: true,
551
+ lowerCaseAlphabets: true,
552
+ upperCaseAlphabets: true,
553
+ specialChars: true,
554
+ });
555
+ ```
556
+
557
+ ### Reference Utilities
558
+
559
+ ```typescript
560
+ import { generateReference } from '@takentrade/takentrade-libs';
561
+
562
+ // Generate unique reference string
563
+ const ref = generateReference('TXN'); // 'TXN-1234567890-ABC'
564
+ ```
565
+
566
+ ### Circuit Breaker
567
+
568
+ ```typescript
569
+ import {
570
+ CircuitBreakerModule,
571
+ CircuitBreakerService,
572
+ } from '@takentrade/takentrade-libs';
573
+
574
+ @Module({
575
+ imports: [CircuitBreakerModule],
576
+ })
577
+ export class AppModule {}
578
+
579
+ @Injectable()
580
+ export class MyService {
581
+ constructor(private readonly circuitBreaker: CircuitBreakerService) {}
582
+
583
+ async callExternalService() {
584
+ const breaker = this.circuitBreaker.createBreaker('external-api', {
585
+ failureThreshold: 5,
586
+ resetTimeout: 60000,
587
+ });
588
+
589
+ if (this.circuitBreaker.isOpen('external-api')) {
590
+ throw new Error('Circuit breaker is open');
591
+ }
592
+
593
+ try {
594
+ const result = await this.externalApiCall();
595
+ this.circuitBreaker.recordSuccess('external-api');
596
+ return result;
597
+ } catch (error) {
598
+ this.circuitBreaker.recordFailure('external-api');
599
+ throw error;
600
+ }
601
+ }
602
+ }
603
+ ```
604
+
605
+ ### Health Module
606
+
607
+ ```typescript
608
+ import { HealthModule } from '@takentrade/takentrade-libs';
609
+
610
+ @Module({
611
+ imports: [HealthModule],
612
+ })
613
+ export class AppModule {}
614
+ ```
615
+
616
+ The health module provides a `/health` endpoint for service health checks.
617
+
618
+ ---
619
+
620
+ ## Utils Module
621
+
622
+ ### DTOs
623
+
624
+ ```typescript
625
+ import { PaginationDto } from '@takentrade/takentrade-libs';
626
+
627
+ // Pagination DTO for request queries
628
+ export class GetUsersDto extends PaginationDto {
629
+ @IsOptional()
630
+ @IsString()
631
+ search?: string;
632
+ }
633
+ ```
634
+
635
+ ### Pipes
636
+
637
+ ```typescript
638
+ import { PaginationQueryCleanerPipe } from '@takentrade/takentrade-libs';
639
+
640
+ @Controller('users')
641
+ export class UserController {
642
+ @Get()
643
+ async getUsers(
644
+ @Query(PaginationQueryCleanerPipe) query: any // Removes page and limit from query
645
+ ) {
646
+ // query object will not contain page and limit fields
647
+ }
648
+ }
649
+ ```
650
+
651
+ ### Interceptors
194
652
 
195
- 1. Always import from the library's main entry point (e.g., `@/libs/auth` not `@/libs/auth/src/*`)
196
- 2. Use TypeScript types and interfaces provided by the libraries
197
- 3. Follow the async/await pattern when working with services
198
- 4. Configure modules properly in your service's root module
199
- 5. Handle errors appropriately as most library functions are promise-based
653
+ ```typescript
654
+ import { ResponseInterceptor } from '@takentrade/takentrade-libs';
655
+
656
+ @Module({
657
+ providers: [
658
+ {
659
+ provide: APP_INTERCEPTOR,
660
+ useClass: ResponseInterceptor,
661
+ },
662
+ ],
663
+ })
664
+ export class AppModule {}
665
+ ```
666
+
667
+ The `ResponseInterceptor` automatically wraps all responses in a standard format:
668
+
669
+ ```json
670
+ {
671
+ "success": true,
672
+ "message": "Operation successful",
673
+ "data": {
674
+ /* your data */
675
+ },
676
+ "metadata": {
677
+ "path": "/api/users",
678
+ "requestId": "uuid",
679
+ "timestamp": "2024-01-01T00:00:00Z"
680
+ }
681
+ }
682
+ ```
683
+
684
+ ### Filters
685
+
686
+ ```typescript
687
+ import { HttpExceptionFilter } from '@takentrade/takentrade-libs';
688
+
689
+ @Module({
690
+ providers: [
691
+ {
692
+ provide: APP_FILTER,
693
+ useClass: HttpExceptionFilter,
694
+ },
695
+ ],
696
+ })
697
+ export class AppModule {}
698
+ ```
699
+
700
+ The `HttpExceptionFilter` catches all exceptions and formats them consistently.
701
+
702
+ ### Validators
703
+
704
+ ```typescript
705
+ import { ValidateNatsMessage } from '@takentrade/takentrade-libs';
706
+
707
+ @Controller()
708
+ export class MyController {
709
+ @EventPattern('user.created')
710
+ async handleUserCreated(
711
+ @Payload(ValidateNatsMessage(UserCreatedDto)) data: UserCreatedDto
712
+ ) {
713
+ // data is validated and typed
714
+ }
715
+ }
716
+ ```
717
+
718
+ ### Response Utilities
719
+
720
+ ```typescript
721
+ import { AppResponse } from '@takentrade/takentrade-libs';
722
+
723
+ @Controller()
724
+ export class MyController {
725
+ @Get('users')
726
+ async getUsers() {
727
+ const users = await this.userService.findAll();
728
+ return AppResponse.success(users, 'Users retrieved successfully');
729
+ }
730
+ }
731
+ ```
732
+
733
+ ### Pagination Utilities
734
+
735
+ ```typescript
736
+ import { paginate } from '@takentrade/takentrade-libs';
737
+
738
+ const result = paginate([1, 2, 3, 4, 5], 1, 2);
739
+ // Returns: { data: [1, 2], total: 5, page: 1, limit: 2, totalPages: 3 }
740
+ ```
741
+
742
+ ### OTP Utilities
743
+
744
+ ```typescript
745
+ import { generateOTP, verifyOTP } from '@takentrade/takentrade-libs';
746
+
747
+ // Generate OTP
748
+ const otp = generateOTP(6); // 6-digit OTP
749
+
750
+ // Verify OTP (with expiration)
751
+ const isValid = verifyOTP(otp, storedOtp, expirationTime);
752
+ ```
753
+
754
+ ### Configuration Utilities
755
+
756
+ ```typescript
757
+ import { getConfiguration } from '@takentrade/takentrade-libs';
758
+
759
+ const config = getConfiguration();
760
+ // Returns typed configuration object
761
+ ```
762
+
763
+ ---
200
764
 
201
765
  ## Configuration
202
766
 
203
767
  Most libraries require configuration through environment variables. Ensure these are set in your service's `.env` file:
204
768
 
205
769
  ```env
206
- # Cache Configuration
770
+ # Cache & BullMQ Configuration
207
771
  REDIS_HOST=localhost
208
772
  REDIS_PORT=6379
773
+ REDIS_USERNAME=
209
774
  REDIS_PASSWORD=your_password
210
775
 
211
776
  # NATS Configuration
212
777
  NATS_URL=nats://localhost:4222
213
- NATS_SERVICE_QUEUE=service_queue # Replace 'service' with your service name (e.g., payment_queue)
778
+ NATS_SERVICE_QUEUE=service_queue # Replace 'service' with your service name
779
+
780
+ # JWT Configuration
781
+ JWT_SECRET=your_jwt_secret
214
782
 
215
- # Other configurations...
783
+ # Database (for Prisma)
784
+ DATABASE_URL=postgresql://user:password@localhost:5432/dbname
216
785
  ```
786
+
787
+ ---
788
+
789
+ ## Best Practices
790
+
791
+ 1. **Always import from the library's main entry point**: Use `@takentrade/takentrade-libs` instead of internal paths
792
+ 2. **Use TypeScript types and interfaces**: Take advantage of the provided types for better type safety
793
+ 3. **Follow async/await pattern**: Most library functions are promise-based
794
+ 4. **Configure modules properly**: Register modules in your service's root module
795
+ 5. **Handle errors appropriately**: Use the provided filters and interceptors for consistent error handling
796
+ 6. **Use constants for NATS subjects**: Always use `NatsSubjects` enum instead of hardcoding subject strings
797
+ 7. **Leverage RPC utilities**: Use `TakeNTradeRpc` for consistent RPC error handling
798
+
799
+ ---
800
+
801
+ ## Exports
802
+
803
+ The package exports the following sub-paths:
804
+
805
+ - `@takentrade/takentrade-libs` - Main entry point
806
+ - `@takentrade/takentrade-libs/bullmq` - BullMQ module
807
+ - `@takentrade/takentrade-libs/cache` - Cache module
808
+ - `@takentrade/takentrade-libs/common` - Common utilities
809
+ - `@takentrade/takentrade-libs/nats` - NATS utilities
810
+
811
+ ---
812
+
813
+ ## License
814
+
815
+ MIT