servcraft 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/.claude/settings.local.json +29 -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/README.md +1070 -1
  9. package/dist/cli/index.cjs +2026 -2168
  10. package/dist/cli/index.cjs.map +1 -1
  11. package/dist/cli/index.js +2026 -2168
  12. package/dist/cli/index.js.map +1 -1
  13. package/dist/index.cjs +595 -616
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +114 -52
  16. package/dist/index.d.ts +114 -52
  17. package/dist/index.js +595 -616
  18. package/dist/index.js.map +1 -1
  19. package/docs/CLI-001_MULTI_DB_PLAN.md +546 -0
  20. package/docs/DATABASE_MULTI_ORM.md +399 -0
  21. package/docs/PHASE1_BREAKDOWN.md +346 -0
  22. package/docs/PROGRESS.md +550 -0
  23. package/docs/modules/ANALYTICS.md +226 -0
  24. package/docs/modules/API-VERSIONING.md +252 -0
  25. package/docs/modules/AUDIT.md +192 -0
  26. package/docs/modules/AUTH.md +431 -0
  27. package/docs/modules/CACHE.md +346 -0
  28. package/docs/modules/EMAIL.md +254 -0
  29. package/docs/modules/FEATURE-FLAG.md +291 -0
  30. package/docs/modules/I18N.md +294 -0
  31. package/docs/modules/MEDIA-PROCESSING.md +281 -0
  32. package/docs/modules/MFA.md +266 -0
  33. package/docs/modules/NOTIFICATION.md +311 -0
  34. package/docs/modules/OAUTH.md +237 -0
  35. package/docs/modules/PAYMENT.md +804 -0
  36. package/docs/modules/QUEUE.md +540 -0
  37. package/docs/modules/RATE-LIMIT.md +339 -0
  38. package/docs/modules/SEARCH.md +288 -0
  39. package/docs/modules/SECURITY.md +327 -0
  40. package/docs/modules/SESSION.md +382 -0
  41. package/docs/modules/SWAGGER.md +305 -0
  42. package/docs/modules/UPLOAD.md +296 -0
  43. package/docs/modules/USER.md +505 -0
  44. package/docs/modules/VALIDATION.md +294 -0
  45. package/docs/modules/WEBHOOK.md +270 -0
  46. package/docs/modules/WEBSOCKET.md +691 -0
  47. package/package.json +53 -38
  48. package/prisma/schema.prisma +395 -1
  49. package/src/cli/commands/add-module.ts +520 -87
  50. package/src/cli/commands/db.ts +3 -4
  51. package/src/cli/commands/docs.ts +256 -6
  52. package/src/cli/commands/generate.ts +12 -19
  53. package/src/cli/commands/init.ts +384 -214
  54. package/src/cli/index.ts +0 -4
  55. package/src/cli/templates/repository.ts +6 -1
  56. package/src/cli/templates/routes.ts +6 -21
  57. package/src/cli/utils/docs-generator.ts +6 -7
  58. package/src/cli/utils/env-manager.ts +717 -0
  59. package/src/cli/utils/field-parser.ts +16 -7
  60. package/src/cli/utils/interactive-prompt.ts +223 -0
  61. package/src/cli/utils/template-manager.ts +346 -0
  62. package/src/config/database.config.ts +183 -0
  63. package/src/config/env.ts +0 -10
  64. package/src/config/index.ts +0 -14
  65. package/src/core/server.ts +1 -1
  66. package/src/database/adapters/mongoose.adapter.ts +132 -0
  67. package/src/database/adapters/prisma.adapter.ts +118 -0
  68. package/src/database/connection.ts +190 -0
  69. package/src/database/interfaces/database.interface.ts +85 -0
  70. package/src/database/interfaces/index.ts +7 -0
  71. package/src/database/interfaces/repository.interface.ts +129 -0
  72. package/src/database/models/mongoose/index.ts +7 -0
  73. package/src/database/models/mongoose/payment.schema.ts +347 -0
  74. package/src/database/models/mongoose/user.schema.ts +154 -0
  75. package/src/database/prisma.ts +1 -4
  76. package/src/database/redis.ts +101 -0
  77. package/src/database/repositories/mongoose/index.ts +7 -0
  78. package/src/database/repositories/mongoose/payment.repository.ts +380 -0
  79. package/src/database/repositories/mongoose/user.repository.ts +255 -0
  80. package/src/database/seed.ts +6 -1
  81. package/src/index.ts +9 -20
  82. package/src/middleware/security.ts +2 -6
  83. package/src/modules/analytics/analytics.routes.ts +80 -0
  84. package/src/modules/analytics/analytics.service.ts +364 -0
  85. package/src/modules/analytics/index.ts +18 -0
  86. package/src/modules/analytics/types.ts +180 -0
  87. package/src/modules/api-versioning/index.ts +15 -0
  88. package/src/modules/api-versioning/types.ts +86 -0
  89. package/src/modules/api-versioning/versioning.middleware.ts +120 -0
  90. package/src/modules/api-versioning/versioning.routes.ts +54 -0
  91. package/src/modules/api-versioning/versioning.service.ts +189 -0
  92. package/src/modules/audit/audit.repository.ts +206 -0
  93. package/src/modules/audit/audit.service.ts +27 -59
  94. package/src/modules/auth/auth.controller.ts +2 -2
  95. package/src/modules/auth/auth.middleware.ts +3 -9
  96. package/src/modules/auth/auth.routes.ts +10 -107
  97. package/src/modules/auth/auth.service.ts +126 -23
  98. package/src/modules/auth/index.ts +3 -4
  99. package/src/modules/cache/cache.service.ts +367 -0
  100. package/src/modules/cache/index.ts +10 -0
  101. package/src/modules/cache/types.ts +44 -0
  102. package/src/modules/email/email.service.ts +3 -10
  103. package/src/modules/email/templates.ts +2 -8
  104. package/src/modules/feature-flag/feature-flag.repository.ts +303 -0
  105. package/src/modules/feature-flag/feature-flag.routes.ts +247 -0
  106. package/src/modules/feature-flag/feature-flag.service.ts +566 -0
  107. package/src/modules/feature-flag/index.ts +20 -0
  108. package/src/modules/feature-flag/types.ts +192 -0
  109. package/src/modules/i18n/i18n.middleware.ts +186 -0
  110. package/src/modules/i18n/i18n.routes.ts +191 -0
  111. package/src/modules/i18n/i18n.service.ts +456 -0
  112. package/src/modules/i18n/index.ts +18 -0
  113. package/src/modules/i18n/types.ts +118 -0
  114. package/src/modules/media-processing/index.ts +17 -0
  115. package/src/modules/media-processing/media-processing.routes.ts +111 -0
  116. package/src/modules/media-processing/media-processing.service.ts +245 -0
  117. package/src/modules/media-processing/types.ts +156 -0
  118. package/src/modules/mfa/index.ts +20 -0
  119. package/src/modules/mfa/mfa.repository.ts +206 -0
  120. package/src/modules/mfa/mfa.routes.ts +595 -0
  121. package/src/modules/mfa/mfa.service.ts +572 -0
  122. package/src/modules/mfa/totp.ts +150 -0
  123. package/src/modules/mfa/types.ts +57 -0
  124. package/src/modules/notification/index.ts +20 -0
  125. package/src/modules/notification/notification.repository.ts +356 -0
  126. package/src/modules/notification/notification.service.ts +483 -0
  127. package/src/modules/notification/types.ts +119 -0
  128. package/src/modules/oauth/index.ts +20 -0
  129. package/src/modules/oauth/oauth.repository.ts +219 -0
  130. package/src/modules/oauth/oauth.routes.ts +446 -0
  131. package/src/modules/oauth/oauth.service.ts +293 -0
  132. package/src/modules/oauth/providers/apple.provider.ts +250 -0
  133. package/src/modules/oauth/providers/facebook.provider.ts +181 -0
  134. package/src/modules/oauth/providers/github.provider.ts +248 -0
  135. package/src/modules/oauth/providers/google.provider.ts +189 -0
  136. package/src/modules/oauth/providers/twitter.provider.ts +214 -0
  137. package/src/modules/oauth/types.ts +94 -0
  138. package/src/modules/payment/index.ts +19 -0
  139. package/src/modules/payment/payment.repository.ts +733 -0
  140. package/src/modules/payment/payment.routes.ts +390 -0
  141. package/src/modules/payment/payment.service.ts +354 -0
  142. package/src/modules/payment/providers/mobile-money.provider.ts +274 -0
  143. package/src/modules/payment/providers/paypal.provider.ts +190 -0
  144. package/src/modules/payment/providers/stripe.provider.ts +215 -0
  145. package/src/modules/payment/types.ts +140 -0
  146. package/src/modules/queue/cron.ts +438 -0
  147. package/src/modules/queue/index.ts +87 -0
  148. package/src/modules/queue/queue.routes.ts +600 -0
  149. package/src/modules/queue/queue.service.ts +842 -0
  150. package/src/modules/queue/types.ts +222 -0
  151. package/src/modules/queue/workers.ts +366 -0
  152. package/src/modules/rate-limit/index.ts +59 -0
  153. package/src/modules/rate-limit/rate-limit.middleware.ts +134 -0
  154. package/src/modules/rate-limit/rate-limit.routes.ts +269 -0
  155. package/src/modules/rate-limit/rate-limit.service.ts +348 -0
  156. package/src/modules/rate-limit/stores/memory.store.ts +165 -0
  157. package/src/modules/rate-limit/stores/redis.store.ts +322 -0
  158. package/src/modules/rate-limit/types.ts +153 -0
  159. package/src/modules/search/adapters/elasticsearch.adapter.ts +326 -0
  160. package/src/modules/search/adapters/meilisearch.adapter.ts +261 -0
  161. package/src/modules/search/adapters/memory.adapter.ts +278 -0
  162. package/src/modules/search/index.ts +21 -0
  163. package/src/modules/search/search.service.ts +234 -0
  164. package/src/modules/search/types.ts +214 -0
  165. package/src/modules/security/index.ts +40 -0
  166. package/src/modules/security/sanitize.ts +223 -0
  167. package/src/modules/security/security-audit.service.ts +388 -0
  168. package/src/modules/security/security.middleware.ts +398 -0
  169. package/src/modules/session/index.ts +3 -0
  170. package/src/modules/session/session.repository.ts +159 -0
  171. package/src/modules/session/session.service.ts +340 -0
  172. package/src/modules/session/types.ts +38 -0
  173. package/src/modules/swagger/index.ts +7 -1
  174. package/src/modules/swagger/schema-builder.ts +16 -4
  175. package/src/modules/swagger/swagger.service.ts +9 -10
  176. package/src/modules/swagger/types.ts +0 -2
  177. package/src/modules/upload/index.ts +14 -0
  178. package/src/modules/upload/types.ts +83 -0
  179. package/src/modules/upload/upload.repository.ts +199 -0
  180. package/src/modules/upload/upload.routes.ts +311 -0
  181. package/src/modules/upload/upload.service.ts +448 -0
  182. package/src/modules/user/index.ts +3 -3
  183. package/src/modules/user/user.controller.ts +15 -9
  184. package/src/modules/user/user.repository.ts +237 -113
  185. package/src/modules/user/user.routes.ts +39 -164
  186. package/src/modules/user/user.service.ts +4 -3
  187. package/src/modules/validation/validator.ts +12 -17
  188. package/src/modules/webhook/index.ts +91 -0
  189. package/src/modules/webhook/retry.ts +196 -0
  190. package/src/modules/webhook/signature.ts +135 -0
  191. package/src/modules/webhook/types.ts +181 -0
  192. package/src/modules/webhook/webhook.repository.ts +358 -0
  193. package/src/modules/webhook/webhook.routes.ts +442 -0
  194. package/src/modules/webhook/webhook.service.ts +457 -0
  195. package/src/modules/websocket/features.ts +504 -0
  196. package/src/modules/websocket/index.ts +106 -0
  197. package/src/modules/websocket/middlewares.ts +298 -0
  198. package/src/modules/websocket/types.ts +181 -0
  199. package/src/modules/websocket/websocket.service.ts +692 -0
  200. package/src/utils/errors.ts +7 -0
  201. package/src/utils/pagination.ts +4 -1
  202. package/tests/helpers/db-check.ts +79 -0
  203. package/tests/integration/auth-redis.test.ts +94 -0
  204. package/tests/integration/cache-redis.test.ts +387 -0
  205. package/tests/integration/mongoose-repositories.test.ts +410 -0
  206. package/tests/integration/payment-prisma.test.ts +637 -0
  207. package/tests/integration/queue-bullmq.test.ts +417 -0
  208. package/tests/integration/user-prisma.test.ts +441 -0
  209. package/tests/integration/websocket-socketio.test.ts +552 -0
  210. package/tests/setup.ts +11 -9
  211. package/vitest.config.ts +3 -8
  212. package/npm-cache/_cacache/content-v2/sha512/1c/d0/03440d500a0487621aad1d6402978340698976602046db8e24fa03c01ee6c022c69b0582f969042d9442ee876ac35c038e960dd427d1e622fa24b8eb7dba +0 -0
  213. package/npm-cache/_cacache/content-v2/sha512/42/55/28b493ca491833e5aab0e9c3108d29ab3f36c248ca88f45d4630674fce9130959e56ae308797ac2b6328fa7f09a610b9550ed09cb971d039876d293fc69d +0 -0
  214. package/npm-cache/_cacache/content-v2/sha512/e0/12/f360dc9315ee5f17844a0c8c233ee6bf7c30837c4a02ea0d56c61c7f7ab21c0e958e50ed2c57c59f983c762b93056778c9009b2398ffc26def0183999b13 +0 -0
  215. package/npm-cache/_cacache/content-v2/sha512/ed/b0/fae1161902898f4c913c67d7f6cdf6be0665aec3b389b9c4f4f0a101ca1da59badf1b59c4e0030f5223023b8d63cfe501c46a32c20c895d4fb3f11ca2232 +0 -0
  216. package/npm-cache/_cacache/index-v5/58/94/c2cba79e0f16b4c10e95a87e32255741149e8222cc314a476aab67c39cc0 +0 -5
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
2
2
  import pino, { Logger } from 'pino';
