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/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "servcraft",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "description": "A modular, production-ready Node.js backend framework",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "bin": {
8
- "servcraft": "dist/cli/index.js"
8
+ "servcraft": "./dist/cli/index.js"
9
9
  },
10
10
  "scripts": {
11
11
  "dev": "tsx watch src/index.ts",
@@ -16,10 +16,8 @@
16
16
  "lint": "eslint src --ext .ts",
17
17
  "lint:fix": "eslint src --ext .ts --fix",
18
18
  "format": "prettier --write \"src/**/*.ts\"",
19
- "prepare": "command -v husky >/dev/null 2>&1 && husky install || echo \"husky not installed, skipping hooks\"",
19
+ "prepare": "husky",
20
20
  "typecheck": "tsc --noEmit",
21
- "docs": "tsx src/cli/index.ts docs",
22
- "prepublishOnly": "npm run build",
23
21
  "db:generate": "prisma generate",
24
22
  "db:migrate": "prisma migrate dev",
25
23
  "db:push": "prisma db push",
@@ -41,55 +39,83 @@
41
39
  "authentication",
42
40
  "jwt"
43
41
  ],
44
- "author": "Le-Sourcier",
42
+ "author": "",
45
43
  "license": "MIT",
46
44
  "engines": {
47
45
  "node": ">=18.0.0"
48
46
  },
49
47
  "dependencies": {
48
+ "@aws-sdk/client-s3": "^3.700.0",
49
+ "@aws-sdk/s3-request-presigner": "^3.700.0",
50
+ "@elastic/elasticsearch": "^8.16.2",
51
+ "@fastify/cookie": "^9.3.1",
50
52
  "@fastify/cors": "^9.0.1",
51
53
  "@fastify/helmet": "^11.1.1",
52
- "@fastify/jwt": "^8.0.1",
54
+ "@fastify/jwt": "^10.0.0",
55
+ "@fastify/multipart": "^8.3.0",
53
56
  "@fastify/rate-limit": "^9.1.0",
54
- "@fastify/cookie": "^9.3.1",
55
57
  "@fastify/swagger": "^8.15.0",
56
58
  "@fastify/swagger-ui": "^4.1.0",
59
+ "@fastify/websocket": "^10.0.1",
60
+ "@paypal/paypal-server-sdk": "^1.0.0",
57
61
  "@prisma/client": "^5.22.0",
58
- "fastify": "^4.28.1",
59
- "pino": "^9.5.0",
60
- "pino-pretty": "^11.3.0",
61
- "zod": "^3.23.8",
62
+ "@socket.io/redis-adapter": "^8.3.0",
62
63
  "bcryptjs": "^2.4.3",
64
+ "bullmq": "^5.25.0",
65
+ "chalk": "^5.3.0",
66
+ "commander": "^12.1.0",
63
67
  "dotenv": "^16.4.5",
64
- "nodemailer": "^6.9.15",
68
+ "express": "^4.21.1",
69
+ "fastify": "^4.28.1",
70
+ "fluent-ffmpeg": "^2.1.3",
65
71
  "handlebars": "^4.7.8",
66
- "commander": "^12.1.0",
67
- "chalk": "^5.3.0",
68
72
  "inquirer": "^12.1.0",
69
- "ora": "^8.1.1"
73
+ "ioredis": "^5.4.1",
74
+ "meilisearch": "^0.44.1",
75
+ "mongoose": "^8.8.4",
76
+ "nodemailer": "^7.0.11",
77
+ "ora": "^8.1.1",
78
+ "otplib": "^12.0.1",
79
+ "pino": "^9.5.0",
80
+ "pino-pretty": "^11.3.0",
81
+ "prom-client": "^15.1.3",
82
+ "qrcode": "^1.5.4",
83
+ "sharp": "^0.33.5",
84
+ "socket.io": "^4.8.1",
85
+ "socket.io-client": "^4.8.1",
86
+ "speakeasy": "^2.0.0",
87
+ "stripe": "^17.3.1",
88
+ "uuid": "^11.0.3",
89
+ "zod": "^3.23.8"
70
90
  },
