servcraft 0.1.0 → 0.1.3

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 (217) hide show
  1. package/.claude/settings.local.json +30 -0
  2. package/.github/CODEOWNERS +18 -0
  3. package/.github/PULL_REQUEST_TEMPLATE.md +46 -0
  4. package/.github/dependabot.yml +59 -0
  5. package/.github/workflows/ci.yml +188 -0
  6. package/.github/workflows/release.yml +195 -0
  7. package/AUDIT.md +602 -0
  8. package/LICENSE +21 -0
  9. package/README.md +1102 -1
  10. package/dist/cli/index.cjs +2026 -2168
  11. package/dist/cli/index.cjs.map +1 -1
  12. package/dist/cli/index.js +2026 -2168
  13. package/dist/cli/index.js.map +1 -1
  14. package/dist/index.cjs +595 -616
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +114 -52
  17. package/dist/index.d.ts +114 -52
  18. package/dist/index.js +595 -616
  19. package/dist/index.js.map +1 -1
  20. package/docs/CLI-001_MULTI_DB_PLAN.md +546 -0
  21. package/docs/DATABASE_MULTI_ORM.md +399 -0
  22. package/docs/PHASE1_BREAKDOWN.md +346 -0
  23. package/docs/PROGRESS.md +550 -0
  24. package/docs/modules/ANALYTICS.md +226 -0
  25. package/docs/modules/API-VERSIONING.md +252 -0
  26. package/docs/modules/AUDIT.md +192 -0
  27. package/docs/modules/AUTH.md +431 -0
  28. package/docs/modules/CACHE.md +346 -0
  29. package/docs/modules/EMAIL.md +254 -0
  30. package/docs/modules/FEATURE-FLAG.md +291 -0
  31. package/docs/modules/I18N.md +294 -0
  32. package/docs/modules/MEDIA-PROCESSING.md +281 -0
  33. package/docs/modules/MFA.md +266 -0
  34. package/docs/modules/NOTIFICATION.md +311 -0
  35. package/docs/modules/OAUTH.md +237 -0
  36. package/docs/modules/PAYMENT.md +804 -0
  37. package/docs/modules/QUEUE.md +540 -0
  38. package/docs/modules/RATE-LIMIT.md +339 -0
  39. package/docs/modules/SEARCH.md +288 -0
  40. package/docs/modules/SECURITY.md +327 -0
  41. package/docs/modules/SESSION.md +382 -0
  42. package/docs/modules/SWAGGER.md +305 -0
  43. package/docs/modules/UPLOAD.md +296 -0
  44. package/docs/modules/USER.md +505 -0
  45. package/docs/modules/VALIDATION.md +294 -0
  46. package/docs/modules/WEBHOOK.md +270 -0
  47. package/docs/modules/WEBSOCKET.md +691 -0
  48. package/package.json +53 -38
  49. package/prisma/schema.prisma +395 -1
  50. package/src/cli/commands/add-module.ts +520 -87
  51. package/src/cli/commands/db.ts +3 -4
  52. package/src/cli/commands/docs.ts +256 -6
  53. package/src/cli/commands/generate.ts +12 -19
  54. package/src/cli/commands/init.ts +384 -214
  55. package/src/cli/index.ts +0 -4
  56. package/src/cli/templates/repository.ts +6 -1
  57. package/src/cli/templates/routes.ts +6 -21
  58. package/src/cli/utils/docs-generator.ts +6 -7
  59. package/src/cli/utils/env-manager.ts +717 -0
  60. package/src/cli/utils/field-parser.ts +16 -7
  61. package/src/cli/utils/interactive-prompt.ts +223 -0
  62. package/src/cli/utils/template-manager.ts +346 -0
  63. package/src/config/database.config.ts +183 -0
  64. package/src/config/env.ts +0 -10
  65. package/src/config/index.ts +0 -14
  66. package/src/core/server.ts +1 -1
  67. package/src/database/adapters/mongoose.adapter.ts +132 -0
  68. package/src/database/adapters/prisma.adapter.ts +118 -0
  69. package/src/database/connection.ts +190 -0
  70. package/src/database/interfaces/database.interface.ts +85 -0
  71. package/src/database/interfaces/index.ts +7 -0
  72. package/src/database/interfaces/repository.interface.ts +129 -0
  73. package/src/database/models/mongoose/index.ts +7 -0
  74. package/src/database/models/mongoose/payment.schema.ts +347 -0
  75. package/src/database/models/mongoose/user.schema.ts +154 -0
  76. package/src/database/prisma.ts +1 -4
  77. package/src/database/redis.ts +101 -0
  78. package/src/database/repositories/mongoose/index.ts +7 -0
  79. package/src/database/repositories/mongoose/payment.repository.ts +380 -0
  80. package/src/database/repositories/mongoose/user.repository.ts +255 -0
  81. package/src/database/seed.ts +6 -1
  82. package/src/index.ts +9 -20
  83. package/src/middleware/security.ts +2 -6
  84. package/src/modules/analytics/analytics.routes.ts +80 -0
  85. package/src/modules/analytics/analytics.service.ts +364 -0
  86. package/src/modules/analytics/index.ts +18 -0
  87. package/src/modules/analytics/types.ts +180 -0
  88. package/src/modules/api-versioning/index.ts +15 -0
  89. package/src/modules/api-versioning/types.ts +86 -0
  90. package/src/modules/api-versioning/versioning.middleware.ts +120 -0
  91. package/src/modules/api-versioning/versioning.routes.ts +54 -0
  92. package/src/modules/api-versioning/versioning.service.ts +189 -0
  93. package/src/modules/audit/audit.repository.ts +206 -0
  94. package/src/modules/audit/audit.service.ts +27 -59
  95. package/src/modules/auth/auth.controller.ts +2 -2
  96. package/src/modules/auth/auth.middleware.ts +3 -9
  97. package/src/modules/auth/auth.routes.ts +10 -107
  98. package/src/modules/auth/auth.service.ts +126 -23
  99. package/src/modules/auth/index.ts +3 -4
  100. package/src/modules/cache/cache.service.ts +367 -0
  101. package/src/modules/cache/index.ts +10 -0
  102. package/src/modules/cache/types.ts +44 -0
  103. package/src/modules/email/email.service.ts +3 -10
  104. package/src/modules/email/templates.ts +2 -8
  105. package/src/modules/feature-flag/feature-flag.repository.ts +303 -0
  106. package/src/modules/feature-flag/feature-flag.routes.ts +247 -0
  107. package/src/modules/feature-flag/feature-flag.service.ts +566 -0
  108. package/src/modules/feature-flag/index.ts +20 -0
  109. package/src/modules/feature-flag/types.ts +192 -0
  110. package/src/modules/i18n/i18n.middleware.ts +186 -0
  111. package/src/modules/i18n/i18n.routes.ts +191 -0
  112. package/src/modules/i18n/i18n.service.ts +456 -0
  113. package/src/modules/i18n/index.ts +18 -0
  114. package/src/modules/i18n/types.ts +118 -0
  115. package/src/modules/media-processing/index.ts +17 -0
  116. package/src/modules/media-processing/media-processing.routes.ts +111 -0
  117. package/src/modules/media-processing/media-processing.service.ts +245 -0
  118. package/src/modules/media-processing/types.ts +156 -0
  119. package/src/modules/mfa/index.ts +20 -0
  120. package/src/modules/mfa/mfa.repository.ts +206 -0
  121. package/src/modules/mfa/mfa.routes.ts +595 -0
  122. package/src/modules/mfa/mfa.service.ts +572 -0
  123. package/src/modules/mfa/totp.ts +150 -0
  124. package/src/modules/mfa/types.ts +57 -0
  125. package/src/modules/notification/index.ts +20 -0
  126. package/src/modules/notification/notification.repository.ts +356 -0
  127. package/src/modules/notification/notification.service.ts +483 -0
  128. package/src/modules/notification/types.ts +119 -0
  129. package/src/modules/oauth/index.ts +20 -0
  130. package/src/modules/oauth/oauth.repository.ts +219 -0
  131. package/src/modules/oauth/oauth.routes.ts +446 -0
  132. package/src/modules/oauth/oauth.service.ts +293 -0
  133. package/src/modules/oauth/providers/apple.provider.ts +250 -0
  134. package/src/modules/oauth/providers/facebook.provider.ts +181 -0
  135. package/src/modules/oauth/providers/github.provider.ts +248 -0
  136. package/src/modules/oauth/providers/google.provider.ts +189 -0
  137. package/src/modules/oauth/providers/twitter.provider.ts +214 -0
  138. package/src/modules/oauth/types.ts +94 -0
  139. package/src/modules/payment/index.ts +19 -0
  140. package/src/modules/payment/payment.repository.ts +733 -0
  141. package/src/modules/payment/payment.routes.ts +390 -0
  142. package/src/modules/payment/payment.service.ts +354 -0
  143. package/src/modules/payment/providers/mobile-money.provider.ts +274 -0
  144. package/src/modules/payment/providers/paypal.provider.ts +190 -0
  145. package/src/modules/payment/providers/stripe.provider.ts +215 -0
  146. package/src/modules/payment/types.ts +140 -0
  147. package/src/modules/queue/cron.ts +438 -0
  148. package/src/modules/queue/index.ts +87 -0
  149. package/src/modules/queue/queue.routes.ts +600 -0
  150. package/src/modules/queue/queue.service.ts +842 -0
  151. package/src/modules/queue/types.ts +222 -0
  152. package/src/modules/queue/workers.ts +366 -0
  153. package/src/modules/rate-limit/index.ts +59 -0
  154. package/src/modules/rate-limit/rate-limit.middleware.ts +134 -0
  155. package/src/modules/rate-limit/rate-limit.routes.ts +269 -0
  156. package/src/modules/rate-limit/rate-limit.service.ts +348 -0
  157. package/src/modules/rate-limit/stores/memory.store.ts +165 -0
  158. package/src/modules/rate-limit/stores/redis.store.ts +322 -0
  159. package/src/modules/rate-limit/types.ts +153 -0
  160. package/src/modules/search/adapters/elasticsearch.adapter.ts +326 -0
  161. package/src/modules/search/adapters/meilisearch.adapter.ts +261 -0
  162. package/src/modules/search/adapters/memory.adapter.ts +278 -0
  163. package/src/modules/search/index.ts +21 -0
  164. package/src/modules/search/search.service.ts +234 -0
  165. package/src/modules/search/types.ts +214 -0
  166. package/src/modules/security/index.ts +40 -0
  167. package/src/modules/security/sanitize.ts +223 -0
  168. package/src/modules/security/security-audit.service.ts +388 -0
  169. package/src/modules/security/security.middleware.ts +398 -0
  170. package/src/modules/session/index.ts +3 -0
  171. package/src/modules/session/session.repository.ts +159 -0
  172. package/src/modules/session/session.service.ts +340 -0
  173. package/src/modules/session/types.ts +38 -0
  174. package/src/modules/swagger/index.ts +7 -1
  175. package/src/modules/swagger/schema-builder.ts +16 -4
  176. package/src/modules/swagger/swagger.service.ts +9 -10
  177. package/src/modules/swagger/types.ts +0 -2
  178. package/src/modules/upload/index.ts +14 -0
  179. package/src/modules/upload/types.ts +83 -0
  180. package/src/modules/upload/upload.repository.ts +199 -0
  181. package/src/modules/upload/upload.routes.ts +311 -0
  182. package/src/modules/upload/upload.service.ts +448 -0
  183. package/src/modules/user/index.ts +3 -3
  184. package/src/modules/user/user.controller.ts +15 -9
  185. package/src/modules/user/user.repository.ts +237 -113
  186. package/src/modules/user/user.routes.ts +39 -164
  187. package/src/modules/user/user.service.ts +4 -3
  188. package/src/modules/validation/validator.ts +12 -17
  189. package/src/modules/webhook/index.ts +91 -0
  190. package/src/modules/webhook/retry.ts +196 -0
  191. package/src/modules/webhook/signature.ts +135 -0
  192. package/src/modules/webhook/types.ts +181 -0
  193. package/src/modules/webhook/webhook.repository.ts +358 -0
  194. package/src/modules/webhook/webhook.routes.ts +442 -0
  195. package/src/modules/webhook/webhook.service.ts +457 -0
  196. package/src/modules/websocket/features.ts +504 -0
  197. package/src/modules/websocket/index.ts +106 -0
  198. package/src/modules/websocket/middlewares.ts +298 -0
  199. package/src/modules/websocket/types.ts +181 -0
  200. package/src/modules/websocket/websocket.service.ts +692 -0
  201. package/src/utils/errors.ts +7 -0
  202. package/src/utils/pagination.ts +4 -1
  203. package/tests/helpers/db-check.ts +79 -0
  204. package/tests/integration/auth-redis.test.ts +94 -0
  205. package/tests/integration/cache-redis.test.ts +387 -0
  206. package/tests/integration/mongoose-repositories.test.ts +410 -0
  207. package/tests/integration/payment-prisma.test.ts +637 -0
  208. package/tests/integration/queue-bullmq.test.ts +417 -0
  209. package/tests/integration/user-prisma.test.ts +441 -0
  210. package/tests/integration/websocket-socketio.test.ts +552 -0
  211. package/tests/setup.ts +11 -9
  212. package/vitest.config.ts +3 -8
  213. package/npm-cache/_cacache/content-v2/sha512/1c/d0/03440d500a0487621aad1d6402978340698976602046db8e24fa03c01ee6c022c69b0582f969042d9442ee876ac35c038e960dd427d1e622fa24b8eb7dba +0 -0
  214. package/npm-cache/_cacache/content-v2/sha512/42/55/28b493ca491833e5aab0e9c3108d29ab3f36c248ca88f45d4630674fce9130959e56ae308797ac2b6328fa7f09a610b9550ed09cb971d039876d293fc69d +0 -0
  215. package/npm-cache/_cacache/content-v2/sha512/e0/12/f360dc9315ee5f17844a0c8c233ee6bf7c30837c4a02ea0d56c61c7f7ab21c0e958e50ed2c57c59f983c762b93056778c9009b2398ffc26def0183999b13 +0 -0
  216. package/npm-cache/_cacache/content-v2/sha512/ed/b0/fae1161902898f4c913c67d7f6cdf6be0665aec3b389b9c4f4f0a101ca1da59badf1b59c4e0030f5223023b8d63cfe501c46a32c20c895d4fb3f11ca2232 +0 -0
  217. package/npm-cache/_cacache/index-v5/58/94/c2cba79e0f16b4c10e95a87e32255741149e8222cc314a476aab67c39cc0 +0 -5