3
3
  export { Logger } from 'pino';
4
- import { z, ZodTypeAny } from 'zod';
4
+ import { z, ZodSchema } from 'zod';
5
5
 
6
6
  interface LoggerConfig {
7
7
  level: string;
@@ -50,11 +50,6 @@ declare const envSchema: z.ZodObject<{
50
50
  SMTP_PASS: z.ZodOptional<z.ZodString>;
51
51
  SMTP_FROM: z.ZodOptional<z.ZodString>;
52
52
  REDIS_URL: z.ZodOptional<z.ZodString>;
53
- SWAGGER_ENABLED: z.ZodEffects<z.ZodDefault<z.ZodUnion<[z.ZodLiteral<"true">, z.ZodLiteral<"false">]>>, boolean, "true" | "false" | undefined>;
54
- SWAGGER_ROUTE: z.ZodDefault<z.ZodString>;
55
- SWAGGER_TITLE: z.ZodDefault<z.ZodString>;
56
- SWAGGER_DESCRIPTION: z.ZodDefault<z.ZodString>;
57
- SWAGGER_VERSION: z.ZodDefault<z.ZodString>;
58
53
  LOG_LEVEL: z.ZodDefault<z.ZodEnum<["fatal", "error", "warn", "info", "debug", "trace"]>>;
59
54
  }, "strip", z.ZodTypeAny, {
60
55
  NODE_ENV: "development" | "staging" | "production" | "test";
@@ -65,11 +60,6 @@ declare const envSchema: z.ZodObject<{
65
60
  CORS_ORIGIN: string;
66
61
  RATE_LIMIT_MAX: number;
67
62
  RATE_LIMIT_WINDOW_MS: number;
68
- SWAGGER_ENABLED: boolean;
69
- SWAGGER_ROUTE: string;
70
- SWAGGER_TITLE: string;
71
- SWAGGER_DESCRIPTION: string;
72
- SWAGGER_VERSION: string;
73
63
  LOG_LEVEL: "fatal" | "error" | "warn" | "info" | "debug" | "trace";
74
64
  DATABASE_URL?: string | undefined;
75
65
  JWT_SECRET?: string | undefined;
@@ -96,11 +86,6 @@ declare const envSchema: z.ZodObject<{
96
86
  SMTP_PASS?: string | undefined;
97
87
  SMTP_FROM?: string | undefined;
98
88
  REDIS_URL?: string | undefined;
99
- SWAGGER_ENABLED?: "true" | "false" | undefined;
100
- SWAGGER_ROUTE?: string | undefined;
101
- SWAGGER_TITLE?: string | undefined;
102
- SWAGGER_DESCRIPTION?: string | undefined;
103
- SWAGGER_VERSION?: string | undefined;
104
89
  LOG_LEVEL?: "fatal" | "error" | "warn" | "info" | "debug" | "trace" | undefined;
105
90
  }>;
106
91
  type Env = z.infer<typeof envSchema>;
@@ -113,11 +98,6 @@ declare const env: {
113
98
  CORS_ORIGIN: string;
114
99
  RATE_LIMIT_MAX: number;
115
100
  RATE_LIMIT_WINDOW_MS: number;
116
- SWAGGER_ENABLED: boolean;
117
- SWAGGER_ROUTE: string;
118
- SWAGGER_TITLE: string;
119
- SWAGGER_DESCRIPTION: string;
120
- SWAGGER_VERSION: string;
121
101
  LOG_LEVEL: "fatal" | "error" | "warn" | "info" | "debug" | "trace";
122
102
  DATABASE_URL?: string | undefined;
123
103
  JWT_SECRET?: string | undefined;
@@ -164,13 +144,6 @@ interface AppConfig {
164
144
  redis: {
165
145
  url?: string;
166
146
  };
167
- swagger: {
168
- enabled: boolean;
169
- route: string;
170
- title: string;
171
- description: string;
172
- version: string;
173
- };
174
147
  }
175
148
  declare function createConfig(): AppConfig;
176
149
  declare const config: AppConfig;
@@ -343,16 +316,43 @@ declare module '@fastify/jwt' {
343
316
  declare class AuthService {
344
317
  private app;
345
318
  private readonly SALT_ROUNDS;
346
- constructor(app: FastifyInstance);
319
+ private redis;
320
+ private readonly BLACKLIST_PREFIX;
321
+ private readonly BLACKLIST_TTL;
322
+ constructor(app: FastifyInstance, redisUrl?: string);
347
323
  hashPassword(password: string): Promise<string>;
348
324
  verifyPassword(password: string, hash: string): Promise<boolean>;
349
325
  generateTokenPair(user: AuthUser): TokenPair;
350
326
  private parseExpiration;
351
327
  verifyAccessToken(token: string): Promise<JwtPayload>;
352
328
  verifyRefreshToken(token: string): Promise<JwtPayload>;
353
- blacklistToken(token: string): void;
354
- isTokenBlacklisted(token: string): boolean;
355
- cleanupBlacklist(): void;
329
+ /**
330
+ * Blacklist a token (JWT revocation)
331
+ * Uses Redis if available, falls back to in-memory Set
332
+ */
333
+ blacklistToken(token: string): Promise<void>;
334
+ /**
335
+ * Check if a token is blacklisted
336
+ * Uses Redis if available, falls back to always returning false
337
+ */
338
+ isTokenBlacklisted(token: string): Promise<boolean>;
339
+ /**
340
+ * Get count of blacklisted tokens (Redis only)
341
+ */
342
+ getBlacklistCount(): Promise<number>;
343
+ /**
344
+ * Close Redis connection
345
+ */
346
+ close(): Promise<void>;
347
+ findUserByEmail(_email: string): Promise<AuthUser | null>;
348
+ createUserFromOAuth(data: {
349
+ email: string;
350
+ name?: string;
351
+ picture?: string;
352
+ emailVerified?: boolean;
353
+ }): Promise<AuthUser>;
354
+ generateTokensForUser(userId: string): Promise<TokenPair>;
355
+ verifyPasswordById(userId: string, _password: string): Promise<boolean>;
356
356
  }
357
357
  declare function createAuthService(app: FastifyInstance): AuthService;
358
358
 
@@ -403,17 +403,80 @@ interface Role {
403
403
  }
404
404
  declare const DEFAULT_ROLE_PERMISSIONS: Record<UserRole, string[]>;
405
405
 
406
+ /**
407
+ * User Repository - Prisma Implementation
408
+ * Manages user data persistence using Prisma ORM
409
+ */
406
410
  declare class UserRepository {
411
+ /**
412
+ * Find user by ID
413
+ */
407
414
  findById(id: string): Promise<User | null>;
415
+ /**
416
+ * Find user by email (case-insensitive)
417
+ */
408
418
  findByEmail(email: string): Promise<User | null>;
419
+ /**
420
+ * Find multiple users with pagination and filters
421
+ */
409
422
  findMany(params: PaginationParams, filters?: UserFilters): Promise<PaginatedResult<User>>;
423
+ /**
424
+ * Create a new user
425
+ */
410
426
  create(data: CreateUserData): Promise<User>;
427
+ /**
428
+ * Update user data
429
+ */
411
430
  update(id: string, data: UpdateUserData): Promise<User | null>;
431
+ /**
432
+ * Update user password
433
+ */
412
434
  updatePassword(id: string, password: string): Promise<User | null>;
435
+ /**
436
+ * Update last login timestamp
437
+ */
413
438
  updateLastLogin(id: string): Promise<User | null>;
439
+ /**
440
+ * Delete user by ID
441
+ */
414
442
  delete(id: string): Promise<boolean>;
443
+ /**
444
+ * Count users with optional filters
445
+ */
415
446
  count(filters?: UserFilters): Promise<number>;
447
+ /**
448
+ * Helper to clear all users (for testing only)
449
+ * WARNING: This deletes all users from the database
450
+ */
416
451
  clear(): Promise<void>;
452
+ /**
453
+ * Build Prisma where clause from filters
454
+ */
455
+ private buildWhereClause;
456
+ /**
457
+ * Build Prisma orderBy clause from pagination params
458
+ */
459
+ private buildOrderBy;
460
+ /**
461
+ * Map Prisma User to application User type
462
+ */
463
+ private mapPrismaUserToUser;
464
+ /**
465
+ * Map application role to Prisma enum
466
+ */
467
+ private mapRoleToEnum;
468
+ /**
469
+ * Map Prisma enum to application role
470
+ */
471
+ private mapEnumToRole;
472
+ /**
473
+ * Map application status to Prisma enum
474
+ */
475
+ private mapStatusToEnum;
476
+ /**
477
+ * Map Prisma enum to application status
478
+ */
479
+ private mapEnumToStatus;
417
480
  }
418
481
  declare function createUserRepository(): UserRepository;
419
482
 
@@ -451,9 +514,9 @@ declare class AuthController {
451
514
  }
452
515
  declare function createAuthController(authService: AuthService, userService: UserService): AuthController;
453
516
 
454
- declare function createAuthMiddleware(authService: AuthService): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
517
+ declare function createAuthMiddleware(authService: AuthService): (request: FastifyRequest, _reply: FastifyReply) => Promise<void>;
455
518
  declare function createRoleMiddleware(allowedRoles: string[]): (request: FastifyRequest, _reply: FastifyReply) => Promise<void>;
456
- declare function createPermissionMiddleware(requiredPermissions: string[]): (request: FastifyRequest, _reply: FastifyReply) => Promise<void>;
519
+ declare function createPermissionMiddleware(_requiredPermissions: string[]): (request: FastifyRequest, _reply: FastifyReply) => Promise<void>;
457
520
  declare function createOptionalAuthMiddleware(authService: AuthService): (request: FastifyRequest, _reply: FastifyReply) => Promise<void>;
458
521
 
459
522
  declare const loginSchema: z.ZodObject<{
@@ -520,7 +583,7 @@ type PasswordResetRequestInput = z.infer<typeof passwordResetRequestSchema>;
520
583
  type PasswordResetConfirmInput = z.infer<typeof passwordResetConfirmSchema>;
521
584
  type ChangePasswordInput = z.infer<typeof changePasswordSchema>;
522
585
 
523
- declare function registerAuthModule(app: FastifyInstance): Promise<AuthService>;
586
+ declare function registerAuthModule(app: FastifyInstance): Promise<void>;
524
587
 
525
588
  declare class UserController {
526
589
  private userService;
@@ -570,8 +633,8 @@ declare const createUserSchema: z.ZodObject<{
570
633
  role: z.ZodDefault<z.ZodOptional<z.ZodEnum<["user", "admin", "moderator", "super_admin"]>>>;
571
634
  }, "strip", z.ZodTypeAny, {
572
635
  email: string;
573
- password: string;
574
636
  role: "user" | "admin" | "moderator" | "super_admin";
637
+ password: string;
575
638
  name?: string | undefined;
576
639
  }, {
577
640
  email: string;
@@ -712,10 +775,10 @@ declare function createEmailService(config?: Partial<EmailConfig>): EmailService
712
775
  declare function renderTemplate(templateName: string, data: Record<string, unknown>): string;
713
776
  declare function renderCustomTemplate(htmlTemplate: string, data: Record<string, unknown>): string;
714
777
 
715
- declare function validateBody<T extends ZodTypeAny>(schema: T, data: unknown): z.infer<T>;
716
- declare function validateQuery<T extends ZodTypeAny>(schema: T, data: unknown): z.infer<T>;
717
- declare function validateParams<T extends ZodTypeAny>(schema: T, data: unknown): z.infer<T>;
718
- declare function validate<T extends ZodTypeAny>(schema: T, data: unknown): z.infer<T>;
778
+ declare function validateBody<T>(schema: ZodSchema<T>, data: unknown): T;
779
+ declare function validateQuery<T extends z.ZodTypeAny>(schema: T, data: unknown): z.infer<T>;
780
+ declare function validateParams<T>(schema: ZodSchema<T>, data: unknown): T;
781
+ declare function validate<T>(schema: ZodSchema<T>, data: unknown): T;
719
782
  declare const idParamSchema: z.ZodObject<{
720
783
  id: z.ZodString;
721
784
  }, "strip", z.ZodTypeAny, {
@@ -782,20 +845,18 @@ interface AuditLogQuery {
782
845
  limit?: number;
783
846
  }
784
847
 
848
+ interface AuditLogRecord extends AuditLogEntry {
849
+ id: string;
850
+ createdAt: Date;
851
+ }
852
+
785
853
  declare class AuditService {
854
+ private repository;
855
+ constructor();
786
856
  log(entry: AuditLogEntry): Promise<void>;
787
- query(params: AuditLogQuery): Promise<PaginatedResult<AuditLogEntry & {
788
- id: string;
789
- createdAt: Date;
790
- }>>;
791
- findByUser(userId: string, limit?: number): Promise<(AuditLogEntry & {
792
- id: string;
793
- createdAt: Date;
794
- })[]>;
795
- findByResource(resource: string, resourceId: string, limit?: number): Promise<(AuditLogEntry & {
796
- id: string;
797
- createdAt: Date;
798
- })[]>;
857
+ query(params: AuditLogQuery): Promise<PaginatedResult<AuditLogRecord>>;
858
+ findByUser(userId: string, limit?: number): Promise<AuditLogRecord[]>;
859
+ findByResource(resource: string, resourceId: string, limit?: number): Promise<AuditLogRecord[]>;
799
860
  logCreate(resource: string, resourceId: string, userId?: string, newValue?: Record<string, unknown>, meta?: {
800
861
  ipAddress?: string;
801
862
  userAgent?: string;
@@ -820,6 +881,7 @@ declare class AuditService {
820
881
  ipAddress?: string;
821
882
  userAgent?: string;
822
883
  }): Promise<void>;
884
+ cleanupOldLogs(retentionDays: number): Promise<number>;
823
885
  clear(): Promise<void>;
824
886
  }
825
887
  declare function getAuditService(): AuditService;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
2
2
  import pino, { Logger } from 'pino';
3
3
  export { Logger } from 'pino';
4
- import { z, ZodTypeAny } from 'zod';
4
+ import { z, ZodSchema } from 'zod';
5
5
 
6
6
  interface LoggerConfig {
7
7
  level: string;
@@ -50,11 +50,6 @@ declare const envSchema: z.ZodObject<{
50
50
  SMTP_PASS: z.ZodOptional<z.ZodString>;
51
51
  SMTP_FROM: z.ZodOptional<z.ZodString>;
52
52
  REDIS_URL: z.ZodOptional<z.ZodString>;
53
- SWAGGER_ENABLED: z.ZodEffects<z.ZodDefault<z.ZodUnion<[z.ZodLiteral<"true">, z.ZodLiteral<"false">]>>, boolean, "true" | "false" | undefined>;
54
- SWAGGER_ROUTE: z.ZodDefault<z.ZodString>;
55
- SWAGGER_TITLE: z.ZodDefault<z.ZodString>;
56
- SWAGGER_DESCRIPTION: z.ZodDefault<z.ZodString>;
57
- SWAGGER_VERSION: z.ZodDefault<z.ZodString>;
58
53
  LOG_LEVEL: z.ZodDefault<z.ZodEnum<["fatal", "error", "warn", "info", "debug", "trace"]>>;
59
54
  }, "strip", z.ZodTypeAny, {
60
55
  NODE_ENV: "development" | "staging" | "production" | "test";
@@ -65,11 +60,6 @@ declare const envSchema: z.ZodObject<{
65
60
  CORS_ORIGIN: string;
66
61
  RATE_LIMIT_MAX: number;
67
62
  RATE_LIMIT_WINDOW_MS: number;
68
- SWAGGER_ENABLED: boolean;
69
- SWAGGER_ROUTE: string;
70
- SWAGGER_TITLE: string;
71
- SWAGGER_DESCRIPTION: string;
72
- SWAGGER_VERSION: string;
73
63
  LOG_LEVEL: "fatal" | "error" | "warn" | "info" | "debug" | "trace";
74
64
  DATABASE_URL?: string | undefined;
75
65
  JWT_SECRET?: string | undefined;
@@ -96,11 +86,6 @@ declare const envSchema: z.ZodObject<{
96
86
  SMTP_PASS?: string | undefined;
97
87
  SMTP_FROM?: string | undefined;
98
88
  REDIS_URL?: string | undefined;
99
- SWAGGER_ENABLED?: "true" | "false" | undefined;
100
- SWAGGER_ROUTE?: string | undefined;
101
- SWAGGER_TITLE?: string | undefined;
102
- SWAGGER_DESCRIPTION?: string | undefined;
103
- SWAGGER_VERSION?: string | undefined;
104
89
  LOG_LEVEL?: "fatal" | "error" | "warn" | "info" | "debug" | "trace" | undefined;
105
90
  }>;
106
91
  type Env = z.infer<typeof envSchema>;
@@ -113,11 +98,6 @@ declare const env: {
113
98
  CORS_ORIGIN: string;
114
99
  RATE_LIMIT_MAX: number;
115
100
  RATE_LIMIT_WINDOW_MS: number;
116
- SWAGGER_ENABLED: boolean;
117
- SWAGGER_ROUTE: string;
118
- SWAGGER_TITLE: string;
119
- SWAGGER_DESCRIPTION: string;
120
- SWAGGER_VERSION: string;
121
101
  LOG_LEVEL: "fatal" | "error" | "warn" | "info" | "debug" | "trace";
122
102
  DATABASE_URL?: string | undefined;
123
103
  JWT_SECRET?: string | undefined;
@@ -164,13 +144,6 @@ interface AppConfig {
164
144
  redis: {
165
145
  url?: string;
166
146
  };
167
- swagger: {
168
- enabled: boolean;
169
- route: string;
170
- title: string;
171
- description: string;
172
- version: string;
173
- };
174
147
  }
175
148
  declare function createConfig(): AppConfig;
176
149
  declare const config: AppConfig;
@@ -343,16 +316,43 @@ declare module '@fastify/jwt' {
343
316
  declare class AuthService {
344
317
  private app;
345
318
  private readonly SALT_ROUNDS;
346
- constructor(app: FastifyInstance);
319
+ private redis;
320
+ private readonly BLACKLIST_PREFIX;
321
+ private readonly BLACKLIST_TTL;
322
+ constructor(app: FastifyInstance, redisUrl?: string);
347
323
  hashPassword(password: string): Promise<string>;
348
324
  verifyPassword(password: string, hash: string): Promise<boolean>;
349
325
  generateTokenPair(user: AuthUser): TokenPair;
350
326
  private parseExpiration;
351
327
  verifyAccessToken(token: string): Promise<JwtPayload>;
352
328
  verifyRefreshToken(token: string): Promise<JwtPayload>;
353
- blacklistToken(token: string): void;
354
- isTokenBlacklisted(token: string): boolean;
355
- cleanupBlacklist(): void;
329
+ /**
330
+ * Blacklist a token (JWT revocation)
331
+ * Uses Redis if available, falls back to in-memory Set
332
+ */
333
+ blacklistToken(token: string): Promise<void>;
334
+ /**
335
+ * Check if a token is blacklisted
336
+ * Uses Redis if available, falls back to always returning false
337
+ */
338
+ isTokenBlacklisted(token: string): Promise<boolean>;
339
+ /**
340
+ * Get count of blacklisted tokens (Redis only)
341
+ */
342
+ getBlacklistCount(): Promise<number>;
343
+ /**
344
+ * Close Redis connection
345
+ */
346
+ close(): Promise<void>;
347
+ findUserByEmail(_email: string): Promise<AuthUser | null>;
348
+ createUserFromOAuth(data: {
349
+ email: string;
350
+ name?: string;
351
+ picture?: string;
352
+ emailVerified?: boolean;
353
+ }): Promise<AuthUser>;
354
+ generateTokensForUser(userId: string): Promise<TokenPair>;
355
+ verifyPasswordById(userId: string, _password: string): Promise<boolean>;
356
356
  }
357
357
  declare function createAuthService(app: FastifyInstance): AuthService;
358
358
 
@@ -403,17 +403,80 @@ interface Role {
403
403
  }
404
404
  declare const DEFAULT_ROLE_PERMISSIONS: Record<UserRole, string[]>;
405
405
 
406
+ /**
407
+ * User Repository - Prisma Implementation
408
+ * Manages user data persistence using Prisma ORM
409
+ */
406
410
  declare class UserRepository {
411
+ /**
412
+ * Find user by ID
413
+ */
407
414
  findById(id: string): Promise<User | null>;
415
+ /**
416
+ * Find user by email (case-insensitive)
417
+ */
408
418
  findByEmail(email: string): Promise<User | null>;
419
+ /**
420
+ * Find multiple users with pagination and filters
421
+ */
409
422
  findMany(params: PaginationParams, filters?: UserFilters): Promise<PaginatedResult<User>>;
423
+ /**
424
+ * Create a new user
425
+ */
410
426
  create(data: CreateUserData): Promise<User>;
427
+ /**
428
+ * Update user data
429
+ */
411
430
  update(id: string, data: UpdateUserData): Promise<User | null>;
431
+ /**
432
+ * Update user password
433
+ */
412
434
  updatePassword(id: string, password: string): Promise<User | null>;
435
+ /**
436
+ * Update last login timestamp
437
+ */
413
438
  updateLastLogin(id: string): Promise<User | null>;
439
+ /**
440
+ * Delete user by ID
441
+ */
414
442
  delete(id: string): Promise<boolean>;
443
+ /**
444
+ * Count users with optional filters
445
+ */
415
446
  count(filters?: UserFilters): Promise<number>;
447
+ /**
448
+ * Helper to clear all users (for testing only)
449
+ * WARNING: This deletes all users from the database
450
+ */
416
451
  clear(): Promise<void>;
452
+ /**
453
+ * Build Prisma where clause from filters
454
+ */
455
+ private buildWhereClause;
456
+ /**
457
+ * Build Prisma orderBy clause from pagination params
458
+ */
459
+ private buildOrderBy;
460
+ /**
461
+ * Map Prisma User to application User type
462
+ */
463
+ private mapPrismaUserToUser;
464
+ /**
465
+ * Map application role to Prisma enum
466
+ */
467
+ private mapRoleToEnum;
468
+ /**
469
+ * Map Prisma enum to application role
470
+ */
471
+ private mapEnumToRole;
472
+ /**
473
+ * Map application status to Prisma enum
474
+ */
475
+ private mapStatusToEnum;
476
+ /**
477
+ * Map Prisma enum to application status
478
+ */
479
+ private mapEnumToStatus;
417
480
  }
418
481
  declare function createUserRepository(): UserRepository;
419
482
 
@@ -451,9 +514,9 @@ declare class AuthController {
451
514
  }
452
515
  declare function createAuthController(authService: AuthService, userService: UserService): AuthController;
453
516
 
454
- declare function createAuthMiddleware(authService: AuthService): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
517
+ declare function createAuthMiddleware(authService: AuthService): (request: FastifyRequest, _reply: FastifyReply) => Promise<void>;
455
518
  declare function createRoleMiddleware(allowedRoles: string[]): (request: FastifyRequest, _reply: FastifyReply) => Promise<void>;
456
- declare function createPermissionMiddleware(requiredPermissions: string[]): (request: FastifyRequest, _reply: FastifyReply) => Promise<void>;
519
+ declare function createPermissionMiddleware(_requiredPermissions: string[]): (request: FastifyRequest, _reply: FastifyReply) => Promise<void>;
457
520
  declare function createOptionalAuthMiddleware(authService: AuthService): (request: FastifyRequest, _reply: FastifyReply) => Promise<void>;
458
521
 
459
522
  declare const loginSchema: z.ZodObject<{
@@ -520,7 +583,7 @@ type PasswordResetRequestInput = z.infer<typeof passwordResetRequestSchema>;
520
583
  type PasswordResetConfirmInput = z.infer<typeof passwordResetConfirmSchema>;
521
584
  type ChangePasswordInput = z.infer<typeof changePasswordSchema>;
522
585
 
523
- declare function registerAuthModule(app: FastifyInstance): Promise<AuthService>;
586
+ declare function registerAuthModule(app: FastifyInstance): Promise<void>;
524
587
 
525
588
  declare class UserController {
526
589
  private userService;
@@ -570,8 +633,8 @@ declare const createUserSchema: z.ZodObject<{
570
633
  role: z.ZodDefault<z.ZodOptional<z.ZodEnum<["user", "admin", "moderator", "super_admin"]>>>;
571
634
  }, "strip", z.ZodTypeAny, {
572
635
  email: string;
573
- password: string;
574
636
  role: "user" | "admin" | "moderator" | "super_admin";
637
+ password: string;
575
638
  name?: string | undefined;
576
639
  }, {
577
640
  email: string;
@@ -712,10 +775,10 @@ declare function createEmailService(config?: Partial<EmailConfig>): EmailService
712
775
  declare function renderTemplate(templateName: string, data: Record<string, unknown>): string;
713
776
  declare function renderCustomTemplate(htmlTemplate: string, data: Record<string, unknown>): string;
714
777
 
715
- declare function validateBody<T extends ZodTypeAny>(schema: T, data: unknown): z.infer<T>;
716
- declare function validateQuery<T extends ZodTypeAny>(schema: T, data: unknown): z.infer<T>;
717
- declare function validateParams<T extends ZodTypeAny>(schema: T, data: unknown): z.infer<T>;
718
- declare function validate<T extends ZodTypeAny>(schema: T, data: unknown): z.infer<T>;
778
+ declare function validateBody<T>(schema: ZodSchema<T>, data: unknown): T;
779
+ declare function validateQuery<T extends z.ZodTypeAny>(schema: T, data: unknown): z.infer<T>;
780
+ declare function validateParams<T>(schema: ZodSchema<T>, data: unknown): T;
781
+ declare function validate<T>(schema: ZodSchema<T>, data: unknown): T;
719
782
  declare const idParamSchema: z.ZodObject<{
720
783
  id: z.ZodString;
721
784
  }, "strip", z.ZodTypeAny, {
@@ -782,20 +845,18 @@ interface AuditLogQuery {
782
845
  limit?: number;
783
846
  }
784
847
 
848
+ interface AuditLogRecord extends AuditLogEntry {
849
+ id: string;
850
+ createdAt: Date;
851
+ }
852
+
785
853
  declare class AuditService {
854
+ private repository;
855
+ constructor();
786
856
  log(entry: AuditLogEntry): Promise<void>;
787
- query(params: AuditLogQuery): Promise<PaginatedResult<AuditLogEntry & {
788
- id: string;
789
- createdAt: Date;
790
- }>>;
791
- findByUser(userId: string, limit?: number): Promise<(AuditLogEntry & {
792
- id: string;
793
- createdAt: Date;
794
- })[]>;
795
- findByResource(resource: string, resourceId: string, limit?: number): Promise<(AuditLogEntry & {
796
- id: string;
797
- createdAt: Date;
798
- })[]>;
857
+ query(params: AuditLogQuery): Promise<PaginatedResult<AuditLogRecord>>;
858
+ findByUser(userId: string, limit?: number): Promise<AuditLogRecord[]>;
859
+ findByResource(resource: string, resourceId: string, limit?: number): Promise<AuditLogRecord[]>;
799
860
  logCreate(resource: string, resourceId: string, userId?: string, newValue?: Record<string, unknown>, meta?: {
800
861
  ipAddress?: string;
801
862
  userAgent?: string;
@@ -820,6 +881,7 @@ declare class AuditService {
820
881
  ipAddress?: string;
821
882
  userAgent?: string;
822
883
  }): Promise<void>;
884
+ cleanupOldLogs(retentionDays: number): Promise<number>;
823
885
  clear(): Promise<void>;
824
886
  }
825
887
  declare function getAuditService(): AuditService;