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.
- package/.claude/settings.local.json +29 -0
- package/.github/CODEOWNERS +18 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +46 -0
- package/.github/dependabot.yml +59 -0
- package/.github/workflows/ci.yml +188 -0
- package/.github/workflows/release.yml +195 -0
- package/AUDIT.md +602 -0
- package/README.md +1070 -1
- package/dist/cli/index.cjs +2026 -2168
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +2026 -2168
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +595 -616
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +114 -52
- package/dist/index.d.ts +114 -52
- package/dist/index.js +595 -616
- package/dist/index.js.map +1 -1
- package/docs/CLI-001_MULTI_DB_PLAN.md +546 -0
- package/docs/DATABASE_MULTI_ORM.md +399 -0
- package/docs/PHASE1_BREAKDOWN.md +346 -0
- package/docs/PROGRESS.md +550 -0
- package/docs/modules/ANALYTICS.md +226 -0
- package/docs/modules/API-VERSIONING.md +252 -0
- package/docs/modules/AUDIT.md +192 -0
- package/docs/modules/AUTH.md +431 -0
- package/docs/modules/CACHE.md +346 -0
- package/docs/modules/EMAIL.md +254 -0
- package/docs/modules/FEATURE-FLAG.md +291 -0
- package/docs/modules/I18N.md +294 -0
- package/docs/modules/MEDIA-PROCESSING.md +281 -0
- package/docs/modules/MFA.md +266 -0
- package/docs/modules/NOTIFICATION.md +311 -0
- package/docs/modules/OAUTH.md +237 -0
- package/docs/modules/PAYMENT.md +804 -0
- package/docs/modules/QUEUE.md +540 -0
- package/docs/modules/RATE-LIMIT.md +339 -0
- package/docs/modules/SEARCH.md +288 -0
- package/docs/modules/SECURITY.md +327 -0
- package/docs/modules/SESSION.md +382 -0
- package/docs/modules/SWAGGER.md +305 -0
- package/docs/modules/UPLOAD.md +296 -0
- package/docs/modules/USER.md +505 -0
- package/docs/modules/VALIDATION.md +294 -0
- package/docs/modules/WEBHOOK.md +270 -0
- package/docs/modules/WEBSOCKET.md +691 -0
- package/package.json +53 -38
- package/prisma/schema.prisma +395 -1
- package/src/cli/commands/add-module.ts +520 -87
- package/src/cli/commands/db.ts +3 -4
- package/src/cli/commands/docs.ts +256 -6
- package/src/cli/commands/generate.ts +12 -19
- package/src/cli/commands/init.ts +384 -214
- package/src/cli/index.ts +0 -4
- package/src/cli/templates/repository.ts +6 -1
- package/src/cli/templates/routes.ts +6 -21
- package/src/cli/utils/docs-generator.ts +6 -7
- package/src/cli/utils/env-manager.ts +717 -0
- package/src/cli/utils/field-parser.ts +16 -7
- package/src/cli/utils/interactive-prompt.ts +223 -0
- package/src/cli/utils/template-manager.ts +346 -0
- package/src/config/database.config.ts +183 -0
- package/src/config/env.ts +0 -10
- package/src/config/index.ts +0 -14
- package/src/core/server.ts +1 -1
- package/src/database/adapters/mongoose.adapter.ts +132 -0
- package/src/database/adapters/prisma.adapter.ts +118 -0
- package/src/database/connection.ts +190 -0
- package/src/database/interfaces/database.interface.ts +85 -0
- package/src/database/interfaces/index.ts +7 -0
- package/src/database/interfaces/repository.interface.ts +129 -0
- package/src/database/models/mongoose/index.ts +7 -0
- package/src/database/models/mongoose/payment.schema.ts +347 -0
- package/src/database/models/mongoose/user.schema.ts +154 -0
- package/src/database/prisma.ts +1 -4
- package/src/database/redis.ts +101 -0
- package/src/database/repositories/mongoose/index.ts +7 -0
- package/src/database/repositories/mongoose/payment.repository.ts +380 -0
- package/src/database/repositories/mongoose/user.repository.ts +255 -0
- package/src/database/seed.ts +6 -1
- package/src/index.ts +9 -20
- package/src/middleware/security.ts +2 -6
- package/src/modules/analytics/analytics.routes.ts +80 -0
- package/src/modules/analytics/analytics.service.ts +364 -0
- package/src/modules/analytics/index.ts +18 -0
- package/src/modules/analytics/types.ts +180 -0
- package/src/modules/api-versioning/index.ts +15 -0
- package/src/modules/api-versioning/types.ts +86 -0
- package/src/modules/api-versioning/versioning.middleware.ts +120 -0
- package/src/modules/api-versioning/versioning.routes.ts +54 -0
- package/src/modules/api-versioning/versioning.service.ts +189 -0
- package/src/modules/audit/audit.repository.ts +206 -0
- package/src/modules/audit/audit.service.ts +27 -59
- package/src/modules/auth/auth.controller.ts +2 -2
- package/src/modules/auth/auth.middleware.ts +3 -9
- package/src/modules/auth/auth.routes.ts +10 -107
- package/src/modules/auth/auth.service.ts +126 -23
- package/src/modules/auth/index.ts +3 -4
- package/src/modules/cache/cache.service.ts +367 -0
- package/src/modules/cache/index.ts +10 -0
- package/src/modules/cache/types.ts +44 -0
- package/src/modules/email/email.service.ts +3 -10
- package/src/modules/email/templates.ts +2 -8
- package/src/modules/feature-flag/feature-flag.repository.ts +303 -0
- package/src/modules/feature-flag/feature-flag.routes.ts +247 -0
- package/src/modules/feature-flag/feature-flag.service.ts +566 -0
- package/src/modules/feature-flag/index.ts +20 -0
- package/src/modules/feature-flag/types.ts +192 -0
- package/src/modules/i18n/i18n.middleware.ts +186 -0
- package/src/modules/i18n/i18n.routes.ts +191 -0
- package/src/modules/i18n/i18n.service.ts +456 -0
- package/src/modules/i18n/index.ts +18 -0
- package/src/modules/i18n/types.ts +118 -0
- package/src/modules/media-processing/index.ts +17 -0
- package/src/modules/media-processing/media-processing.routes.ts +111 -0
- package/src/modules/media-processing/media-processing.service.ts +245 -0
- package/src/modules/media-processing/types.ts +156 -0
- package/src/modules/mfa/index.ts +20 -0
- package/src/modules/mfa/mfa.repository.ts +206 -0
- package/src/modules/mfa/mfa.routes.ts +595 -0
- package/src/modules/mfa/mfa.service.ts +572 -0
- package/src/modules/mfa/totp.ts +150 -0
- package/src/modules/mfa/types.ts +57 -0
- package/src/modules/notification/index.ts +20 -0
- package/src/modules/notification/notification.repository.ts +356 -0
- package/src/modules/notification/notification.service.ts +483 -0
- package/src/modules/notification/types.ts +119 -0
- package/src/modules/oauth/index.ts +20 -0
- package/src/modules/oauth/oauth.repository.ts +219 -0
- package/src/modules/oauth/oauth.routes.ts +446 -0
- package/src/modules/oauth/oauth.service.ts +293 -0
- package/src/modules/oauth/providers/apple.provider.ts +250 -0
- package/src/modules/oauth/providers/facebook.provider.ts +181 -0
- package/src/modules/oauth/providers/github.provider.ts +248 -0
- package/src/modules/oauth/providers/google.provider.ts +189 -0
- package/src/modules/oauth/providers/twitter.provider.ts +214 -0
- package/src/modules/oauth/types.ts +94 -0
- package/src/modules/payment/index.ts +19 -0
- package/src/modules/payment/payment.repository.ts +733 -0
- package/src/modules/payment/payment.routes.ts +390 -0
- package/src/modules/payment/payment.service.ts +354 -0
- package/src/modules/payment/providers/mobile-money.provider.ts +274 -0
- package/src/modules/payment/providers/paypal.provider.ts +190 -0
- package/src/modules/payment/providers/stripe.provider.ts +215 -0
- package/src/modules/payment/types.ts +140 -0
- package/src/modules/queue/cron.ts +438 -0
- package/src/modules/queue/index.ts +87 -0
- package/src/modules/queue/queue.routes.ts +600 -0
- package/src/modules/queue/queue.service.ts +842 -0
- package/src/modules/queue/types.ts +222 -0
- package/src/modules/queue/workers.ts +366 -0
- package/src/modules/rate-limit/index.ts +59 -0
- package/src/modules/rate-limit/rate-limit.middleware.ts +134 -0
- package/src/modules/rate-limit/rate-limit.routes.ts +269 -0
- package/src/modules/rate-limit/rate-limit.service.ts +348 -0
- package/src/modules/rate-limit/stores/memory.store.ts +165 -0
- package/src/modules/rate-limit/stores/redis.store.ts +322 -0
- package/src/modules/rate-limit/types.ts +153 -0
- package/src/modules/search/adapters/elasticsearch.adapter.ts +326 -0
- package/src/modules/search/adapters/meilisearch.adapter.ts +261 -0
- package/src/modules/search/adapters/memory.adapter.ts +278 -0
- package/src/modules/search/index.ts +21 -0
- package/src/modules/search/search.service.ts +234 -0
- package/src/modules/search/types.ts +214 -0
- package/src/modules/security/index.ts +40 -0
- package/src/modules/security/sanitize.ts +223 -0
- package/src/modules/security/security-audit.service.ts +388 -0
- package/src/modules/security/security.middleware.ts +398 -0
- package/src/modules/session/index.ts +3 -0
- package/src/modules/session/session.repository.ts +159 -0
- package/src/modules/session/session.service.ts +340 -0
- package/src/modules/session/types.ts +38 -0
- package/src/modules/swagger/index.ts +7 -1
- package/src/modules/swagger/schema-builder.ts +16 -4
- package/src/modules/swagger/swagger.service.ts +9 -10
- package/src/modules/swagger/types.ts +0 -2
- package/src/modules/upload/index.ts +14 -0
- package/src/modules/upload/types.ts +83 -0
- package/src/modules/upload/upload.repository.ts +199 -0
- package/src/modules/upload/upload.routes.ts +311 -0
- package/src/modules/upload/upload.service.ts +448 -0
- package/src/modules/user/index.ts +3 -3
- package/src/modules/user/user.controller.ts +15 -9
- package/src/modules/user/user.repository.ts +237 -113
- package/src/modules/user/user.routes.ts +39 -164
- package/src/modules/user/user.service.ts +4 -3
- package/src/modules/validation/validator.ts +12 -17
- package/src/modules/webhook/index.ts +91 -0
- package/src/modules/webhook/retry.ts +196 -0
- package/src/modules/webhook/signature.ts +135 -0
- package/src/modules/webhook/types.ts +181 -0
- package/src/modules/webhook/webhook.repository.ts +358 -0
- package/src/modules/webhook/webhook.routes.ts +442 -0
- package/src/modules/webhook/webhook.service.ts +457 -0
- package/src/modules/websocket/features.ts +504 -0
- package/src/modules/websocket/index.ts +106 -0
- package/src/modules/websocket/middlewares.ts +298 -0
- package/src/modules/websocket/types.ts +181 -0
- package/src/modules/websocket/websocket.service.ts +692 -0
- package/src/utils/errors.ts +7 -0
- package/src/utils/pagination.ts +4 -1
- package/tests/helpers/db-check.ts +79 -0
- package/tests/integration/auth-redis.test.ts +94 -0
- package/tests/integration/cache-redis.test.ts +387 -0
- package/tests/integration/mongoose-repositories.test.ts +410 -0
- package/tests/integration/payment-prisma.test.ts +637 -0
- package/tests/integration/queue-bullmq.test.ts +417 -0
- package/tests/integration/user-prisma.test.ts +441 -0
- package/tests/integration/websocket-socketio.test.ts +552 -0
- package/tests/setup.ts +11 -9
- package/vitest.config.ts +3 -8
- package/npm-cache/_cacache/content-v2/sha512/1c/d0/03440d500a0487621aad1d6402978340698976602046db8e24fa03c01ee6c022c69b0582f969042d9442ee876ac35c038e960dd427d1e622fa24b8eb7dba +0 -0
- package/npm-cache/_cacache/content-v2/sha512/42/55/28b493ca491833e5aab0e9c3108d29ab3f36c248ca88f45d4630674fce9130959e56ae308797ac2b6328fa7f09a610b9550ed09cb971d039876d293fc69d +0 -0
- package/npm-cache/_cacache/content-v2/sha512/e0/12/f360dc9315ee5f17844a0c8c233ee6bf7c30837c4a02ea0d56c61c7f7ab21c0e958e50ed2c57c59f983c762b93056778c9009b2398ffc26def0183999b13 +0 -0
- package/npm-cache/_cacache/content-v2/sha512/ed/b0/fae1161902898f4c913c67d7f6cdf6be0665aec3b389b9c4f4f0a101ca1da59badf1b59c4e0030f5223023b8d63cfe501c46a32c20c895d4fb3f11ca2232 +0 -0
- 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.
|
|
3
|
+
"version": "0.1.1",
|
|
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": "
|
|
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": "
|
|
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": "^
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"@
|
|
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
|
-
"
|
|
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
|
-
"
|
|
90
|
-
"
|
|
114
|
+
"tsup": "^8.3.5",
|
|
115
|
+
"tsx": "^4.19.2",
|
|
116
|
+
"typescript": "^5.7.2",
|
|
91
117
|
"typescript-eslint": "^8.17.0",
|
|
92
|
-
"
|
|
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
|
}
|
package/prisma/schema.prisma
CHANGED
|
@@ -6,7 +6,7 @@ generator client {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
datasource db {
|
|
9
|
-
provider =
|
|
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
|
+
}
|