package/README.md CHANGED
@@ -2,6 +2,38 @@
2
2
 
3
3
  A modular, production-ready Node.js backend framework built with TypeScript, Fastify, and Prisma.
4
4
 
5
+ [![npm version](https://badge.fury.io/js/servcraft.svg)](https://www.npmjs.com/package/servcraft)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ # Install globally (recommended for CLI)
12
+ npm install -g servcraft
13
+
14
+ # Or use with npx
15
+ npx servcraft init my-project
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ ```bash
21
+ # Create a new project
22
+ servcraft init my-app
23
+
24
+ # Navigate to project
25
+ cd my-app
26
+
27
+ # Install dependencies
28
+ npm install
29
+
30
+ # Setup database
31
+ npm run db:push
32
+
33
+ # Start development server
34
+ npm run dev
35
+ ```
36
+
5
37
  ## Features
6
38
 
7
39
  - **Core Server**: Fastify with graceful shutdown, health checks
@@ -10,11 +42,174 @@ A modular, production-ready Node.js backend framework built with TypeScript, Fas
10
42
  - **Validation**: Zod/Joi/Yup support
11
43
  - **Database**: Prisma ORM (PostgreSQL, MySQL, SQLite)
12
44
  - **Email**: SMTP with Handlebars templates
13
- - **Security**: Helmet, CORS, Rate limiting
45
+ - **Security**: Helmet, CORS, Advanced rate limiting (fixed/sliding window, token bucket)
14
46
  - **Logging**: Pino structured logs + Audit trail
15
47
  - **Docker**: Ready for containerization
16
48
  - **CLI**: Generate modules, controllers, services
17
49
 
50
+ ## How to Use the Services
51
+
52
+ The modules (Rate Limiting, Webhooks, Queue, Websockets, etc.) are **reusable services** that you integrate into your own routes and controllers. They are NOT standalone user-facing endpoints.
53
+
54
+ ### Quick Integration Example
55
+
56
+ ```typescript
57
+ // YOUR controller (e.g., src/modules/post/post.controller.ts)
58
+ import { webhookService } from '../webhook';
59
+ import { queueService, emailWorker } from '../queue';
60
+ import { wsService } from '../websocket';
61
+ import { strictRateLimit } from '../rate-limit';
62
+
63
+ class PostController {
64
+ async createPost(req, res) {
65
+ // 1. Create the post
66
+ const post = await db.post.create(req.body);
67
+
68
+ // 2. Use webhook service - notify external systems
69
+ await webhookService.publishEvent('post.created', {
70
+ postId: post.id,
71
+ title: post.title,
72
+ author: req.user.id
73
+ });
74
+
75
+ // 3. Use queue service - send emails asynchronously
76
+ await queueService.addJob('emails', 'send-email', {
77
+ to: 'admin@example.com',
78
+ subject: 'New Post Created',
79
+ html: `<p>${post.title} was published</p>`
80
+ });
81
+
82
+ // 4. Use websocket service - real-time notification
83
+ await wsService.broadcastToAll('post:new', post);
84
+
85
+ // 5. Use cache service - invalidate cache
86
+ await cacheService.delete('posts:latest');
87
+
88
+ res.json(post);
89
+ }
90
+ }
91
+
92
+ // Apply rate limiting to YOUR routes
93
+ app.post('/api/posts', strictRateLimit, postController.createPost);
94
+ app.get('/api/posts', standardRateLimit, postController.list);
95
+ ```
96
+
97
+ ### Available Services
98
+
99
+ All services are available as importable modules in your code:
100
+
101
+ | Service | Import | Usage |
102
+ |---------|--------|-------|
103
+ | **Rate Limiting** | `import { strictRateLimit, createRateLimiter } from './modules/rate-limit'` | Apply as middleware on routes |
104
+ | **Webhooks** | `import { WebhookService } from './modules/webhook'` | Publish events to external URLs |
105
+ | **Queue/Jobs** | `import { QueueService, emailWorker } from './modules/queue'` | Background tasks & cron jobs |
106
+ | **Websockets** | `import { WebSocketService, ChatFeature } from './modules/websocket'` | Real-time communication |
107
+ | **Cache** | `import { CacheService } from './modules/cache'` | Redis caching |
108
+ | **MFA** | `import { MFAService } from './modules/mfa'` | Two-factor authentication |
109
+ | **OAuth** | `import { OAuthService } from './modules/oauth'` | Social login |
110
+ | **Payments** | `import { PaymentService } from './modules/payment'` | Process payments |
111
+ | **Upload** | `import { UploadService } from './modules/upload'` | File uploads |
112
+ | **Notifications** | `import { NotificationService } from './modules/notification'` | Send notifications |
113
+ | **Search** | `import { SearchService, ElasticsearchAdapter } from './modules/search'` | Full-text search with Elasticsearch/Meilisearch |
114
+ | **i18n** | `import { I18nService, createI18nMiddleware } from './modules/i18n'` | Multi-language support & localization |
115
+ | **Feature Flags** | `import { FeatureFlagService, createFeatureFlagRoutes } from './modules/feature-flag'` | A/B testing & progressive rollout |
116
+ | **Analytics** | `import { AnalyticsService, createAnalyticsRoutes } from './modules/analytics'` | Prometheus metrics & event tracking |
117
+ | **Media Processing** | `import { MediaProcessingService } from './modules/media-processing'` | Image/video processing with FFmpeg |
118
+ | **API Versioning** | `import { VersioningService, createVersioningMiddleware } from './modules/api-versioning'` | Multiple API versions support |
119
+
120
+ ### Common Integration Patterns
121
+
122
+ **Pattern 1: E-commerce Order Flow**
123
+ ```typescript
124
+ async createOrder(req, res) {
125
+ const order = await db.order.create(req.body);
126
+
127
+ // Send webhook to inventory system
128
+ await webhookService.publishEvent('order.created', order);
129
+
130
+ // Queue payment processing
131
+ await queueService.addJob('payments', 'process-payment', {
132
+ orderId: order.id,
133
+ amount: order.total
134
+ });
135
+
136
+ // Real-time update to user
137
+ await wsService.broadcastToUsers([order.userId], 'order:created', order);
138
+
139
+ // Queue confirmation email (delayed 5 minutes)
140
+ await queueService.addJob('emails', 'send-email', {
141
+ to: order.email,
142
+ template: 'order-confirmation',
143
+ data: order
144
+ }, { delay: 5 * 60 * 1000 });
145
+
146
+ res.json(order);
147
+ }
148
+ ```
149
+
150
+ **Pattern 2: User Registration**
151
+ ```typescript
152
+ async register(req, res) {
153
+ const user = await db.user.create(req.body);
154
+
155
+ // Generate MFA secret
156
+ const mfaSetup = await mfaService.setupTOTP(user.id, 'MyApp');
157
+
158
+ // Queue welcome email
159
+ await queueService.addJob('emails', 'send-email', {
160
+ to: user.email,
161
+ subject: 'Welcome!',
162
+ template: 'welcome',
163
+ data: { user, mfaQR: mfaSetup.qrCode }
164
+ });
165
+
166
+ // Webhook to CRM
167
+ await webhookService.publishEvent('user.registered', user);
168
+
169
+ res.json({ user, mfaSetup });
170
+ }
171
+ ```
172
+
173
+ **Pattern 3: Content Moderation**
174
+ ```typescript
175
+ async uploadImage(req, res) {
176
+ // Upload file
177
+ const file = await uploadService.upload(req.file, {
178
+ allowedTypes: ['image/jpeg', 'image/png'],
179
+ maxSize: 5 * 1024 * 1024
180
+ });
181
+
182
+ // Queue image processing
183
+ await queueService.addJob('images', 'process-image', {
184
+ source: file.path,
185
+ operations: [
186
+ { type: 'resize', options: { width: 800 } },
187
+ { type: 'watermark', options: { text: '© MyApp' } },
188
+ { type: 'compress', options: { quality: 80 } }
189
+ ],
190
+ output: `/processed/${file.id}.jpg`
191
+ });
192
+
193
+ res.json(file);
194
+ }
195
+ ```
196
+
197
+ ### Auto-Generated Documentation
198
+
199
+ Yes! Use the built-in docs generator:
200
+
201
+ ```bash
202
+ # Generate API documentation automatically
203
+ servcraft docs generate
204
+
205
+ # This will scan all your routes and generate:
206
+ # - OpenAPI/Swagger spec
207
+ # - Endpoint list
208
+ # - Request/response examples
209
+ ```
210
+
211
+ The `src/cli/commands/docs.ts` file I created does this automatically!
212
+
18
213
  ## Quick Start
19
214
 
20
215
  ### Create a new project
@@ -79,9 +274,79 @@ servcraft add email # Email service
79
274
  servcraft add audit # Audit logging
80
275
  servcraft add cache # Redis cache
81
276
  servcraft add upload # File uploads
277
+ servcraft add rate-limit # Advanced rate limiting
278
+ servcraft add webhook # Outgoing webhooks
279
+ servcraft add queue # Background jobs & queues
280
+ servcraft add websocket # Real-time with Socket.io
281
+ servcraft add search # Elasticsearch/Meilisearch search
282
+ servcraft add i18n # Multi-language support
283
+ servcraft add feature-flag # Feature flags & A/B testing
284
+ servcraft add analytics # Prometheus metrics & tracking
285
+ servcraft add media-processing # Image/video processing
286
+ servcraft add api-versioning # API version management
82
287
  servcraft add --list # Show all modules
83
288
  ```
84
289
 
290
+ **Automatic Environment Configuration:**
291
+
292
+ When you add a module, ServCraft automatically:
293
+ - ✅ Adds required environment variables to your `.env` file
294
+ - ✅ Preserves existing variables (no overwrites)
295
+ - ✅ Updates `.env.example` with placeholder values
296
+ - ✅ Shows which variables need configuration
297
+ - ✅ Provides helpful comments for each variable
298
+
299
+ **Example:**
300
+
301
+ ```bash
302
+ $ servcraft add search
303
+
304
+ ✓ Module 'Search' added successfully!
305
+
306
+ 📁 Files created:
307
+ ✓ src/modules/search/types.ts
308
+ ✓ src/modules/search/search.service.ts
309
+ ✓ src/modules/search/index.ts
310
+
311
+ ✓ Environment variables updated!
312
+
313
+ ✅ Added to .env:
314
+ ✓ SEARCH_ENGINE
315
+ ✓ ELASTICSEARCH_NODE
316
+ ✓ MEILISEARCH_HOST
317
+
318
+ ⏭️ Already in .env (skipped):
319
+ ℹ REDIS_HOST
320
+
321
+ ⚠️ Required configuration:
322
+ ⚠ ELASTICSEARCH_USERNAME - Please configure this variable
323
+ ⚠ ELASTICSEARCH_PASSWORD - Please configure this variable
324
+
325
+ 📌 Next steps:
326
+ 1. Configure environment variables in .env (if needed)
327
+ 2. Register the module in your main app file
328
+ 3. Run database migrations if needed
329
+ ```
330
+
331
+ Your `.env` file will be updated with:
332
+
333
+ ```env
334
+ # Search Configuration (Elasticsearch)
335
+ SEARCH_ENGINE=memory
336
+ # Elasticsearch node URL
337
+ # ELASTICSEARCH_NODE=http://localhost:9200
338
+ # Elasticsearch username (optional)
339
+ # ELASTICSEARCH_USERNAME=
340
+ # Elasticsearch password (optional)
341
+ # ELASTICSEARCH_PASSWORD=
342
+
343
+ # Search Configuration (Meilisearch)
344
+ # Meilisearch host URL
345
+ # MEILISEARCH_HOST=http://localhost:7700
346
+ # Meilisearch API key (optional)
347
+ # MEILISEARCH_API_KEY=
348
+ ```
349
+
85
350
  ### Database commands
86
351
 
87
352
  ```bash
@@ -164,6 +429,842 @@ SMTP_PASS=pass
164
429
  LOG_LEVEL=info
165
430
  ```
166
431
 
432
+ ## Modules
433
+
434
+ ### Rate Limiting
435
+
436
+ Advanced rate limiting with multiple algorithms and strategies:
437
+
438
+ **Features:**
439
+ - Multiple algorithms: Fixed Window, Sliding Window, Token Bucket
440
+ - Storage options: In-memory or Redis (for distributed systems)
441
+ - Flexible key generation: IP, User ID, API Key, or custom
442
+ - Whitelist/Blacklist support
443
+ - Custom limits per endpoint or user role
444
+ - Standard rate limit headers (X-RateLimit-*)
445
+ - Admin API for management
446
+
447
+ **Usage:**
448
+
449
+ ```typescript
450
+ import {
451
+ createRateLimiter,
452
+ strictRateLimit,
453
+ authRateLimit,
454
+ userRateLimit
455
+ } from './modules/rate-limit';
456
+
457
+ // Global rate limiter
458
+ app.use(createRateLimiter({
459
+ max: 100, // 100 requests
460
+ windowMs: 60 * 1000, // per minute
461
+ algorithm: 'sliding-window' // or 'fixed-window', 'token-bucket'
462
+ }));
463
+
464
+ // Pre-configured limiters
465
+ app.post('/login', authRateLimit, loginHandler); // 5 req/15min
466
+ app.post('/sensitive', strictRateLimit, sensitiveHandler); // 5 req/min
467
+
468
+ // Custom limiters
469
+ app.get('/api/data',
470
+ userRateLimit(1000, 60 * 60 * 1000), // 1000 req/hour per user
471
+ dataHandler
472
+ );
473
+
474
+ // Per-endpoint limits
475
+ app.use(createRateLimiter({
476
+ max: 100,
477
+ windowMs: 60 * 1000,
478
+ customLimits: {
479
+ 'POST:/api/expensive': { max: 10, windowMs: 60 * 1000 },
480
+ 'role:admin': { max: 10000, windowMs: 60 * 1000 }
481
+ }
482
+ }));
483
+ ```
484
+
485
+ **Admin Routes:**
486
+
487
+ ```
488
+ GET /rate-limit/info/:key Get rate limit info
489
+ POST /rate-limit/reset/:key Reset rate limit
490
+ GET /rate-limit/config Get configuration
491
+ POST /rate-limit/whitelist Add IP to whitelist
492
+ DELETE /rate-limit/whitelist/:ip Remove from whitelist
493
+ POST /rate-limit/blacklist Add IP to blacklist
494
+ DELETE /rate-limit/blacklist/:ip Remove from blacklist
495
+ POST /rate-limit/clear Clear all data
496
+ POST /rate-limit/cleanup Cleanup expired entries
497
+ ```
498
+
499
+ **Redis Storage (for multi-instance):**
500
+
501
+ ```typescript
502
+ import { RateLimitService, RedisStore } from './modules/rate-limit';
503
+ import Redis from 'ioredis';
504
+
505
+ const redis = new Redis();
506
+ const store = new RedisStore(redis);
507
+ const service = new RateLimitService({ max: 100, windowMs: 60000 }, store);
508
+ ```
509
+
510
+ ### Webhooks Sortants
511
+
512
+ Send events to external URLs with automatic retry, HMAC signatures, and monitoring:
513
+
514
+ **Features:**
515
+ - Automatic retry with exponential backoff
516
+ - HMAC-SHA256 signature verification
517
+ - Delivery tracking and monitoring
518
+ - Multiple retry strategies
519
+ - Event filtering by type
520
+ - Webhook endpoint management
521
+
522
+ **Usage:**
523
+
524
+ ```typescript
525
+ import { WebhookService, createWebhookRoutes } from './modules/webhook';
526
+
527
+ // Create service
528
+ const webhookService = new WebhookService({
529
+ maxRetries: 5,
530
+ timeout: 10000,
531
+ enableSignature: true
532
+ });
533
+
534
+ // Create endpoint
535
+ const endpoint = await webhookService.createEndpoint({
536
+ url: 'https://example.com/webhook',
537
+ events: ['user.created', 'order.completed'],
538
+ description: 'Production webhook'
539
+ });
540
+
541
+ // Publish event
542
+ await webhookService.publishEvent('user.created', {
543
+ userId: '123',
544
+ email: 'user@example.com',
545
+ name: 'John Doe'
546
+ });
547
+
548
+ // Add routes
549
+ app.use('/api/webhooks', authMiddleware, createWebhookRoutes(webhookService));
550
+ ```
551
+
552
+ **Signature Verification (Recipient Side):**
553
+
554
+ ```typescript
555
+ import { verifyWebhookSignature } from './modules/webhook';
556
+
557
+ app.post('/webhook', (req, res) => {
558
+ const signature = req.headers['x-webhook-signature'];
559
+ const secret = 'your-webhook-secret';
560
+
561
+ if (!verifyWebhookSignature(req.body, signature, secret)) {
562
+ return res.status(401).json({ error: 'Invalid signature' });
563
+ }
564
+
565
+ // Process webhook
566
+ res.json({ received: true });
567
+ });
568
+ ```
569
+
570
+ **Admin Routes:**
571
+
572
+ ```
573
+ POST /webhooks/endpoints Create endpoint
574
+ GET /webhooks/endpoints List endpoints
575
+ GET /webhooks/endpoints/:id Get endpoint
576
+ PATCH /webhooks/endpoints/:id Update endpoint
577
+ DELETE /webhooks/endpoints/:id Delete endpoint
578
+ POST /webhooks/endpoints/:id/rotate-secret Rotate secret
579
+ POST /webhooks/events Publish event
580
+ GET /webhooks/deliveries List deliveries
581
+ GET /webhooks/deliveries/:id Get delivery
582
+ GET /webhooks/deliveries/:id/attempts Get attempts
583
+ POST /webhooks/deliveries/:id/retry Retry delivery
584
+ GET /webhooks/stats Get statistics
585
+ POST /webhooks/cleanup Cleanup old data
586
+ ```
587
+
588
+ **Retry Strategies:**
589
+
590
+ ```typescript
591
+ import {
592
+ ExponentialBackoffStrategy,
593
+ LinearBackoffStrategy,
594
+ FixedDelayStrategy
595
+ } from './modules/webhook';
596
+
597
+ // Exponential: 1s, 2s, 4s, 8s, 16s
598
+ const exponential = new ExponentialBackoffStrategy(1000, 60000, 2, 5);
599
+
600
+ // Linear: 5s, 10s, 15s
601
+ const linear = new LinearBackoffStrategy(5000, 3);
602
+
603
+ // Fixed: 10s, 10s, 10s
604
+ const fixed = new FixedDelayStrategy(10000, 3);
605
+ ```
606
+
607
+ ### Queue/Jobs (Background Tasks)
608
+
609
+ Background job processing with Bull/BullMQ, cron scheduling, and pre-built workers:
610
+
611
+ **Features:**
612
+ - Background job processing
613
+ - Priority queues
614
+ - Automatic retry with backoff
615
+ - Cron-based scheduling
616
+ - Job progress tracking
617
+ - Real-time monitoring & metrics
618
+ - 10+ pre-built workers
619
+
620
+ **Usage:**
621
+
622
+ ```typescript
623
+ import {
624
+ QueueService,
625
+ CronJobManager,
626
+ emailWorker,
627
+ imageProcessingWorker,
628
+ CronSchedules
629
+ } from './modules/queue';
630
+
631
+ // Create queue service
632
+ const queueService = new QueueService({
633
+ redis: { host: 'localhost', port: 6379 },
634
+ metrics: true
635
+ });
636
+
637
+ // Register workers
638
+ queueService.registerWorker('emails', emailWorker);
639
+ queueService.registerWorker('images', imageProcessingWorker);
640
+
641
+ // Add job
642
+ await queueService.addJob('emails', 'send-email', {
643
+ to: 'user@example.com',
644
+ subject: 'Welcome!',
645
+ html: '<h1>Welcome to our service</h1>'
646
+ }, {
647
+ priority: 'high',
648
+ attempts: 3,
649
+ backoff: { type: 'exponential', delay: 1000 }
650
+ });
651
+
652
+ // Bulk jobs
653
+ await queueService.addBulkJobs('notifications', {
654
+ jobs: [
655
+ { name: 'send-notification', data: { userId: '1', message: 'Hello' } },
656
+ { name: 'send-notification', data: { userId: '2', message: 'Hi' } }
657
+ ]
658
+ });
659
+ ```
660
+
661
+ **Cron Jobs:**
662
+
663
+ ```typescript
664
+ const cronManager = new CronJobManager(queueService);
665
+
666
+ // Daily backup at midnight
667
+ await cronManager.createCronJob(
668
+ 'Daily Backup',
669
+ CronSchedules.DAILY,
670
+ 'maintenance',
671
+ 'database-backup',
672
+ { databases: ['main', 'analytics'] }
673
+ );
674
+
675
+ // Custom cron expression: Every 15 minutes
676
+ await cronManager.createCronJob(
677
+ 'Cache Warming',
678
+ '*/15 * * * *',
679
+ 'cache',
680
+ 'warm-cache',
681
+ { keys: ['popular-posts', 'trending-users'] }
682
+ );
683
+ ```
684
+
685
+ **Pre-built Workers:**
686
+
687
+ - `emailWorker` - Send emails (nodemailer, SendGrid, etc.)
688
+ - `imageProcessingWorker` - Resize, crop, watermark images
689
+ - `notificationWorker` - Push/SMS/email notifications
690
+ - `webhookWorker` - HTTP webhooks
691
+ - `dataExportWorker` - Export to CSV/Excel/PDF
692
+ - `reportGenerationWorker` - Generate reports
693
+ - `databaseBackupWorker` - Database backups
694
+ - `cacheWarmingWorker` - Cache warming
695
+ - `dataCleanupWorker` - Clean old data
696
+ - `batchProcessingWorker` - Batch processing
697
+
698
+ **Admin Routes:**
699
+
700
+ ```
701
+ GET /queue/queues List all queues
702
+ GET /queue/queues/:name/stats Get queue stats
703
+ GET /queue/queues/:name/metrics Get queue metrics
704
+ POST /queue/queues/:name/pause Pause queue
705
+ POST /queue/queues/:name/resume Resume queue
706
+ POST /queue/queues/:name/jobs Add job
707
+ POST /queue/queues/:name/jobs/bulk Add bulk jobs
708
+ GET /queue/queues/:name/jobs List jobs
709
+ GET /queue/queues/:name/jobs/:id Get job
710
+ DELETE /queue/queues/:name/jobs/:id Remove job
711
+ POST /queue/queues/:name/jobs/:id/retry Retry job
712
+ POST /queue/queues/:name/clean Clean old jobs
713
+ POST /queue/cron Create cron job
714
+ GET /queue/cron List cron jobs
715
+ GET /queue/cron/:id Get cron job
716
+ PATCH /queue/cron/:id Update cron job
717
+ DELETE /queue/cron/:id Delete cron job
718
+ POST /queue/cron/:id/trigger Trigger cron job
719
+ ```
720
+
721
+ **Cron Schedules:**
722
+
723
+ ```typescript
724
+ CronSchedules.EVERY_MINUTE // * * * * *
725
+ CronSchedules.EVERY_15_MINUTES // */15 * * * *
726
+ CronSchedules.EVERY_HOUR // 0 * * * *
727
+ CronSchedules.DAILY // 0 0 * * *
728
+ CronSchedules.WEEKLY // 0 0 * * 0
729
+ CronSchedules.MONTHLY // 0 0 1 * *
730
+ CronSchedules.WEEKDAYS_9AM // 0 9 * * 1-5
731
+ ```
732
+
733
+ ### Websockets/Real-time
734
+
735
+ Real-time communication with Socket.io for chat, presence, notifications, and live events:
736
+
737
+ **Features:**
738
+ - Real-time chat with typing indicators
739
+ - User presence tracking (online/offline/away)
740
+ - Live notifications
741
+ - Room/namespace management
742
+ - Event broadcasting
743
+ - Authentication & role-based access
744
+ - Rate limiting & throttling
745
+
746
+ **Usage:**
747
+
748
+ ```typescript
749
+ import {
750
+ WebSocketService,
751
+ ChatFeature,
752
+ PresenceFeature,
753
+ NotificationFeature,
754
+ authMiddleware
755
+ } from './modules/websocket';
756
+
757
+ // Create service
758
+ const wsService = new WebSocketService({
759
+ cors: { origin: 'http://localhost:3000' },
760
+ redis: { host: 'localhost', port: 6379 }
761
+ });
762
+
763
+ // Initialize with HTTP server
764
+ wsService.initialize(httpServer);
765
+
766
+ // Create features
767
+ const chat = new ChatFeature(wsService);
768
+ const presence = new PresenceFeature(wsService);
769
+ const notifications = new NotificationFeature(wsService);
770
+
771
+ // Send chat message
772
+ await chat.sendMessage('room-123', 'user-456', 'Hello everyone!', {
773
+ mentions: ['user-789']
774
+ });
775
+
776
+ // Typing indicator
777
+ await chat.startTyping('room-123', 'user-456', 'John');
778
+
779
+ // Send notification
780
+ await notifications.send(
781
+ 'user-123',
782
+ 'message',
783
+ 'New Message',
784
+ 'You have a new message from John'
785
+ );
786
+
787
+ // Broadcast live event
788
+ await wsService.broadcastToAll('analytics:update', {
789
+ metric: 'active_users',
790
+ value: 1250
791
+ });
792
+ ```
793
+
794
+ **Client-side:**
795
+
796
+ ```typescript
797
+ import { io } from 'socket.io-client';
798
+
799
+ const socket = io('http://localhost:3000', {
800
+ auth: { token: 'your-jwt-token' },
801
+ query: { username: 'john' }
802
+ });
803
+
804
+ // Listen for events
805
+ socket.on('chat:message', (msg) => console.log('New message:', msg));
806
+ socket.on('presence:status', (status) => console.log('Status:', status));
807
+ socket.on('notification:new', (notif) => console.log('Notification:', notif));
808
+ socket.on('live:event', (event) => console.log('Live event:', event));
809
+
810
+ // Send message
811
+ socket.emit('chat:send', { roomId: 'room-123', content: 'Hello!' });
812
+
813
+ // Start typing
814
+ socket.emit('chat:typing', { roomId: 'room-123' });
815
+ ```
816
+
817
+ **Middlewares:**
818
+
819
+ ```typescript
820
+ import {
821
+ authMiddleware,
822
+ rateLimitMiddleware,
823
+ roleMiddleware,
824
+ throttleMiddleware
825
+ } from './modules/websocket';
826
+
827
+ // Apply middlewares
828
+ io.use(authMiddleware());
829
+ io.use(rateLimitMiddleware(5, 60000)); // 5 connections per minute
830
+ io.use(roleMiddleware(['user', 'admin']));
831
+ io.use(throttleMiddleware(100, 1000)); // 100 events per second
832
+ ```
833
+
834
+ **Features:**
835
+
836
+ - **Chat**: Messages, typing indicators, mentions, edit/delete
837
+ - **Presence**: Online/away/busy status, last seen
838
+ - **Notifications**: Real-time push, read/unread tracking
839
+ - **Live Events**: Analytics, system updates, custom events
840
+ - **Rooms**: Create, join, leave, member management
841
+ - **Broadcasting**: To all, to room, to specific users
842
+
843
+ ### Search (Elasticsearch/Meilisearch)
844
+
845
+ Full-text search with support for Elasticsearch, Meilisearch, or in-memory adapter for development:
846
+
847
+ **Features:**
848
+ - Multiple search engines: Elasticsearch, Meilisearch, In-memory
849
+ - Unified interface for all engines
850
+ - Full-text search with fuzzy matching
851
+ - Filtering, sorting, pagination
852
+ - Faceted search
853
+ - Autocomplete suggestions
854
+ - Similar document search
855
+ - Bulk indexing
856
+ - Index management & statistics
857
+
858
+ **Usage:**
859
+
860
+ ```typescript
861
+ import {
862
+ SearchService,
863
+ ElasticsearchAdapter,
864
+ MeilisearchAdapter,
865
+ MemorySearchAdapter
866
+ } from './modules/search';
867
+
868
+ // Using Elasticsearch
869
+ import { Client } from '@elastic/elasticsearch';
870
+ const esClient = new Client({ node: 'http://localhost:9200' });
871
+ const searchService = new SearchService(
872
+ { engine: 'elasticsearch' },
873
+ new ElasticsearchAdapter(esClient)
874
+ );
875
+
876
+ // Or Meilisearch
877
+ import { MeiliSearch } from 'meilisearch';
878
+ const meiliClient = new MeiliSearch({ host: 'http://localhost:7700' });
879
+ const searchService = new SearchService(
880
+ { engine: 'meilisearch' },
881
+ new MeilisearchAdapter(meiliClient)
882
+ );
883
+
884
+ // Or in-memory (for development)
885
+ const searchService = new SearchService(); // Uses MemorySearchAdapter by default
886
+
887
+ // Create an index
888
+ await searchService.createIndex('products', {
889
+ searchableAttributes: ['title', 'description', 'tags'],
890
+ filterableAttributes: ['category', 'price', 'inStock'],
891
+ sortableAttributes: ['price', 'createdAt']
892
+ });
893
+
894
+ // Index documents
895
+ await searchService.indexDocuments('products', [
896
+ {
897
+ id: '1',
898
+ title: 'Laptop',
899
+ description: 'High-performance laptop',
900
+ category: 'electronics',
901
+ price: 999,
902
+ inStock: true
903
+ },
904
+ {
905
+ id: '2',
906
+ title: 'Headphones',
907
+ description: 'Noise-canceling headphones',
908
+ category: 'electronics',
909
+ price: 299,
910
+ inStock: true
911
+ }
912
+ ]);
913
+
914
+ // Search
915
+ const results = await searchService.search('products', {
916
+ query: 'laptop',
917
+ filters: [
918
+ { field: 'category', operator: 'eq', value: 'electronics' },
919
+ { field: 'price', operator: 'lte', value: 1000 }
920
+ ],
921
+ sort: [{ field: 'price', direction: 'asc' }],
922
+ limit: 10
923
+ });
924
+
925
+ // Autocomplete
926
+ const suggestions = await searchService.autocomplete('products', 'lap', 5);
927
+
928
+ // Search with facets
929
+ const facetResults = await searchService.searchWithFacets('products', 'laptop', {
930
+ facets: ['category', 'inStock'],
931
+ filters: [{ field: 'price', operator: 'gte', value: 100 }]
932
+ });
933
+
934
+ // Similar documents
935
+ const similar = await searchService.searchSimilar('products', '1', 5);
936
+
937
+ // Reindex (with transformation)
938
+ await searchService.reindex('products', 'products_v2', (doc) => ({
939
+ ...doc,
940
+ slug: doc.title.toLowerCase().replace(/\s+/g, '-')
941
+ }));
942
+ ```
943
+
944
+ **Integration Example:**
945
+
946
+ ```typescript
947
+ // Product search endpoint
948
+ app.get('/api/products/search', async (req, res) => {
949
+ const { q, category, minPrice, maxPrice, sort } = req.query;
950
+
951
+ const filters = [];
952
+ if (category) {
953
+ filters.push({ field: 'category', operator: 'eq', value: category });
954
+ }
955
+ if (minPrice) {
956
+ filters.push({ field: 'price', operator: 'gte', value: Number(minPrice) });
957
+ }
958
+ if (maxPrice) {
959
+ filters.push({ field: 'price', operator: 'lte', value: Number(maxPrice) });
960
+ }
961
+
962
+ const results = await searchService.search('products', {
963
+ query: q || '*',
964
+ filters,
965
+ sort: sort ? [{ field: sort, direction: 'asc' }] : undefined,
966
+ limit: 20
967
+ });
968
+
969
+ res.json(results);
970
+ });
971
+
972
+ // Autocomplete endpoint
973
+ app.get('/api/products/autocomplete', async (req, res) => {
974
+ const { q } = req.query;
975
+ const suggestions = await searchService.autocomplete('products', q, 10);
976
+ res.json(suggestions);
977
+ });
978
+
979
+ // Index product when created
980
+ app.post('/api/products', async (req, res) => {
981
+ const product = await db.product.create(req.body);
982
+
983
+ // Index in search engine
984
+ await searchService.indexDocument('products', product.id, product);
985
+
986
+ res.json(product);
987
+ });
988
+ ```
989
+
990
+ **Filter Operators:**
991
+
992
+ - `eq` - Equal to
993
+ - `ne` - Not equal to
994
+ - `gt` - Greater than
995
+ - `gte` - Greater than or equal to
996
+ - `lt` - Less than
997
+ - `lte` - Less than or equal to
998
+ - `in` - In array
999
+ - `nin` - Not in array
1000
+ - `contains` - Contains text
1001
+ - `exists` - Field exists
1002
+
1003
+ **Index Statistics:**
1004
+
1005
+ ```typescript
1006
+ const stats = await searchService.getStats('products');
1007
+ console.log({
1008
+ documentCount: stats.documentCount,
1009
+ size: stats.size,
1010
+ isIndexing: stats.isIndexing,
1011
+ health: stats.health
1012
+ });
1013
+ ```
1014
+
1015
+ ### i18n/Localization
1016
+
1017
+ Multi-language support with automatic locale detection and translation management:
1018
+
1019
+ **Features:**
1020
+ - Multiple locale support
1021
+ - Automatic locale detection (query, cookie, header)
1022
+ - Translation loading from files or in-memory
1023
+ - Variable interpolation
1024
+ - Pluralization support
1025
+ - Date, number, currency formatting
1026
+ - Relative time formatting
1027
+ - Translation metadata & missing keys tracking
1028
+ - Nested translation keys
1029
+ - Namespace organization
1030
+
1031
+ **Usage:**
1032
+
1033
+ ```typescript
1034
+ import {
1035
+ I18nService,
1036
+ createI18nMiddleware,
1037
+ createI18nRoutes
1038
+ } from './modules/i18n';
1039
+
1040
+ // Create service
1041
+ const i18nService = new I18nService({
1042
+ defaultLocale: 'en',
1043
+ supportedLocales: ['en', 'fr', 'es', 'de', 'ar', 'zh', 'ja'],
1044
+ fallbackLocale: 'en',
1045
+ translationsDir: './locales',
1046
+ cache: true
1047
+ });
1048
+
1049
+ // Load translations from files
1050
+ await i18nService.loadTranslations('en', 'common');
1051
+ await i18nService.loadTranslations('fr', 'common');
1052
+
1053
+ // Or add translations programmatically
1054
+ i18nService.addTranslations({
1055
+ locale: 'en',
1056
+ namespace: 'common',
1057
+ data: {
1058
+ welcome: 'Welcome',
1059
+ greeting: 'Hello, {{name}}!',
1060
+ items: 'You have {{count}} item{s}',
1061
+ user: {
1062
+ profile: {
1063
+ title: 'User Profile',
1064
+ edit: 'Edit Profile'
1065
+ }
1066
+ }
1067
+ }
1068
+ });
1069
+
1070
+ // Apply middleware
1071
+ app.use(createI18nMiddleware(i18nService, {
1072
+ queryParam: 'lang',
1073
+ cookieName: 'locale',
1074
+ detectFromHeader: true
1075
+ }));
1076
+
1077
+ // Add routes
1078
+ app.use('/api/i18n', createI18nRoutes(i18nService));
1079
+
1080
+ // Use in controllers
1081
+ app.get('/api/welcome', (req, res) => {
1082
+ const message = req.t('welcome');
1083
+ res.json({ message });
1084
+ });
1085
+ ```
1086
+
1087
+ **Translation Features:**
1088
+
1089
+ ```typescript
1090
+ // Simple translation
1091
+ i18nService.t('welcome', { locale: 'en' });
1092
+ // => 'Welcome'
1093
+
1094
+ // Variable interpolation
1095
+ i18nService.t('greeting', {
1096
+ locale: 'en',
1097
+ variables: { name: 'John' }
1098
+ });
1099
+ // => 'Hello, John!'
1100
+
1101
+ // Pluralization
1102
+ i18nService.t('items', {
1103
+ locale: 'en',
1104
+ count: 1,
1105
+ variables: { count: 1 }
1106
+ });
1107
+ // => 'You have 1 item'
1108
+
1109
+ i18nService.t('items', {
1110
+ locale: 'en',
1111
+ count: 5,
1112
+ variables: { count: 5 }
1113
+ });
1114
+ // => 'You have 5 items'
1115
+
1116
+ // Nested keys
1117
+ i18nService.t('user.profile.title', { locale: 'en' });
1118
+ // => 'User Profile'
1119
+
1120
+ // With default value
1121
+ i18nService.t('missing.key', {
1122
+ locale: 'en',
1123
+ defaultValue: 'Fallback text'
1124
+ });
1125
+ // => 'Fallback text'
1126
+ ```
1127
+
1128
+ **Formatting:**
1129
+
1130
+ ```typescript
1131
+ // Date formatting
1132
+ i18nService.formatDate(new Date(), 'en', {
1133
+ dateStyle: 'full',
1134
+ timeStyle: 'short'
1135
+ });
1136
+ // => 'Monday, January 1, 2024 at 10:30 AM'
1137
+
1138
+ // Number formatting
1139
+ i18nService.formatNumber(1234567.89, 'en', {
1140
+ minimumFractionDigits: 2
1141
+ });
1142
+ // => '1,234,567.89'
1143
+
1144
+ // Currency formatting
1145
+ i18nService.formatCurrency(99.99, 'en', 'USD');
1146
+ // => '$99.99'
1147
+
1148
+ i18nService.formatCurrency(99.99, 'fr', 'EUR');
1149
+ // => '99,99 €'
1150
+
1151
+ // Relative time
1152
+ i18nService.formatRelativeTime(new Date(Date.now() - 3600000), 'en');
1153
+ // => '1 hour ago'
1154
+ ```
1155
+
1156
+ **Locale Detection:**
1157
+
1158
+ The middleware automatically detects locale from:
1159
+ 1. Query parameter (?lang=fr)
1160
+ 2. Cookie (locale=fr)
1161
+ 3. Accept-Language header
1162
+ 4. Default locale (fallback)
1163
+
1164
+ ```typescript
1165
+ // Detection result available in request
1166
+ app.get('/api/info', (req, res) => {
1167
+ res.json({
1168
+ locale: req.locale,
1169
+ detection: req.localeDetection // { locale, source, confidence }
1170
+ });
1171
+ });
1172
+ ```
1173
+
1174
+ **API Routes:**
1175
+
1176
+ ```
1177
+ GET /i18n/locales List supported locales
1178
+ GET /i18n/locale Get current locale
1179
+ POST /i18n/locale Switch locale
1180
+ GET /i18n/translations/:namespace Get translations
1181
+ GET /i18n/translations/:namespace/metadata Get metadata
1182
+ GET /i18n/translations/:namespace/missing Get missing keys
1183
+ POST /i18n/translate Translate a key
1184
+ POST /i18n/cache/clear Clear cache
1185
+ ```
1186
+
1187
+ **Translation File Structure:**
1188
+
1189
+ ```
1190
+ locales/
1191
+ ├── en/
1192
+ │ ├── common.json
1193
+ │ ├── errors.json
1194
+ │ └── emails.json
1195
+ ├── fr/
1196
+ │ ├── common.json
1197
+ │ ├── errors.json
1198
+ │ └── emails.json
1199
+ └── es/
1200
+ ├── common.json
1201
+ ├── errors.json
1202
+ └── emails.json
1203
+ ```
1204
+
1205
+ **common.json example:**
1206
+
1207
+ ```json
1208
+ {
1209
+ "welcome": "Welcome",
1210
+ "greeting": "Hello, {{name}}!",
1211
+ "farewell": "Goodbye",
1212
+ "nav": {
1213
+ "home": "Home",
1214
+ "about": "About",
1215
+ "contact": "Contact"
1216
+ },
1217
+ "errors": {
1218
+ "notFound": "Not found",
1219
+ "serverError": "Server error"
1220
+ }
1221
+ }
1222
+ ```
1223
+
1224
+ **Tracking Translation Progress:**
1225
+
1226
+ ```typescript
1227
+ // Get metadata
1228
+ const metadata = await i18nService.getTranslationMetadata('fr', 'common');
1229
+ console.log({
1230
+ totalKeys: metadata.totalKeys,
1231
+ translatedKeys: metadata.translatedKeys,
1232
+ completionPercentage: metadata.completionPercentage
1233
+ });
1234
+
1235
+ // Get missing translations
1236
+ const missing = i18nService.getMissingTranslations('en', 'fr', 'common');
1237
+ console.log('Missing keys:', missing);
1238
+ ```
1239
+
1240
+ ## Modules & Resources
1241
+
1242
+ ServCraft includes these pre-built modules:
1243
+
1244
+ ### Core Modules
1245
+ - ✅ **Authentication** - JWT access/refresh tokens, RBAC
1246
+ - ✅ **User Management** - Full CRUD with roles & permissions
1247
+ - ✅ **Email Service** - SMTP with Handlebars templates
1248
+ - ✅ **Audit Logging** - Activity tracking & audit trail
1249
+
1250
+ ### Advanced Features
1251
+ - ✅ **Cache Module** - Redis caching with TTL & invalidation
1252
+ - ✅ **Rate Limiting** - Fixed/sliding window, token bucket algorithms
1253
+ - ✅ **Webhooks (Outgoing)** - HMAC signatures, auto-retry, delivery tracking
1254
+ - ✅ **Queue/Jobs** - Background tasks, cron scheduling, 10+ workers
1255
+ - ✅ **Websockets/Real-time** - Chat, presence, notifications, live events
1256
+ - ✅ **Search** - Elasticsearch/Meilisearch full-text search
1257
+ - ✅ **i18n/Localization** - Multi-language support with 7+ locales
1258
+ - ✅ **Feature Flags** - A/B testing, progressive rollout, user targeting
1259
+ - ✅ **Analytics/Metrics** - Prometheus metrics, counters, gauges, histograms
1260
+ - ✅ **Media Processing** - Image/video processing with FFmpeg, thumbnails
1261
+ - ✅ **API Versioning** - Multiple API versions with migrations
1262
+ - ✅ **File Upload** - Multi-provider support (local, S3, etc.)
1263
+ - ✅ **MFA/TOTP** - Two-factor authentication with QR codes
1264
+ - ✅ **OAuth** - Google, GitHub, Facebook, Twitter, Apple
1265
+ - ✅ **Payments** - Stripe, PayPal, Mobile Money integration
1266
+ - ✅ **Notifications** - Email, SMS, Push notifications
1267
+
167
1268
  ## API Endpoints
168
1269
 
169
1270
  ### Authentication