71
91
  "devDependencies": {
72
- "@types/node": "^22.10.1",
92
+ "@commitlint/cli": "^19.6.0",
93
+ "@commitlint/config-conventional": "^19.6.0",
94
+ "@eslint/js": "^9.16.0",
73
95
  "@types/bcryptjs": "^2.4.6",
96
+ "@types/express": "^5.0.0",
97
+ "@types/fluent-ffmpeg": "^2.1.27",
98
+ "@types/node": "^22.10.1",
74
99
  "@types/nodemailer": "^6.4.17",
100
+ "@types/qrcode": "^1.5.5",
101
+ "@types/speakeasy": "^2.0.10",
102
+ "@types/uuid": "^10.0.0",
103
+ "@types/ws": "^8.5.13",
75
104
  "@typescript-eslint/eslint-plugin": "^8.17.0",
76
105
  "@typescript-eslint/parser": "^8.17.0",
106
+ "@vitest/coverage-v8": "^4.0.16",
77
107
  "eslint": "^9.16.0",
78
108
  "eslint-config-prettier": "^9.1.0",
79
109
  "eslint-plugin-prettier": "^5.2.1",
80
- "prettier": "^3.4.2",
81
110
  "husky": "^9.1.7",
82
111
  "lint-staged": "^15.2.10",
83
- "typescript": "^5.7.2",
84
- "tsx": "^4.19.2",
85
- "tsup": "^8.3.5",
86
- "vitest": "^2.1.8",
87
- "@vitest/coverage-v8": "^2.1.8",
112
+ "prettier": "^3.4.2",
88
113
  "prisma": "^5.22.0",
89
- "@commitlint/cli": "^19.6.0",
90
- "@commitlint/config-conventional": "^19.6.0",
114
+ "tsup": "^8.3.5",
115
+ "tsx": "^4.19.2",
116
+ "typescript": "^5.7.2",
91
117
  "typescript-eslint": "^8.17.0",
92
- "@eslint/js": "^9.16.0"
118
+ "vitest": "^4.0.16"
93
119
  },
94
120
  "type": "module",
95
121
  "lint-staged": {
@@ -97,16 +123,5 @@
97
123
  "eslint --fix",
98
124
  "prettier --write"
99
125
  ]
100
- },
101
- "directories": {
102
- "test": "tests"
103
- },
104
- "repository": {
105
- "type": "git",
106
- "url": "git+https://github.com/Le-Sourcier/servcraft.git"
107
- },
108
- "bugs": {
109
- "url": "https://github.com/Le-Sourcier/servcraft/issues"
110
- },
111
- "homepage": "https://github.com/Le-Sourcier/servcraft#readme"
126
+ }
112
127
  }
@@ -6,7 +6,7 @@ generator client {
6
6
  }
7
7
 
8
8
  datasource db {
9
- provider = env("DATABASE_PROVIDER") // "postgresql", "mysql", or "sqlite"
9
+ provider = "postgresql" // Change to "mysql" or "sqlite" as needed
10
10
  url = env("DATABASE_URL")
11
11
  }
12
12
 
