lapeh 2.6.17 → 3.0.2

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 (67) hide show
  1. package/.env.example +1 -6
  2. package/README.md +19 -85
  3. package/bin/index.js +84 -180
  4. package/dist/lib/bootstrap.d.ts.map +1 -1
  5. package/dist/lib/bootstrap.js +17 -16
  6. package/dist/lib/core/store.d.ts +55 -0
  7. package/dist/lib/core/store.d.ts.map +1 -0
  8. package/dist/lib/core/store.js +66 -0
  9. package/dist/lib/middleware/error.d.ts.map +1 -1
  10. package/dist/lib/middleware/error.js +1 -20
  11. package/dist/lib/utils/validator.d.ts.map +1 -1
  12. package/dist/lib/utils/validator.js +3 -32
  13. package/dist/src/modules/Auth/auth.controller.d.ts.map +1 -1
  14. package/dist/src/modules/Auth/auth.controller.js +118 -105
  15. package/dist/src/modules/Rbac/rbac.controller.d.ts.map +1 -1
  16. package/dist/src/modules/Rbac/rbac.controller.js +141 -140
  17. package/dist/src/routes/index.d.ts.map +1 -1
  18. package/dist/src/routes/index.js +0 -5
  19. package/doc/en/CHEATSHEET.md +3 -7
  20. package/doc/en/CLI.md +16 -41
  21. package/doc/en/DEPLOYMENT.md +171 -245
  22. package/doc/en/GETTING_STARTED.md +1 -25
  23. package/doc/en/PACKAGES.md +2 -3
  24. package/doc/en/STRUCTURE.md +1 -11
  25. package/doc/en/TUTORIAL.md +61 -119
  26. package/doc/id/CHANGELOG.md +16 -0
  27. package/doc/id/CHEATSHEET.md +0 -4
  28. package/doc/id/CLI.md +19 -54
  29. package/doc/id/DEPLOYMENT.md +171 -245
  30. package/doc/id/GETTING_STARTED.md +91 -115
  31. package/doc/id/PACKAGES.md +0 -1
  32. package/doc/id/STRUCTURE.md +1 -11
  33. package/doc/id/TUTORIAL.md +51 -109
  34. package/gitignore.template +0 -10
  35. package/lib/bootstrap.ts +39 -38
  36. package/lib/core/store.ts +116 -0
  37. package/lib/middleware/error.ts +1 -21
  38. package/lib/utils/validator.ts +3 -39
  39. package/package.json +4 -18
  40. package/scripts/init-project.js +2 -108
  41. package/scripts/make-module.js +1 -12
  42. package/scripts/seed-json.js +158 -0
  43. package/src/modules/Auth/auth.controller.ts +156 -106
  44. package/src/modules/Rbac/rbac.controller.ts +193 -138
  45. package/src/routes/index.ts +0 -3
  46. package/src/routes/rbac.ts +42 -42
  47. package/storage/logs/.0337f5062fe676994d1dc340156e089444e3d6e0-audit.json +5 -10
  48. package/storage/logs/lapeh-2025-12-30.log +1093 -0
  49. package/tsconfig.build.json +1 -3
  50. package/tsconfig.json +0 -1
  51. package/lib/core/database.ts +0 -5
  52. package/prisma/base.prisma.template +0 -8
  53. package/prisma/migrations/20251225163737_init/migration.sql +0 -236
  54. package/prisma/migrations/20251226000329_create_pets_table/migration.sql +0 -11
  55. package/prisma/migrations/20251226001249_create_pets_table/migration.sql +0 -82
  56. package/prisma/migrations/20251226001717_restore_core_models/migration.sql +0 -236
  57. package/prisma/migrations/migration_lock.toml +0 -3
  58. package/prisma/schema.prisma +0 -197
  59. package/prisma/seed.ts +0 -411
  60. package/scripts/compile-schema.js +0 -64
  61. package/src/modules/Auth/auth.prisma +0 -106
  62. package/src/modules/Pets/pets.controller.ts +0 -238
  63. package/src/modules/Pets/pets.prisma +0 -9
  64. package/src/modules/Rbac/rbac.prisma +0 -68
  65. package/src/routes/pets.ts +0 -13
  66. package/storage/logs/lapeh-2025-12-26.log +0 -88
  67. package/storage/logs/lapeh-2025-12-27.log +0 -217
