lapeh 1.0.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/.env.example ADDED
@@ -0,0 +1,16 @@
1
+ PORT=4000
2
+ DATABASE_PROVIDER="postgresql"
3
+ DATABASE_URL="postgresql://roby:12341234@localhost:5432/db_contact?schema=public"
4
+ JWT_SECRET="replace_this_with_a_secure_random_string"
5
+
6
+ # redis example:
7
+ REDIS_URL="redis://localhost:6379"
8
+
9
+ # mysql example:
10
+ # DATABASE_PROVIDER="mysql"
11
+ # DATABASE_URL="mysql://user:password@localhost:3306/news_db"
12
+ # DATABASE_HOST="localhost"
13
+ # DATABASE_PORT=3306
14
+ # DATABASE_USER="user"
15
+ # DATABASE_PASSWORD="password"
16
+ # DATABASE_NAME="news_db"
package/bin/index.js ADDED
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { execSync } = require('child_process');
6
+
7
+ const projectName = process.argv[2];
8
+
9
+ if (!projectName) {
10
+ console.error('❌ Please specify the project name:');
11
+ console.error(' npx lapeh-cli <project-name>');
12
+ process.exit(1);
13
+ }
14
+
15
+ const currentDir = process.cwd();
16
+ const projectDir = path.join(currentDir, projectName);
17
+ const templateDir = path.join(__dirname, '..');
18
+
19
+ if (fs.existsSync(projectDir)) {
20
+ console.error(`❌ Directory ${projectName} already exists.`);
21
+ process.exit(1);
22
+ }
23
+
24
+ console.log(`🚀 Creating a new API Lapeh project in ${projectDir}...`);
25
+ fs.mkdirSync(projectDir);
26
+
27
+ // List of files/folders to exclude
28
+ const ignoreList = [
29
+ 'node_modules',
30
+ 'dist',
31
+ '.git',
32
+ '.env',
33
+ 'bin', // Don't copy the CLI script itself
34
+ 'package-lock.json',
35
+ '.DS_Store',
36
+ projectName // Don't copy the destination folder itself if creating inside the template
37
+ ];
38
+
39
+ function copyDir(src, dest) {
40
+ const entries = fs.readdirSync(src, { withFileTypes: true });
41
+
42
+ for (const entry of entries) {
43
+ const srcPath = path.join(src, entry.name);
44
+ const destPath = path.join(dest, entry.name);
45
+
46
+ if (ignoreList.includes(entry.name)) {
47
+ continue;
48
+ }
49
+
50
+ if (entry.isDirectory()) {
51
+ fs.mkdirSync(destPath);
52
+ copyDir(srcPath, destPath);
53
+ } else {
54
+ fs.copyFileSync(srcPath, destPath);
55
+ }
56
+ }
57
+ }
58
+
59
+ console.log('📂 Copying template files...');
60
+ copyDir(templateDir, projectDir);
61
+
62
+ // Update package.json
63
+ console.log('📝 Updating package.json...');
64
+ const packageJsonPath = path.join(projectDir, 'package.json');
65
+ const packageJson = require(packageJsonPath);
66
+
67
+ packageJson.name = projectName;
68
+ packageJson.version = '1.0.0';
69
+ packageJson.description = 'Generated by lapeh';
70
+ delete packageJson.bin; // Remove the bin entry from the generated project
71
+ delete packageJson.repository; // Remove repository info if specific to the template
72
+
73
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
74
+
75
+ // Create .env from .env.example
76
+ console.log('⚙️ Configuring environment...');
77
+ const envExamplePath = path.join(projectDir, '.env.example');
78
+ const envPath = path.join(projectDir, '.env');
79
+
80
+ if (fs.existsSync(envExamplePath)) {
81
+ fs.copyFileSync(envExamplePath, envPath);
82
+ }
83
+
84
+ // Install dependencies
85
+ console.log('📦 Installing dependencies (this might take a while)...');
86
+ try {
87
+ execSync('npm install', { cwd: projectDir, stdio: 'inherit' });
88
+ } catch (error) {
89
+ console.error('❌ Error installing dependencies.');
90
+ process.exit(1);
91
+ }
92
+
93
+ // Generate JWT Secret
94
+ console.log('🔑 Generating JWT Secret...');
95
+ try {
96
+ execSync('npm run generate:jwt', { cwd: projectDir, stdio: 'inherit' });
97
+ } catch (error) {
98
+ console.warn('⚠️ Could not generate JWT secret automatically. Please run "npm run generate:jwt" manually.');
99
+ }
100
+
101
+ console.log('\n✅ Project created successfully!');
102
+ console.log(`\nNext steps:\n`);
103
+ console.log(` cd ${projectName}`);
104
+ console.log(` npm run dev`);
105
+ console.log('\nHappy coding! 🚀\n');
@@ -0,0 +1,17 @@
1
+ version: "3.9"
2
+ services:
3
+ redis:
4
+ image: redis:7-alpine
5
+ command: ["redis-server", "--appendonly", "yes"]
6
+ ports:
7
+ - "6379:6379"
8
+ volumes:
9
+ - redis_data:/data
10
+ healthcheck:
11
+ test: ["CMD", "redis-cli", "ping"]
12
+ interval: 10s
13
+ timeout: 5s
14
+ retries: 5
15
+
16
+ volumes:
17
+ redis_data:
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "lapeh",
3
+ "version": "1.0.1",
4
+ "description": "Framework API Express yang siap pakai (Standardized)",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "lapeh": "bin/index.js"
8
+ },
9
+ "scripts": {
10
+ "dev": "nodemon",
11
+ "build": "tsc",
12
+ "start": "node dist/src/index.js",
13
+ "start:prod": "NODE_ENV=production node dist/src/index.js",
14
+ "typecheck": "tsc --noEmit",
15
+ "prisma:generate": "node scripts/compile-schema.js && prisma generate",
16
+ "prisma:migrate": "node scripts/compile-schema.js && prisma migrate dev",
17
+ "prisma:deploy": "node scripts/compile-schema.js && prisma migrate deploy",
18
+ "db:seed": "prisma db seed",
19
+ "generate:jwt": "node scripts/generate-jwt-secret.js",
20
+ "make:module": "node scripts/make-module.js",
21
+ "make:model": "node scripts/make-model.js"
22
+ },
23
+ "keywords": [
24
+ "express",
25
+ "api",
26
+ "framework",
27
+ "cli",
28
+ "generator",
29
+ "boilerplate",
30
+ "typescript",
31
+ "prisma",
32
+ "lapeh-cli"
33
+ ],
34
+ "author": "",
35
+ "license": "ISC",
36
+ "type": "commonjs",
37
+ "dependencies": {
38
+ "@prisma/adapter-mariadb": "^7.2.0",
39
+ "@prisma/adapter-pg": "^7.2.0",
40
+ "@prisma/client": "^7.2.0",
41
+ "bcryptjs": "^3.0.3",
42
+ "cors": "^2.8.5",
43
+ "dotenv": "^17.2.3",
44
+ "express": "^5.2.1",
45
+ "express-rate-limit": "^8.2.1",
46
+ "helmet": "^8.1.0",
47
+ "ioredis": "^5.8.2",
48
+ "jsonwebtoken": "^9.0.3",
49
+ "multer": "^2.0.2",
50
+ "pg": "^8.16.3",
51
+ "slugify": "^1.6.6",
52
+ "socket.io": "^4.8.3",
53
+ "uuid": "^13.0.0",
54
+ "zod": "^4.2.1"
55
+ },
56
+ "devDependencies": {
57
+ "@types/bcryptjs": "^2.4.6",
58
+ "@types/cors": "^2.8.19",
59
+ "@types/express": "^5.0.6",
60
+ "@types/jsonwebtoken": "^9.0.10",
61
+ "@types/node": "^25.0.3",
62
+ "@types/pg": "^8.16.0",
63
+ "@types/uuid": "^10.0.0",
64
+ "nodemon": "^3.1.11",
65
+ "prisma": "^7.2.0",
66
+ "ts-node": "^10.9.2",
67
+ "ts-node-dev": "^2.0.0",
68
+ "typescript": "^5.9.3"
69
+ }
70
+ }
@@ -0,0 +1,8 @@
1
+ generator client {
2
+ provider = "prisma-client"
3
+ output = "../generated/prisma"
4
+ }
5
+
6
+ datasource db {
7
+ provider = "postgresql"
8
+ }
@@ -0,0 +1,236 @@
1
+ -- CreateTable
2
+ CREATE TABLE "cache" (
3
+ "key" VARCHAR(255) NOT NULL,
4
+ "value" TEXT NOT NULL,
5
+ "expiration" INTEGER NOT NULL,
6
+
7
+ CONSTRAINT "cache_pkey" PRIMARY KEY ("key")
8
+ );
9
+
10
+ -- CreateTable
11
+ CREATE TABLE "cache_locks" (
12
+ "key" VARCHAR(255) NOT NULL,
13
+ "owner" VARCHAR(255) NOT NULL,
14
+ "expiration" INTEGER NOT NULL,
15
+
16
+ CONSTRAINT "cache_locks_pkey" PRIMARY KEY ("key")
17
+ );
18
+
19
+ -- CreateTable
20
+ CREATE TABLE "failed_jobs" (
21
+ "id" BIGSERIAL NOT NULL,
22
+ "uuid" VARCHAR(255) NOT NULL,
23
+ "connection" TEXT NOT NULL,
24
+ "queue" TEXT NOT NULL,
25
+ "payload" TEXT NOT NULL,
26
+ "exception" TEXT NOT NULL,
27
+ "failed_at" TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
28
+
29
+ CONSTRAINT "failed_jobs_pkey" PRIMARY KEY ("id")
30
+ );
31
+
32
+ -- CreateTable
33
+ CREATE TABLE "job_batches" (
34
+ "id" VARCHAR(255) NOT NULL,
35
+ "name" VARCHAR(255) NOT NULL,
36
+ "total_jobs" INTEGER NOT NULL,
37
+ "pending_jobs" INTEGER NOT NULL,
38
+ "failed_jobs" INTEGER NOT NULL,
39
+ "failed_job_ids" TEXT NOT NULL,
40
+ "options" TEXT,
41
+ "cancelled_at" INTEGER,
42
+ "created_at" INTEGER NOT NULL,
43
+ "finished_at" INTEGER,
44
+
45
+ CONSTRAINT "job_batches_pkey" PRIMARY KEY ("id")
46
+ );
47
+
48
+ -- CreateTable
49
+ CREATE TABLE "jobs" (
50
+ "id" BIGSERIAL NOT NULL,
51
+ "queue" VARCHAR(255) NOT NULL,
52
+ "payload" TEXT NOT NULL,
53
+ "attempts" SMALLINT NOT NULL,
54
+ "reserved_at" INTEGER,
55
+ "available_at" INTEGER NOT NULL,
56
+ "created_at" INTEGER NOT NULL,
57
+
58
+ CONSTRAINT "jobs_pkey" PRIMARY KEY ("id")
59
+ );
60
+
61
+ -- CreateTable
62
+ CREATE TABLE "migrations" (
63
+ "id" SERIAL NOT NULL,
64
+ "migration" VARCHAR(255) NOT NULL,
65
+ "batch" INTEGER NOT NULL,
66
+
67
+ CONSTRAINT "migrations_pkey" PRIMARY KEY ("id")
68
+ );
69
+
70
+ -- CreateTable
71
+ CREATE TABLE "password_reset_tokens" (
72
+ "email" VARCHAR(255) NOT NULL,
73
+ "token" VARCHAR(255) NOT NULL,
74
+ "created_at" TIMESTAMP(0),
75
+
76
+ CONSTRAINT "password_reset_tokens_pkey" PRIMARY KEY ("email")
77
+ );
78
+
79
+ -- CreateTable
80
+ CREATE TABLE "personal_access_tokens" (
81
+ "id" BIGSERIAL NOT NULL,
82
+ "tokenable_type" VARCHAR(255) NOT NULL,
83
+ "tokenable_id" BIGINT NOT NULL,
84
+ "name" TEXT NOT NULL,
85
+ "token" VARCHAR(64) NOT NULL,
86
+ "abilities" TEXT,
87
+ "last_used_at" TIMESTAMP(0),
88
+ "expires_at" TIMESTAMP(0),
89
+ "created_at" TIMESTAMP(0),
90
+ "updated_at" TIMESTAMP(0),
91
+
92
+ CONSTRAINT "personal_access_tokens_pkey" PRIMARY KEY ("id")
93
+ );
94
+
95
+ -- CreateTable
96
+ CREATE TABLE "sessions" (
97
+ "id" VARCHAR(255) NOT NULL,
98
+ "user_id" BIGINT,
99
+ "ip_address" VARCHAR(45),
100
+ "user_agent" TEXT,
101
+ "payload" TEXT NOT NULL,
102
+ "last_activity" INTEGER NOT NULL,
103
+
104
+ CONSTRAINT "sessions_pkey" PRIMARY KEY ("id")
105
+ );
106
+
107
+ -- CreateTable
108
+ CREATE TABLE "users" (
109
+ "id" BIGSERIAL NOT NULL,
110
+ "uuid" UUID NOT NULL,
111
+ "name" VARCHAR(255) NOT NULL,
112
+ "email" VARCHAR(255) NOT NULL,
113
+ "avatar" VARCHAR(255),
114
+ "avatar_url" VARCHAR(255),
115
+ "email_verified_at" TIMESTAMP(0),
116
+ "password" VARCHAR(255) NOT NULL,
117
+ "remember_token" VARCHAR(100),
118
+ "created_at" TIMESTAMP(0),
119
+ "updated_at" TIMESTAMP(0),
120
+
121
+ CONSTRAINT "users_pkey" PRIMARY KEY ("id")
122
+ );
123
+
124
+ -- CreateTable
125
+ CREATE TABLE "roles" (
126
+ "id" BIGSERIAL NOT NULL,
127
+ "name" VARCHAR(255) NOT NULL,
128
+ "slug" VARCHAR(255) NOT NULL,
129
+ "description" TEXT,
130
+ "created_at" TIMESTAMP(0),
131
+ "updated_at" TIMESTAMP(0),
132
+
133
+ CONSTRAINT "roles_pkey" PRIMARY KEY ("id")
134
+ );
135
+
136
+ -- CreateTable
137
+ CREATE TABLE "permissions" (
138
+ "id" BIGSERIAL NOT NULL,
139
+ "name" VARCHAR(255) NOT NULL,
140
+ "slug" VARCHAR(255) NOT NULL,
141
+ "description" TEXT,
142
+ "created_at" TIMESTAMP(0),
143
+ "updated_at" TIMESTAMP(0),
144
+
145
+ CONSTRAINT "permissions_pkey" PRIMARY KEY ("id")
146
+ );
147
+
148
+ -- CreateTable
149
+ CREATE TABLE "user_roles" (
150
+ "id" BIGSERIAL NOT NULL,
151
+ "user_id" BIGINT NOT NULL,
152
+ "role_id" BIGINT NOT NULL,
153
+ "created_at" TIMESTAMP(0),
154
+
155
+ CONSTRAINT "user_roles_pkey" PRIMARY KEY ("id")
156
+ );
157
+
158
+ -- CreateTable
159
+ CREATE TABLE "role_permissions" (
160
+ "id" BIGSERIAL NOT NULL,
161
+ "role_id" BIGINT NOT NULL,
162
+ "permission_id" BIGINT NOT NULL,
163
+ "created_at" TIMESTAMP(0),
164
+
165
+ CONSTRAINT "role_permissions_pkey" PRIMARY KEY ("id")
166
+ );
167
+
168
+ -- CreateTable
169
+ CREATE TABLE "user_permissions" (
170
+ "id" BIGSERIAL NOT NULL,
171
+ "user_id" BIGINT NOT NULL,
172
+ "permission_id" BIGINT NOT NULL,
173
+ "created_at" TIMESTAMP(0),
174
+
175
+ CONSTRAINT "user_permissions_pkey" PRIMARY KEY ("id")
176
+ );
177
+
178
+ -- CreateIndex
179
+ CREATE UNIQUE INDEX "failed_jobs_uuid_unique" ON "failed_jobs"("uuid");
180
+
181
+ -- CreateIndex
182
+ CREATE INDEX "jobs_queue_index" ON "jobs"("queue");
183
+
184
+ -- CreateIndex
185
+ CREATE UNIQUE INDEX "personal_access_tokens_token_unique" ON "personal_access_tokens"("token");
186
+
187
+ -- CreateIndex
188
+ CREATE INDEX "personal_access_tokens_expires_at_index" ON "personal_access_tokens"("expires_at");
189
+
190
+ -- CreateIndex
191
+ CREATE INDEX "personal_access_tokens_tokenable_type_tokenable_id_index" ON "personal_access_tokens"("tokenable_type", "tokenable_id");
192
+
193
+ -- CreateIndex
194
+ CREATE INDEX "sessions_last_activity_index" ON "sessions"("last_activity");
195
+
196
+ -- CreateIndex
197
+ CREATE INDEX "sessions_user_id_index" ON "sessions"("user_id");
198
+
199
+ -- CreateIndex
200
+ CREATE UNIQUE INDEX "users_uuid_unique" ON "users"("uuid");
201
+
202
+ -- CreateIndex
203
+ CREATE UNIQUE INDEX "users_email_unique" ON "users"("email");
204
+
205
+ -- CreateIndex
206
+ CREATE UNIQUE INDEX "roles_slug_key" ON "roles"("slug");
207
+
208
+ -- CreateIndex
209
+ CREATE UNIQUE INDEX "permissions_slug_key" ON "permissions"("slug");
210
+
211
+ -- CreateIndex
212
+ CREATE UNIQUE INDEX "user_roles_user_id_role_id_key" ON "user_roles"("user_id", "role_id");
213
+
214
+ -- CreateIndex
215
+ CREATE UNIQUE INDEX "role_permissions_role_id_permission_id_key" ON "role_permissions"("role_id", "permission_id");
216
+
217
+ -- CreateIndex
218
+ CREATE UNIQUE INDEX "user_permissions_user_id_permission_id_key" ON "user_permissions"("user_id", "permission_id");
219
+
220
+ -- AddForeignKey
221
+ ALTER TABLE "user_roles" ADD CONSTRAINT "user_roles_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
222
+
223
+ -- AddForeignKey
224
+ ALTER TABLE "user_roles" ADD CONSTRAINT "user_roles_role_id_fkey" FOREIGN KEY ("role_id") REFERENCES "roles"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
225
+
226
+ -- AddForeignKey
227
+ ALTER TABLE "role_permissions" ADD CONSTRAINT "role_permissions_role_id_fkey" FOREIGN KEY ("role_id") REFERENCES "roles"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
228
+
229
+ -- AddForeignKey
230
+ ALTER TABLE "role_permissions" ADD CONSTRAINT "role_permissions_permission_id_fkey" FOREIGN KEY ("permission_id") REFERENCES "permissions"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
231
+
232
+ -- AddForeignKey
233
+ ALTER TABLE "user_permissions" ADD CONSTRAINT "user_permissions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
234
+
235
+ -- AddForeignKey
236
+ ALTER TABLE "user_permissions" ADD CONSTRAINT "user_permissions_permission_id_fkey" FOREIGN KEY ("permission_id") REFERENCES "permissions"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "postgresql"
@@ -0,0 +1,174 @@
1
+ // ⚠️ DO NOT EDIT THIS FILE MANUALLY ⚠️
2
+ // This file is automatically generated by scripts/compile-schema.js
3
+ // Please define your models in src/models/*.prisma instead.
4
+
5
+ generator client {
6
+ provider = "prisma-client"
7
+ output = "../generated/prisma"
8
+ }
9
+
10
+ datasource db {
11
+ provider = "postgresql"
12
+ }
13
+
14
+
15
+
16
+
17
+ model cache {
18
+ key String @id @db.VarChar(255)
19
+ value String
20
+ expiration Int
21
+ }
22
+
23
+ model cache_locks {
24
+ key String @id @db.VarChar(255)
25
+ owner String @db.VarChar(255)
26
+ expiration Int
27
+ }
28
+
29
+ model failed_jobs {
30
+ id BigInt @id @default(autoincrement())
31
+ uuid String @unique(map: "failed_jobs_uuid_unique") @db.VarChar(255)
32
+ connection String
33
+ queue String
34
+ payload String
35
+ exception String
36
+ failed_at DateTime @default(now()) @db.Timestamp(0)
37
+ }
38
+
39
+ model job_batches {
40
+ id String @id @db.VarChar(255)
41
+ name String @db.VarChar(255)
42
+ total_jobs Int
43
+ pending_jobs Int
44
+ failed_jobs Int
45
+ failed_job_ids String
46
+ options String?
47
+ cancelled_at Int?
48
+ created_at Int
49
+ finished_at Int?
50
+ }
51
+
52
+ model jobs {
53
+ id BigInt @id @default(autoincrement())
54
+ queue String @db.VarChar(255)
55
+ payload String
56
+ attempts Int @db.SmallInt
57
+ reserved_at Int?
58
+ available_at Int
59
+ created_at Int
60
+
61
+ @@index([queue], map: "jobs_queue_index")
62
+ }
63
+
64
+ model migrations {
65
+ id Int @id @default(autoincrement())
66
+ migration String @db.VarChar(255)
67
+ batch Int
68
+ }
69
+
70
+ model password_reset_tokens {
71
+ email String @id @db.VarChar(255)
72
+ token String @db.VarChar(255)
73
+ created_at DateTime? @db.Timestamp(0)
74
+ }
75
+
76
+ model personal_access_tokens {
77
+ id BigInt @id @default(autoincrement())
78
+ tokenable_type String @db.VarChar(255)
79
+ tokenable_id BigInt
80
+ name String
81
+ token String @unique(map: "personal_access_tokens_token_unique") @db.VarChar(64)
82
+ abilities String?
83
+ last_used_at DateTime? @db.Timestamp(0)
84
+ expires_at DateTime? @db.Timestamp(0)
85
+ created_at DateTime? @db.Timestamp(0)
86
+ updated_at DateTime? @db.Timestamp(0)
87
+
88
+ @@index([expires_at], map: "personal_access_tokens_expires_at_index")
89
+ @@index([tokenable_type, tokenable_id], map: "personal_access_tokens_tokenable_type_tokenable_id_index")
90
+ }
91
+
92
+ model sessions {
93
+ id String @id @db.VarChar(255)
94
+ user_id BigInt?
95
+ ip_address String? @db.VarChar(45)
96
+ user_agent String?
97
+ payload String
98
+ last_activity Int
99
+
100
+ @@index([last_activity], map: "sessions_last_activity_index")
101
+ @@index([user_id], map: "sessions_user_id_index")
102
+ }
103
+
104
+ /// This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info.
105
+ model users {
106
+ id BigInt @id @default(autoincrement())
107
+ uuid String @unique(map: "users_uuid_unique") @db.Uuid
108
+ name String @db.VarChar(255)
109
+ email String @unique(map: "users_email_unique") @db.VarChar(255)
110
+ avatar String? @db.VarChar(255)
111
+ avatar_url String? @db.VarChar(255)
112
+ email_verified_at DateTime? @db.Timestamp(0)
113
+ password String @db.VarChar(255)
114
+ remember_token String? @db.VarChar(100)
115
+ created_at DateTime? @db.Timestamp(0)
116
+ updated_at DateTime? @db.Timestamp(0)
117
+ user_roles user_roles[]
118
+ user_permissions user_permissions[]
119
+ }
120
+
121
+ model roles {
122
+ id BigInt @id @default(autoincrement())
123
+ name String @db.VarChar(255)
124
+ slug String @unique @db.VarChar(255)
125
+ description String?
126
+ created_at DateTime? @db.Timestamp(0)
127
+ updated_at DateTime? @db.Timestamp(0)
128
+ user_roles user_roles[]
129
+ role_permissions role_permissions[]
130
+ }
131
+
132
+ model permissions {
133
+ id BigInt @id @default(autoincrement())
134
+ name String @db.VarChar(255)
135
+ slug String @unique @db.VarChar(255)
136
+ description String?
137
+ created_at DateTime? @db.Timestamp(0)
138
+ updated_at DateTime? @db.Timestamp(0)
139
+ user_permissions user_permissions[]
140
+ role_permissions role_permissions[]
141
+ }
142
+
143
+ model user_roles {
144
+ id BigInt @id @default(autoincrement())
145
+ user_id BigInt
146
+ role_id BigInt
147
+ created_at DateTime? @db.Timestamp(0)
148
+ users users @relation(fields: [user_id], references: [id], onDelete: Cascade, onUpdate: NoAction)
149
+ roles roles @relation(fields: [role_id], references: [id], onDelete: Cascade, onUpdate: NoAction)
150
+
151
+ @@unique([user_id, role_id])
152
+ }
153
+
154
+ model role_permissions {
155
+ id BigInt @id @default(autoincrement())
156
+ role_id BigInt
157
+ permission_id BigInt
158
+ created_at DateTime? @db.Timestamp(0)
159
+ roles roles @relation(fields: [role_id], references: [id], onDelete: Cascade, onUpdate: NoAction)
160
+ permissions permissions @relation(fields: [permission_id], references: [id], onDelete: Cascade, onUpdate: NoAction)
161
+
162
+ @@unique([role_id, permission_id])
163
+ }
164
+
165
+ model user_permissions {
166
+ id BigInt @id @default(autoincrement())
167
+ user_id BigInt
168
+ permission_id BigInt
169
+ created_at DateTime? @db.Timestamp(0)
170
+ users users @relation(fields: [user_id], references: [id], onDelete: Cascade, onUpdate: NoAction)
171
+ permissions permissions @relation(fields: [permission_id], references: [id], onDelete: Cascade, onUpdate: NoAction)
172
+
173
+ @@unique([user_id, permission_id])
174
+ }