@@ -32,6 +32,8 @@ model User {
32
32
  refreshTokens RefreshToken[]
33
33
  sessions Session[]
34
34
  auditLogs AuditLog[]
35
+ payments Payment[]
36
+ subscriptions Subscription[]
35
37
 
36
38
  @@index([email])
37
39
  @@index([status])
@@ -155,3 +157,395 @@ model Setting {
155
157
  @@index([group])
156
158
  @@map("settings")
157
159
  }
160
+
161
+ // ==========================================
162
+ // PAYMENTS & SUBSCRIPTIONS
163
+ // ==========================================
164
+
165
+ model Payment {
166
+ id String @id @default(uuid())
167
+ userId String
168
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
169
+ provider PaymentProvider @default(MANUAL)
170
+ method PaymentMethod @default(CARD)
171
+ status PaymentStatus @default(PENDING)
172
+ amount Float
173
+ currency String @default("USD")
174
+ description String?
175
+ metadata Json?
176
+ providerPaymentId String? @unique
177
+ providerCustomerId String?
178
+ refundedAmount Float?
179
+ failureReason String?
180
+ paidAt DateTime?
181
+ createdAt DateTime @default(now())
182
+ updatedAt DateTime @updatedAt
183
+
184
+ @@index([userId])
185
+ @@index([provider])
186
+ @@index([status])
187
+ @@index([createdAt])
188
+ @@index([providerPaymentId])
189
+ @@map("payments")
190
+ }
191
+
192
+ enum PaymentProvider {
193
+ STRIPE
194
+ PAYPAL
195
+ MOBILE_MONEY
196
+ MANUAL
197
+ }
198
+
199
+ enum PaymentStatus {
200
+ PENDING
201
+ PROCESSING
202
+ COMPLETED
203
+ FAILED
204
+ REFUNDED
205
+ CANCELLED
206
+ }
207
+
208
+ enum PaymentMethod {
209
+ CARD
210
+ BANK_TRANSFER
211
+ MOBILE_MONEY
212
+ PAYPAL
213
+ CRYPTO
214
+ CASH
215
+ }
216
+
217
+ model Subscription {
218
+ id String @id @default(uuid())
219
+ userId String
220
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
221
+ planId String
222
+ plan Plan @relation(fields: [planId], references: [id], onDelete: Restrict)
223
+ provider PaymentProvider @default(STRIPE)
224
+ providerSubscriptionId String? @unique
225
+ status SubscriptionStatus @default(ACTIVE)
226
+ currentPeriodStart DateTime
227
+ currentPeriodEnd DateTime
228
+ cancelAtPeriodEnd Boolean @default(false)
229
+ createdAt DateTime @default(now())
230
+ updatedAt DateTime @updatedAt
231
+
232
+ @@index([userId])
233
+ @@index([planId])
234
+ @@index([status])
235
+ @@index([providerSubscriptionId])
236
+ @@map("subscriptions")
237
+ }
238
+
239
+ enum SubscriptionStatus {
240
+ ACTIVE
241
+ CANCELLED
242
+ PAST_DUE
243
+ TRIALING
244
+ PAUSED
245
+ }
246
+
247
+ model Plan {
248
+ id String @id @default(uuid())
249
+ name String
250
+ description String?
251
+ amount Float
252
+ currency String @default("USD")
253
+ interval PlanInterval @default(MONTH)
254
+ intervalCount Int @default(1)
255
+ trialDays Int?
256
+ features Json?
257
+ metadata Json?
258
+ active Boolean @default(true)
259
+ createdAt DateTime @default(now())
260
+ updatedAt DateTime @updatedAt
261
+
262
+ // Relations
263
+ subscriptions Subscription[]
264
+
265
+ @@index([active])
266
+ @@map("plans")
267
+ }
268
+
269
+ enum PlanInterval {
270
+ DAY
271
+ WEEK
272
+ MONTH
273
+ YEAR
274
+ }
275
+
276
+ model PaymentWebhook {
277
+ id String @id @default(uuid())
278
+ provider PaymentProvider
279
+ type String
280
+ data Json
281
+ processed Boolean @default(false)
282
+ error String?
283
+ createdAt DateTime @default(now())
284
+
285
+ @@index([provider])
286
+ @@index([processed])
287
+ @@index([createdAt])
288
+ @@map("payment_webhooks")
289
+ }
290
+
291
+ // ==========================================
292
+ // NOTIFICATIONS
293
+ // ==========================================
294
+
295
+ model Notification {
296
+ id String @id @default(uuid())
297
+ userId String
298
+ channel NotificationChannel
299
+ status NotificationStatus @default(PENDING)
300
+ title String
301
+ body String
302
+ data Json?
303
+ sentAt DateTime?
304
+ readAt DateTime?
305
+ createdAt DateTime @default(now())
306
+
307
+ @@index([userId])
308
+ @@index([channel])
309
+ @@index([status])
310
+ @@index([createdAt])
311
+ @@map("notifications")
312
+ }
313
+
314
+ enum NotificationChannel {
315
+ EMAIL
316
+ SMS
317
+ PUSH
318
+ WEBHOOK
319
+ IN_APP
320
+ }
321
+
322
+ enum NotificationStatus {
323
+ PENDING
324
+ SENT
325
+ FAILED
326
+ READ
327
+ }
328
+
329
+ model NotificationTemplate {
330
+ id String @id @default(uuid())
331
+ name String @unique
332
+ channel NotificationChannel
333
+ subject String?
334
+ body String
335
+ variables Json?
336
+ metadata Json?
337
+ active Boolean @default(true)
338
+ createdAt DateTime @default(now())
339
+ updatedAt DateTime @updatedAt
340
+
341
+ @@index([name])
342
+ @@index([channel])
343
+ @@index([active])
344
+ @@map("notification_templates")
345
+ }
346
+
347
+ // ==========================================
348
+ // FILE UPLOADS
349
+ // ==========================================
350
+
351
+ model UploadedFile {
352
+ id String @id @default(uuid())
353
+ userId String?
354
+ originalName String
355
+ filename String
356
+ mimetype String
357
+ size Int
358
+ path String
359
+ url String
360
+ provider StorageProvider @default(LOCAL)
361
+ bucket String?
362
+ metadata Json?
363
+ createdAt DateTime @default(now())
364
+
365
+ @@index([userId])
366
+ @@index([provider])
367
+ @@index([mimetype])
368
+ @@index([createdAt])
369
+ @@map("uploaded_files")
370
+ }
371
+
372
+ enum StorageProvider {
373
+ LOCAL
374
+ S3
375
+ CLOUDINARY
376
+ GCS
377
+ }
378
+
379
+ // ==========================================
380
+ // OAUTH LINKED ACCOUNTS
381
+ // ==========================================
382
+
383
+ model LinkedAccount {
384
+ id String @id @default(uuid())
385
+ userId String
386
+ provider OAuthProvider
387
+ providerAccountId String
388
+ email String?
389
+ name String?
390
+ picture String?
391
+ accessToken String?
392
+ refreshToken String?
393
+ expiresAt DateTime?
394
+ createdAt DateTime @default(now())
395
+ updatedAt DateTime @updatedAt
396
+
397
+ @@unique([provider, providerAccountId])
398
+ @@index([userId])
399
+ @@index([provider])
400
+ @@map("linked_accounts")
401
+ }
402
+
403
+ enum OAuthProvider {
404
+ GOOGLE
405
+ FACEBOOK
406
+ GITHUB
407
+ TWITTER
408
+ APPLE
409
+ }
410
+
411
+ // ==========================================
412
+ // MFA (Multi-Factor Authentication)
413
+ // ==========================================
414
+
415
+ model UserMFA {
416
+ id String @id @default(uuid())
417
+ userId String @unique
418
+ enabled Boolean @default(false)
419
+ methods MFAMethod[] @default([])
420
+ totpSecret String?
421
+ totpVerified Boolean @default(false)
422
+ backupCodes Json? // String array stored as JSON
423
+ backupCodesUsed Json? // String array stored as JSON
424
+ phoneNumber String?
425
+ phoneVerified Boolean @default(false)
426
+ email String?
427
+ emailVerified Boolean @default(false)
428
+ lastUsed DateTime?
429
+ createdAt DateTime @default(now())
430
+ updatedAt DateTime @updatedAt
431
+
432
+ @@index([userId])
433
+ @@map("user_mfa")
434
+ }
435
+
436
+ enum MFAMethod {
437
+ TOTP
438
+ SMS
439
+ EMAIL
440
+ BACKUP_CODES
441
+ }
442
+
443
+ // ==========================================
444
+ // WEBHOOKS
445
+ // ==========================================
446
+
447
+ model WebhookEndpoint {
448
+ id String @id @default(uuid())
449
+ url String
450
+ secret String
451
+ events String[] // Event types to listen to
452
+ enabled Boolean @default(true)
453
+ description String?
454
+ headers Json? // Custom headers
455
+ metadata Json?
456
+ createdAt DateTime @default(now())
457
+ updatedAt DateTime @updatedAt
458
+
459
+ // Relations
460
+ deliveries WebhookDelivery[]
461
+
462
+ @@index([enabled])
463
+ @@map("webhook_endpoints")
464
+ }
465
+
466
+ model WebhookDelivery {
467
+ id String @id @default(uuid())
468
+ endpointId String
469
+ endpoint WebhookEndpoint @relation(fields: [endpointId], references: [id], onDelete: Cascade)
470
+ eventType String
471
+ status WebhookDeliveryStatus @default(PENDING)
472
+ payload Json
473
+ attempts Int @default(0)
474
+ maxAttempts Int @default(5)
475
+ responseStatus Int?
476
+ responseBody String?
477
+ error String?
478
+ nextRetryAt DateTime?
479
+ deliveredAt DateTime?
480
+ createdAt DateTime @default(now())
481
+
482
+ @@index([endpointId])
483
+ @@index([status])
484
+ @@index([eventType])
485
+ @@index([createdAt])
486
+ @@map("webhook_deliveries")
487
+ }
488
+
489
+ enum WebhookDeliveryStatus {
490
+ PENDING
491
+ RETRYING
492
+ SUCCESS
493
+ FAILED
494
+ }
495
+
496
+ // ==========================================
497
+ // FEATURE FLAGS
498
+ // ==========================================
499
+
500
+ model FeatureFlag {
501
+ id String @id @default(uuid())
502
+ key String @unique
503
+ name String
504
+ description String?
505
+ status FeatureFlagStatus @default(DISABLED)
506
+ strategy FlagStrategy @default(BOOLEAN)
507
+ config Json // Strategy-specific configuration
508
+ environment String?
509
+ tags String[] @default([])
510
+ createdBy String?
511
+ createdAt DateTime @default(now())
512
+ updatedAt DateTime @updatedAt
513
+
514
+ // Relations
515
+ overrides FlagOverride[]
516
+
517
+ @@index([key])
518
+ @@index([status])
519
+ @@index([environment])
520
+ @@map("feature_flags")
521
+ }
522
+
523
+ model FlagOverride {
524
+ id String @id @default(uuid())
525
+ flagId String
526
+ flag FeatureFlag @relation(fields: [flagId], references: [id], onDelete: Cascade)
527
+ targetId String // userId or sessionId
528
+ targetType String // 'user' or 'session'
529
+ enabled Boolean
530
+ expiresAt DateTime?
531
+ createdAt DateTime @default(now())
532
+
533
+ @@unique([flagId, targetId])
534
+ @@index([flagId])
535
+ @@index([targetId])
536
+ @@map("flag_overrides")
537
+ }
538
+
539
+ enum FeatureFlagStatus {
540
+ ENABLED
541
+ DISABLED
542
+ ARCHIVED
543
+ }
544
+
545
+ enum FlagStrategy {
546
+ BOOLEAN
547
+ PERCENTAGE
548
+ USER_LIST
549
+ USER_ATTRIBUTE
550
+ DATE_RANGE
551
+ }