@@ -1,197 +0,0 @@
1
- generator client {
2
- provider = "prisma-client-js"
3
- }
4
-
5
- datasource db {
6
- provider = "postgresql"
7
- url = env("DATABASE_URL")
8
- }
9
-
10
-
11
- model cache {
12
- id String @id @default(uuid())
13
- key String @unique
14
- value String
15
- expiration Int
16
- }
17
-
18
- model cache_locks {
19
- id String @id @default(uuid())
20
- key String @unique
21
- owner String
22
- expiration Int
23
- }
24
-
25
- model failed_jobs {
26
- id String @id @default(uuid())
27
- uuid String @unique
28
- connection String
29
- queue String
30
- payload String
31
- exception String
32
- failed_at DateTime @default(now())
33
- }
34
-
35
- model job_batches {
36
- id String @id
37
- name String
38
- total_jobs Int
39
- pending_jobs Int
40
- failed_jobs Int
41
- failed_job_ids String
42
- options String?
43
- cancelled_at Int?
44
- created_at Int
45
- finished_at Int?
46
- }
47
-
48
- model jobs {
49
- id String @id @default(uuid())
50
- queue String
51
- payload String
52
- attempts Int
53
- reserved_at Int?
54
- available_at Int
55
- created_at Int
56
-
57
- @@index([queue])
58
- }
59
-
60
- model migrations {
61
- id String @id @default(uuid())
62
- migration String
63
- batch Int
64
- }
65
-
66
- model password_reset_tokens {
67
- id String @id @default(uuid())
68
- email String @unique
69
- token String
70
- created_at DateTime?
71
- }
72
-
73
- model personal_access_tokens {
74
- id String @id @default(uuid())
75
- tokenable_type String
76
- tokenable_id String
77
- name String
78
- token String @unique
79
- abilities String?
80
- last_used_at DateTime?
81
- expires_at DateTime?
82
- created_at DateTime?
83
- updated_at DateTime?
84
-
85
- @@index([expires_at])
86
- @@index([tokenable_type, tokenable_id])
87
- }
88
-
89
- model sessions {
90
- id String @id
91
- user_id String?
92
- ip_address String?
93
- user_agent String?
94
- payload String
95
- last_activity Int
96
-
97
- @@index([last_activity])
98
- @@index([user_id])
99
- }
100
-
101
- model users {
102
- id String @id @default(uuid())
103
- uuid String @unique
104
- name String
105
- email String @unique
106
- avatar String?
107
- avatar_url String?
108
- email_verified_at DateTime?
109
- password String
110
- remember_token String?
111
- created_at DateTime?
112
- updated_at DateTime?
113
-
114
- user_roles user_roles[]
115
- user_permissions user_permissions[]
116
- }
117
-
118
-
119
-
120
- model pets {
121
- id String @id @default(uuid())
122
- name String
123
- species String
124
- age Int
125
- created_at DateTime?
126
- updated_at DateTime?
127
- }
128
-
129
-
130
- model roles {
131
- id String @id @default(uuid())
132
- name String
133
- slug String @unique
134
- description String?
135
- created_at DateTime @default(now())
136
- updated_at DateTime @updatedAt
137
-
138
- user_roles user_roles[]
139
- role_permissions role_permissions[]
140
- }
141
-
142
- model permissions {
143
- id String @id @default(uuid())
144
- name String
145
- slug String @unique
146
- description String?
147
- created_at DateTime @default(now())
148
- updated_at DateTime @updatedAt
149
-
150
- role_permissions role_permissions[]
151
- user_permissions user_permissions[]
152
- }
153
-
154
- model user_roles {
155
- id String @id @default(uuid())
156
- user_id String
157
- role_id String
158
- created_at DateTime @default(now())
159
- updated_at DateTime @updatedAt
160
-
161
- user users @relation(fields: [user_id], references: [id], onDelete: Cascade)
162
- role roles @relation(fields: [role_id], references: [id], onDelete: Cascade)
163
-
164
- @@unique([user_id, role_id])
165
- @@index([user_id])
166
- @@index([role_id])
167
- }
168
-
169
- model role_permissions {
170
- id String @id @default(uuid())
171
- role_id String
172
- permission_id String
173
- created_at DateTime @default(now())
174
- updated_at DateTime @updatedAt
175
-
176
- role roles @relation(fields: [role_id], references: [id], onDelete: Cascade)
177
- permission permissions @relation(fields: [permission_id], references: [id], onDelete: Cascade)
178
-
179
- @@unique([role_id, permission_id])
180
- @@index([role_id])
181
- @@index([permission_id])
182
- }
183
-
184
- model user_permissions {
185
- id String @id @default(uuid())
186
- user_id String
187
- permission_id String
188
- created_at DateTime @default(now())
189
- updated_at DateTime @updatedAt
190
-
191
- user users @relation(fields: [user_id], references: [id], onDelete: Cascade)
192
- permission permissions @relation(fields: [permission_id], references: [id], onDelete: Cascade)
193
-
194
- @@unique([user_id, permission_id])
195
- @@index([user_id])
196
- @@index([permission_id])
197
- }
package/prisma/seed.ts DELETED
@@ -1,411 +0,0 @@
1
- import dotenv from "dotenv";
2
- dotenv.config();
3
-
4
- import { prisma } from "@lapeh/core/database";
5
- import bcrypt from "bcryptjs";
6
- import { v4 as uuidv4 } from "uuid";
7
-
8
- async function main() {
9
- console.log("Start seeding...");
10
-
11
- // 1. Create Users (Super Admin, Admin & User)
12
- const passwordHash = await bcrypt.hash("string", 10);
13
-
14
- const superAdmin = await prisma.users.upsert({
15
- where: { email: "sa@sa.com" },
16
- update: {},
17
- create: {
18
- uuid: uuidv4(),
19
- name: "Super Admin",
20
- email: "sa@sa.com",
21
- password: passwordHash,
22
- created_at: new Date(),
23
- updated_at: new Date(),
24
- },
25
- });
26
- console.log(`Created super admin: ${superAdmin.name}`);
27
-
28
- const admin = await prisma.users.upsert({
29
- where: { email: "a@a.com" },
30
- update: {},
31
- create: {
32
- uuid: uuidv4(),
33
- name: "Admin User",
34
- email: "a@a.com",
35
- password: passwordHash,
36
- created_at: new Date(),
37
- updated_at: new Date(),
38
- },
39
- });
40
- console.log(`Created admin: ${admin.name}`);
41
-
42
- const user = await prisma.users.upsert({
43
- where: { email: "u@u.com" },
44
- update: {},
45
- create: {
46
- uuid: uuidv4(),
47
- name: "Regular User",
48
- email: "u@u.com",
49
- password: passwordHash,
50
- created_at: new Date(),
51
- updated_at: new Date(),
52
- },
53
- });
54
- console.log(`Created user: ${user.name}`);
55
-
56
- // 2. Seed Roles
57
- const superAdminRole = await prisma.roles.upsert({
58
- where: { slug: "super_admin" },
59
- update: {},
60
- create: {
61
- name: "Super Admin",
62
- slug: "super_admin",
63
- description: "Full access to all resources",
64
- created_at: new Date(),
65
- updated_at: new Date(),
66
- },
67
- });
68
-
69
- const adminRole = await prisma.roles.upsert({
70
- where: { slug: "admin" },
71
- update: {},
72
- create: {
73
- name: "Admin",
74
- slug: "admin",
75
- description: "Administrator",
76
- created_at: new Date(),
77
- updated_at: new Date(),
78
- },
79
- });
80
-
81
- const userRole = await prisma.roles.upsert({
82
- where: { slug: "user" },
83
- update: {},
84
- create: {
85
- name: "User",
86
- slug: "user",
87
- description: "Regular user",
88
- created_at: new Date(),
89
- updated_at: new Date(),
90
- },
91
- });
92
-
93
- console.log("Seeded roles");
94
-
95
- // 3. Seed Permissions
96
- const manageUsers = await prisma.permissions.upsert({
97
- where: { slug: "users.manage" },
98
- update: {},
99
- create: {
100
- name: "Manage Users",
101
- slug: "users.manage",
102
- description: "Create, update, and delete users",
103
- created_at: new Date(),
104
- updated_at: new Date(),
105
- },
106
- });
107
- const manageUsersCreate = await prisma.permissions.upsert({
108
- where: { slug: "users.create" },
109
- update: {},
110
- create: {
111
- name: "Create Users",
112
- slug: "users.create",
113
- description: "Create users",
114
- created_at: new Date(),
115
- updated_at: new Date(),
116
- },
117
- });
118
- const manageUsersView = await prisma.permissions.upsert({
119
- where: { slug: "users.view" },
120
- update: {},
121
- create: {
122
- name: "View Users",
123
- slug: "users.view",
124
- description: "View users",
125
- created_at: new Date(),
126
- updated_at: new Date(),
127
- },
128
- });
129
- const manageUsersUpdate = await prisma.permissions.upsert({
130
- where: { slug: "users.update" },
131
- update: {},
132
- create: {
133
- name: "Update Users",
134
- slug: "users.update",
135
- description: "Update users",
136
- created_at: new Date(),
137
- updated_at: new Date(),
138
- },
139
- });
140
- const manageUsersDelete = await prisma.permissions.upsert({
141
- where: { slug: "users.delete" },
142
- update: {},
143
- create: {
144
- name: "Delete Users",
145
- slug: "users.delete",
146
- description: "Delete users",
147
- created_at: new Date(),
148
- updated_at: new Date(),
149
- },
150
- });
151
-
152
- const manageRoles = await prisma.permissions.upsert({
153
- where: { slug: "roles.manage" },
154
- update: {},
155
- create: {
156
- name: "Manage Roles",
157
- slug: "roles.manage",
158
- description: "Create, update, and delete roles",
159
- created_at: new Date(),
160
- updated_at: new Date(),
161
- },
162
- });
163
-
164
- const managePermissions = await prisma.permissions.upsert({
165
- where: { slug: "permissions.manage" },
166
- update: {},
167
- create: {
168
- name: "Manage Permissions",
169
- slug: "permissions.manage",
170
- description: "Create, update, and delete permissions",
171
- created_at: new Date(),
172
- updated_at: new Date(),
173
- },
174
- });
175
-
176
- const manageProfiles = await prisma.permissions.upsert({
177
- where: { slug: "profiles.manage" },
178
- update: {},
179
- create: {
180
- name: "Manage Profiles",
181
- slug: "profiles.manage",
182
- description: "Manage user profiles",
183
- created_at: new Date(),
184
- updated_at: new Date(),
185
- },
186
- });
187
-
188
- console.log("Seeded permissions");
189
-
190
- // 4. Assign permissions to roles
191
- const postsCreate = await prisma.permissions.upsert({
192
- where: { slug: "posts.create" },
193
- update: {},
194
- create: {
195
- name: "Create Posts",
196
- slug: "posts.create",
197
- description: "Create posts",
198
- created_at: new Date(),
199
- updated_at: new Date(),
200
- },
201
- });
202
-
203
- const postsUpdate = await prisma.permissions.upsert({
204
- where: { slug: "posts.update" },
205
- update: {},
206
- create: {
207
- name: "Update Posts",
208
- slug: "posts.update",
209
- description: "Update posts",
210
- created_at: new Date(),
211
- updated_at: new Date(),
212
- },
213
- });
214
-
215
- const postsDelete = await prisma.permissions.upsert({
216
- where: { slug: "posts.delete" },
217
- update: {},
218
- create: {
219
- name: "Delete Posts",
220
- slug: "posts.delete",
221
- description: "Delete posts",
222
- created_at: new Date(),
223
- updated_at: new Date(),
224
- },
225
- });
226
-
227
- const postsView = await prisma.permissions.upsert({
228
- where: { slug: "posts.view" },
229
- update: {},
230
- create: {
231
- name: "View Posts",
232
- slug: "posts.view",
233
- description: "View posts",
234
- created_at: new Date(),
235
- updated_at: new Date(),
236
- },
237
- });
238
-
239
- const categoriesManage = await prisma.permissions.upsert({
240
- where: { slug: "categories.manage" },
241
- update: {},
242
- create: {
243
- name: "Manage Categories",
244
- slug: "categories.manage",
245
- description: "Manage categories",
246
- created_at: new Date(),
247
- updated_at: new Date(),
248
- },
249
- });
250
-
251
- const commentsManage = await prisma.permissions.upsert({
252
- where: { slug: "comments.manage" },
253
- update: {},
254
- create: {
255
- name: "Manage Comments",
256
- slug: "comments.manage",
257
- description: "Manage comments",
258
- created_at: new Date(),
259
- updated_at: new Date(),
260
- },
261
- });
262
-
263
- console.log("Seeded resource permissions");
264
-
265
- // 4. Assign permissions to roles
266
- const rolePermPairs: { roleId: string; permId: string }[] = [
267
- // super_admin gets all users permissions + other management permissions
268
- { roleId: superAdminRole.id, permId: manageUsers.id },
269
- { roleId: superAdminRole.id, permId: manageUsersCreate.id },
270
- { roleId: superAdminRole.id, permId: manageUsersView.id },
271
- { roleId: superAdminRole.id, permId: manageUsersUpdate.id },
272
- { roleId: superAdminRole.id, permId: manageUsersDelete.id },
273
- { roleId: superAdminRole.id, permId: manageRoles.id },
274
- { roleId: superAdminRole.id, permId: managePermissions.id },
275
- { roleId: superAdminRole.id, permId: manageProfiles.id },
276
- { roleId: superAdminRole.id, permId: postsCreate.id },
277
- { roleId: superAdminRole.id, permId: postsUpdate.id },
278
- { roleId: superAdminRole.id, permId: postsDelete.id },
279
- { roleId: superAdminRole.id, permId: postsView.id },
280
- { roleId: superAdminRole.id, permId: categoriesManage.id },
281
- { roleId: superAdminRole.id, permId: commentsManage.id },
282
- // admin gets users permissions except delete
283
- { roleId: adminRole.id, permId: manageUsersCreate.id },
284
- { roleId: adminRole.id, permId: manageUsersView.id },
285
- { roleId: adminRole.id, permId: manageUsersUpdate.id },
286
- // admin gets other management permissions
287
- { roleId: adminRole.id, permId: manageRoles.id },
288
- { roleId: adminRole.id, permId: managePermissions.id },
289
- { roleId: adminRole.id, permId: postsCreate.id },
290
- { roleId: adminRole.id, permId: postsUpdate.id },
291
- { roleId: adminRole.id, permId: postsDelete.id },
292
- { roleId: adminRole.id, permId: postsView.id },
293
- { roleId: adminRole.id, permId: categoriesManage.id },
294
- { roleId: adminRole.id, permId: commentsManage.id },
295
- // user gets read-only posts
296
- { roleId: userRole.id, permId: postsView.id },
297
- ];
298
-
299
- for (const pair of rolePermPairs) {
300
- await prisma.role_permissions.upsert({
301
- where: {
302
- role_id_permission_id: {
303
- role_id: pair.roleId,
304
- permission_id: pair.permId,
305
- },
306
- },
307
- create: {
308
- role_id: pair.roleId,
309
- permission_id: pair.permId,
310
- created_at: new Date(),
311
- },
312
- update: {},
313
- });
314
- }
315
-
316
- console.log("Assigned permissions to roles");
317
-
318
- // 5. Assign roles to users
319
- const userRolePairs: { userId: string; roleId: string }[] = [
320
- { userId: superAdmin.id, roleId: superAdminRole.id },
321
- { userId: admin.id, roleId: adminRole.id },
322
- { userId: user.id, roleId: userRole.id },
323
- ];
324
-
325
- for (const pair of userRolePairs) {
326
- await prisma.user_roles.upsert({
327
- where: {
328
- user_id_role_id: {
329
- user_id: pair.userId,
330
- role_id: pair.roleId,
331
- },
332
- },
333
- create: {
334
- user_id: pair.userId,
335
- role_id: pair.roleId,
336
- created_at: new Date(),
337
- },
338
- update: {},
339
- });
340
- }
341
-
342
- console.log("Assigned roles to users");
343
-
344
- // 6. Seed Pets (Massive Seeding)
345
- console.log("Starting massive pet seeding (50,000 records)...");
346
- const petData = [];
347
- const speciesList = [
348
- "Dog",
349
- "Cat",
350
- "Bird",
351
- "Fish",
352
- "Rabbit",
353
- "Hamster",
354
- "Turtle",
355
- "Parrot",
356
- ];
357
- const names = [
358
- "Bella",
359
- "Max",
360
- "Charlie",
361
- "Luna",
362
- "Lucy",
363
- "Cooper",
364
- "Bailey",
365
- "Daisy",
366
- "Sadie",
367
- "Molly",
368
- ];
369
-
370
- for (let i = 0; i < 50000; i++) {
371
- const species = speciesList[Math.floor(Math.random() * speciesList.length)];
372
- const name = names[Math.floor(Math.random() * names.length)] + " " + i;
373
- const age = Math.floor(Math.random() * 15) + 1;
374
-
375
- petData.push({
376
- name,
377
- species,
378
- age,
379
- created_at: new Date(),
380
- updated_at: new Date(),
381
- });
382
-
383
- // Batch insert every 5000 records to prevent memory issues
384
- if (petData.length === 5000) {
385
- await prisma.pets.createMany({
386
- data: petData,
387
- });
388
- petData.length = 0; // Clear array
389
- console.log(`Seeded ${i + 1} pets...`);
390
- }
391
- }
392
-
393
- // Insert remaining pets
394
- if (petData.length > 0) {
395
- await prisma.pets.createMany({
396
- data: petData,
397
- });
398
- }
399
- console.log("Finished seeding 50,000 pets.");
400
-
401
- console.log("Seeding finished.");
402
- }
403
-
404
- main()
405
- .catch((e) => {
406
- console.error(e);
407
- process.exit(1);
408
- })
409
- .finally(async () => {
410
- await prisma.$disconnect();
411
- });
@@ -1,64 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- const prismaDir = path.join(__dirname, '..', 'prisma');
5
- const modulesDir = path.join(__dirname, '..', 'src', 'modules');
6
- const schemaFile = path.join(prismaDir, 'schema.prisma');
7
- const baseFile = path.join(prismaDir, 'base.prisma.template');
8
-
9
- // Read base schema (datasource & generator)
10
- if (!fs.existsSync(baseFile)) {
11
- console.error(`❌ Base schema template not found at ${baseFile}`);
12
- process.exit(1);
13
- }
14
-
15
- let schemaContent = fs.readFileSync(baseFile, 'utf8');
16
-
17
- // Detect provider from datasource block
18
- const providerMatch = schemaContent.match(/datasource\s+\w+\s+\{[\s\S]*?provider\s*=\s*"([^"]+)"/);
19
- const provider = providerMatch ? providerMatch[1] : 'postgresql';
20
- const isMongo = provider === 'mongodb';
21
-
22
- // Helper to find all .prisma files recursively
23
- function findPrismaFiles(dir, fileList = []) {
24
- if (!fs.existsSync(dir)) return fileList;
25
- const files = fs.readdirSync(dir);
26
- files.forEach(file => {
27
- const filePath = path.join(dir, file);
28
- const stat = fs.statSync(filePath);
29
- if (stat.isDirectory()) {
30
- findPrismaFiles(filePath, fileList);
31
- } else {
32
- if (file.endsWith('.prisma')) {
33
- fileList.push(filePath);
34
- }
35
- }
36
- });
37
- return fileList;
38
- }
39
-
40
- const modelFiles = findPrismaFiles(modulesDir);
41
-
42
- modelFiles.forEach(filePath => {
43
- let content = fs.readFileSync(filePath, 'utf8');
44
-
45
- if (!isMongo) {
46
- // Transform MongoDB specific syntax to SQL compatible syntax
47
- content = content
48
- // Remove @db.ObjectId
49
- .replace(/@db\.ObjectId/g, '')
50
- // Remove @map("_id")
51
- .replace(/@map\("_id"\)/g, '')
52
- // Replace @default(auto()) with @default(uuid()) for Strings
53
- // Note: This is a simple replacement, check your schema if you use auto() for Int
54
- .replace(/@default\(auto\(\)\)/g, '@default(uuid())');
55
- }
56
-
57
- schemaContent += '\n\n' + content;
58
- });
59
-
60
- // Write concatenated content to prisma/schema.prisma
61
- fs.writeFileSync(schemaFile, schemaContent);
62
-
63
- console.log('✅ Prisma schema compiled successfully!');
64
- console.log(` Merged ${modelFiles.length} model files from src/modules/ into prisma/schema.prisma`);