lapeh 2.2.8 → 2.2.9

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 (149) hide show
  1. package/api-testing-enambelas/.env.example +19 -0
  2. package/api-testing-enambelas/doc/ARCHITECTURE_GUIDE.md +73 -0
  3. package/api-testing-enambelas/doc/CHANGELOG.md +77 -0
  4. package/api-testing-enambelas/doc/CHEATSHEET.md +94 -0
  5. package/api-testing-enambelas/doc/CLI.md +106 -0
  6. package/api-testing-enambelas/doc/CONTRIBUTING.md +105 -0
  7. package/api-testing-enambelas/doc/DEPLOYMENT.md +122 -0
  8. package/api-testing-enambelas/doc/FAQ.md +81 -0
  9. package/api-testing-enambelas/doc/FEATURES.md +165 -0
  10. package/api-testing-enambelas/doc/GETTING_STARTED.md +108 -0
  11. package/api-testing-enambelas/doc/INTRODUCTION.md +60 -0
  12. package/api-testing-enambelas/doc/PACKAGES.md +66 -0
  13. package/api-testing-enambelas/doc/PERFORMANCE.md +91 -0
  14. package/api-testing-enambelas/doc/ROADMAP.md +93 -0
  15. package/api-testing-enambelas/doc/SECURITY.md +93 -0
  16. package/api-testing-enambelas/doc/STRUCTURE.md +90 -0
  17. package/api-testing-enambelas/doc/TUTORIAL.md +192 -0
  18. package/api-testing-enambelas/docker-compose.yml +24 -0
  19. package/api-testing-enambelas/eslint.config.mjs +26 -0
  20. package/api-testing-enambelas/framework.md +168 -0
  21. package/api-testing-enambelas/nodemon.json +6 -0
  22. package/api-testing-enambelas/package-lock.json +5527 -0
  23. package/api-testing-enambelas/package.json +106 -0
  24. package/api-testing-enambelas/prisma/base.prisma.template +7 -0
  25. package/api-testing-enambelas/prisma/migrations/20251227042956_init_setup/migration.sql +248 -0
  26. package/api-testing-enambelas/prisma/migrations/migration_lock.toml +3 -0
  27. package/api-testing-enambelas/prisma/schema.prisma +183 -0
  28. package/api-testing-enambelas/prisma/seed.ts +411 -0
  29. package/api-testing-enambelas/prisma.config.ts +15 -0
  30. package/api-testing-enambelas/readme.md +414 -0
  31. package/api-testing-enambelas/scripts/check-update.js +92 -0
  32. package/api-testing-enambelas/scripts/compile-schema.js +29 -0
  33. package/api-testing-enambelas/scripts/config-clear.js +45 -0
  34. package/api-testing-enambelas/scripts/generate-jwt-secret.js +38 -0
  35. package/api-testing-enambelas/scripts/init-project.js +178 -0
  36. package/api-testing-enambelas/scripts/make-controller.js +205 -0
  37. package/api-testing-enambelas/scripts/make-model.js +42 -0
  38. package/api-testing-enambelas/scripts/make-module.js +158 -0
  39. package/api-testing-enambelas/scripts/verify-rbac-functional.js +187 -0
  40. package/api-testing-enambelas/src/controllers/authController.ts +469 -0
  41. package/api-testing-enambelas/src/controllers/petController.ts +194 -0
  42. package/api-testing-enambelas/src/controllers/rbacController.ts +478 -0
  43. package/api-testing-enambelas/src/models/core.prisma +163 -0
  44. package/api-testing-enambelas/src/models/pets.prisma +9 -0
  45. package/api-testing-enambelas/src/routes/auth.ts +74 -0
  46. package/api-testing-enambelas/src/routes/index.ts +10 -0
  47. package/api-testing-enambelas/src/routes/pets.ts +13 -0
  48. package/api-testing-enambelas/src/routes/rbac.ts +42 -0
  49. package/api-testing-enambelas/storage/logs/.gitkeep +0 -0
  50. package/api-testing-enambelas/tsconfig.json +43 -0
  51. package/api-testing-tujuhbelas/.env.example +19 -0
  52. package/api-testing-tujuhbelas/api-testing-enambelas/.env.example +19 -0
  53. package/api-testing-tujuhbelas/api-testing-enambelas/doc/ARCHITECTURE_GUIDE.md +73 -0
  54. package/api-testing-tujuhbelas/api-testing-enambelas/doc/CHANGELOG.md +77 -0
  55. package/api-testing-tujuhbelas/api-testing-enambelas/doc/CHEATSHEET.md +94 -0
  56. package/api-testing-tujuhbelas/api-testing-enambelas/doc/CLI.md +106 -0
  57. package/api-testing-tujuhbelas/api-testing-enambelas/doc/CONTRIBUTING.md +105 -0
  58. package/api-testing-tujuhbelas/api-testing-enambelas/doc/DEPLOYMENT.md +122 -0
  59. package/api-testing-tujuhbelas/api-testing-enambelas/doc/FAQ.md +81 -0
  60. package/api-testing-tujuhbelas/api-testing-enambelas/doc/FEATURES.md +165 -0
  61. package/api-testing-tujuhbelas/api-testing-enambelas/doc/GETTING_STARTED.md +108 -0
  62. package/api-testing-tujuhbelas/api-testing-enambelas/doc/INTRODUCTION.md +60 -0
  63. package/api-testing-tujuhbelas/api-testing-enambelas/doc/PACKAGES.md +66 -0
  64. package/api-testing-tujuhbelas/api-testing-enambelas/doc/PERFORMANCE.md +91 -0
  65. package/api-testing-tujuhbelas/api-testing-enambelas/doc/ROADMAP.md +93 -0
  66. package/api-testing-tujuhbelas/api-testing-enambelas/doc/SECURITY.md +93 -0
  67. package/api-testing-tujuhbelas/api-testing-enambelas/doc/STRUCTURE.md +90 -0
  68. package/api-testing-tujuhbelas/api-testing-enambelas/doc/TUTORIAL.md +192 -0
  69. package/api-testing-tujuhbelas/api-testing-enambelas/docker-compose.yml +24 -0
  70. package/api-testing-tujuhbelas/api-testing-enambelas/eslint.config.mjs +26 -0
  71. package/api-testing-tujuhbelas/api-testing-enambelas/framework.md +168 -0
  72. package/api-testing-tujuhbelas/api-testing-enambelas/nodemon.json +6 -0
  73. package/api-testing-tujuhbelas/api-testing-enambelas/package.json +106 -0
  74. package/api-testing-tujuhbelas/api-testing-enambelas/prisma/base.prisma.template +7 -0
  75. package/api-testing-tujuhbelas/api-testing-enambelas/prisma/schema.prisma +183 -0
  76. package/api-testing-tujuhbelas/api-testing-enambelas/prisma/seed.ts +411 -0
  77. package/api-testing-tujuhbelas/api-testing-enambelas/prisma.config.ts +15 -0
  78. package/api-testing-tujuhbelas/api-testing-enambelas/readme.md +414 -0
  79. package/api-testing-tujuhbelas/api-testing-enambelas/scripts/check-update.js +92 -0
  80. package/api-testing-tujuhbelas/api-testing-enambelas/scripts/compile-schema.js +29 -0
  81. package/api-testing-tujuhbelas/api-testing-enambelas/scripts/config-clear.js +45 -0
  82. package/api-testing-tujuhbelas/api-testing-enambelas/scripts/generate-jwt-secret.js +38 -0
  83. package/api-testing-tujuhbelas/api-testing-enambelas/scripts/init-project.js +178 -0
  84. package/api-testing-tujuhbelas/api-testing-enambelas/scripts/make-controller.js +205 -0
  85. package/api-testing-tujuhbelas/api-testing-enambelas/scripts/make-model.js +42 -0
  86. package/api-testing-tujuhbelas/api-testing-enambelas/scripts/make-module.js +158 -0
  87. package/api-testing-tujuhbelas/api-testing-enambelas/scripts/verify-rbac-functional.js +187 -0
  88. package/api-testing-tujuhbelas/api-testing-enambelas/src/controllers/authController.ts +469 -0
  89. package/api-testing-tujuhbelas/api-testing-enambelas/src/controllers/petController.ts +194 -0
  90. package/api-testing-tujuhbelas/api-testing-enambelas/src/controllers/rbacController.ts +478 -0
  91. package/api-testing-tujuhbelas/api-testing-enambelas/src/models/core.prisma +163 -0
  92. package/api-testing-tujuhbelas/api-testing-enambelas/src/models/pets.prisma +9 -0
  93. package/api-testing-tujuhbelas/api-testing-enambelas/src/routes/auth.ts +74 -0
  94. package/api-testing-tujuhbelas/api-testing-enambelas/src/routes/index.ts +10 -0
  95. package/api-testing-tujuhbelas/api-testing-enambelas/src/routes/pets.ts +13 -0
  96. package/api-testing-tujuhbelas/api-testing-enambelas/src/routes/rbac.ts +42 -0
  97. package/api-testing-tujuhbelas/api-testing-enambelas/storage/logs/.gitkeep +0 -0
  98. package/api-testing-tujuhbelas/api-testing-enambelas/tsconfig.json +43 -0
  99. package/api-testing-tujuhbelas/doc/ARCHITECTURE_GUIDE.md +73 -0
  100. package/api-testing-tujuhbelas/doc/CHANGELOG.md +77 -0
  101. package/api-testing-tujuhbelas/doc/CHEATSHEET.md +94 -0
  102. package/api-testing-tujuhbelas/doc/CLI.md +106 -0
  103. package/api-testing-tujuhbelas/doc/CONTRIBUTING.md +105 -0
  104. package/api-testing-tujuhbelas/doc/DEPLOYMENT.md +122 -0
  105. package/api-testing-tujuhbelas/doc/FAQ.md +81 -0
  106. package/api-testing-tujuhbelas/doc/FEATURES.md +165 -0
  107. package/api-testing-tujuhbelas/doc/GETTING_STARTED.md +108 -0
  108. package/api-testing-tujuhbelas/doc/INTRODUCTION.md +60 -0
  109. package/api-testing-tujuhbelas/doc/PACKAGES.md +66 -0
  110. package/api-testing-tujuhbelas/doc/PERFORMANCE.md +91 -0
  111. package/api-testing-tujuhbelas/doc/ROADMAP.md +93 -0
  112. package/api-testing-tujuhbelas/doc/SECURITY.md +93 -0
  113. package/api-testing-tujuhbelas/doc/STRUCTURE.md +90 -0
  114. package/api-testing-tujuhbelas/doc/TUTORIAL.md +192 -0
  115. package/api-testing-tujuhbelas/docker-compose.yml +24 -0
  116. package/api-testing-tujuhbelas/eslint.config.mjs +26 -0
  117. package/api-testing-tujuhbelas/framework.md +168 -0
  118. package/api-testing-tujuhbelas/nodemon.json +6 -0
  119. package/api-testing-tujuhbelas/package-lock.json +5527 -0
  120. package/api-testing-tujuhbelas/package.json +106 -0
  121. package/api-testing-tujuhbelas/prisma/base.prisma.template +7 -0
  122. package/api-testing-tujuhbelas/prisma/migrations/20251227043210_init_setup/migration.sql +248 -0
  123. package/api-testing-tujuhbelas/prisma/migrations/migration_lock.toml +3 -0
  124. package/api-testing-tujuhbelas/prisma/schema.prisma +183 -0
  125. package/api-testing-tujuhbelas/prisma/seed.ts +411 -0
  126. package/api-testing-tujuhbelas/prisma.config.ts +15 -0
  127. package/api-testing-tujuhbelas/readme.md +414 -0
  128. package/api-testing-tujuhbelas/scripts/check-update.js +92 -0
  129. package/api-testing-tujuhbelas/scripts/compile-schema.js +29 -0
  130. package/api-testing-tujuhbelas/scripts/config-clear.js +45 -0
  131. package/api-testing-tujuhbelas/scripts/generate-jwt-secret.js +38 -0
  132. package/api-testing-tujuhbelas/scripts/init-project.js +178 -0
  133. package/api-testing-tujuhbelas/scripts/make-controller.js +205 -0
  134. package/api-testing-tujuhbelas/scripts/make-model.js +42 -0
  135. package/api-testing-tujuhbelas/scripts/make-module.js +158 -0
  136. package/api-testing-tujuhbelas/scripts/verify-rbac-functional.js +187 -0
  137. package/api-testing-tujuhbelas/src/controllers/authController.ts +469 -0
  138. package/api-testing-tujuhbelas/src/controllers/petController.ts +194 -0
  139. package/api-testing-tujuhbelas/src/controllers/rbacController.ts +478 -0
  140. package/api-testing-tujuhbelas/src/models/core.prisma +163 -0
  141. package/api-testing-tujuhbelas/src/models/pets.prisma +9 -0
  142. package/api-testing-tujuhbelas/src/routes/auth.ts +74 -0
  143. package/api-testing-tujuhbelas/src/routes/index.ts +10 -0
  144. package/api-testing-tujuhbelas/src/routes/pets.ts +13 -0
  145. package/api-testing-tujuhbelas/src/routes/rbac.ts +42 -0
  146. package/api-testing-tujuhbelas/storage/logs/.gitkeep +0 -0
  147. package/api-testing-tujuhbelas/tsconfig.json +43 -0
  148. package/bin/index.js +20 -2
  149. package/package.json +1 -1
@@ -0,0 +1,163 @@
1
+ model cache {
2
+ key String @id
3
+ value String
4
+ expiration Int
5
+ }
6
+
7
+ model cache_locks {
8
+ key String @id
9
+ owner String
10
+ expiration Int
11
+ }
12
+
13
+ model failed_jobs {
14
+ id BigInt @id @default(autoincrement())
15
+ uuid String @unique
16
+ connection String
17
+ queue String
18
+ payload String
19
+ exception String
20
+ failed_at DateTime @default(now())
21
+ }
22
+
23
+ model job_batches {
24
+ id String @id
25
+ name String
26
+ total_jobs Int
27
+ pending_jobs Int
28
+ failed_jobs Int
29
+ failed_job_ids String
30
+ options String?
31
+ cancelled_at Int?
32
+ created_at Int
33
+ finished_at Int?
34
+ }
35
+
36
+ model jobs {
37
+ id BigInt @id @default(autoincrement())
38
+ queue String
39
+ payload String
40
+ attempts Int
41
+ reserved_at Int?
42
+ available_at Int
43
+ created_at Int
44
+
45
+ @@index([queue])
46
+ }
47
+
48
+ model migrations {
49
+ id Int @id @default(autoincrement())
50
+ migration String
51
+ batch Int
52
+ }
53
+
54
+ model password_reset_tokens {
55
+ email String @id
56
+ token String
57
+ created_at DateTime?
58
+ }
59
+
60
+ model personal_access_tokens {
61
+ id BigInt @id @default(autoincrement())
62
+ tokenable_type String
63
+ tokenable_id BigInt
64
+ name String
65
+ token String @unique
66
+ abilities String?
67
+ last_used_at DateTime?
68
+ expires_at DateTime?
69
+ created_at DateTime?
70
+ updated_at DateTime?
71
+
72
+ @@index([expires_at])
73
+ @@index([tokenable_type, tokenable_id])
74
+ }
75
+
76
+ model sessions {
77
+ id String @id
78
+ user_id BigInt?
79
+ ip_address String?
80
+ user_agent String?
81
+ payload String
82
+ last_activity Int
83
+
84
+ @@index([last_activity])
85
+ @@index([user_id])
86
+ }
87
+
88
+ model users {
89
+ id BigInt @id @default(autoincrement())
90
+ uuid String @unique
91
+ name String
92
+ email String @unique
93
+ avatar String?
94
+ avatar_url String?
95
+ email_verified_at DateTime?
96
+ password String
97
+ remember_token String?
98
+ created_at DateTime?
99
+ updated_at DateTime?
100
+
101
+ user_roles user_roles[]
102
+ user_permissions user_permissions[]
103
+ }
104
+
105
+ model roles {
106
+ id BigInt @id @default(autoincrement())
107
+ name String
108
+ slug String @unique
109
+ description String?
110
+ created_at DateTime?
111
+ updated_at DateTime?
112
+
113
+ user_roles user_roles[]
114
+ role_permissions role_permissions[]
115
+ }
116
+
117
+ model permissions {
118
+ id BigInt @id @default(autoincrement())
119
+ name String
120
+ slug String @unique
121
+ description String?
122
+ created_at DateTime?
123
+ updated_at DateTime?
124
+
125
+ role_permissions role_permissions[]
126
+ user_permissions user_permissions[]
127
+ }
128
+
129
+ model user_roles {
130
+ id BigInt @id @default(autoincrement())
131
+ user_id BigInt
132
+ role_id BigInt
133
+ created_at DateTime?
134
+
135
+ user users @relation(fields: [user_id], references: [id], onDelete: Cascade, onUpdate: NoAction)
136
+ role roles @relation(fields: [role_id], references: [id], onDelete: Cascade, onUpdate: NoAction)
137
+
138
+ @@unique([user_id, role_id])
139
+ }
140
+
141
+ model role_permissions {
142
+ id BigInt @id @default(autoincrement())
143
+ role_id BigInt
144
+ permission_id BigInt
145
+ created_at DateTime?
146
+
147
+ role roles @relation(fields: [role_id], references: [id], onDelete: Cascade, onUpdate: NoAction)
148
+ permission permissions @relation(fields: [permission_id], references: [id], onDelete: Cascade, onUpdate: NoAction)
149
+
150
+ @@unique([role_id, permission_id])
151
+ }
152
+
153
+ model user_permissions {
154
+ id BigInt @id @default(autoincrement())
155
+ user_id BigInt
156
+ permission_id BigInt
157
+ created_at DateTime?
158
+
159
+ user users @relation(fields: [user_id], references: [id], onDelete: Cascade, onUpdate: NoAction)
160
+ permission permissions @relation(fields: [permission_id], references: [id], onDelete: Cascade, onUpdate: NoAction)
161
+
162
+ @@unique([user_id, permission_id])
163
+ }
@@ -0,0 +1,9 @@
1
+
2
+ model pets {
3
+ id BigInt @id @default(autoincrement())
4
+ name String
5
+ species String
6
+ age Int
7
+ created_at DateTime?
8
+ updated_at DateTime?
9
+ }
@@ -0,0 +1,74 @@
1
+ import { Router } from "express";
2
+ import rateLimit from "express-rate-limit";
3
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
4
+ const multer = require("multer");
5
+ import path from "path";
6
+ import fs from "fs";
7
+ import {
8
+ register,
9
+ login,
10
+ me,
11
+ logout,
12
+ refreshToken,
13
+ updatePassword,
14
+ updateProfile,
15
+ updateAvatar,
16
+ } from "@/controllers/authController";
17
+ import { requireAuth } from "@lapeh/middleware/auth";
18
+
19
+ const authLimiter = rateLimit({
20
+ windowMs: 15 * 60 * 1000,
21
+ max: 50,
22
+ standardHeaders: true,
23
+ legacyHeaders: false,
24
+ });
25
+
26
+ const avatarUploadDir = process.env.AVATAR_UPLOAD_DIR || "uploads/avatars";
27
+ if (!fs.existsSync(avatarUploadDir)) {
28
+ fs.mkdirSync(avatarUploadDir, { recursive: true });
29
+ }
30
+
31
+ const storage = (multer as any).diskStorage({
32
+ destination(
33
+ _req: any,
34
+ _file: any,
35
+ cb: (error: Error | null, destination: string) => void
36
+ ) {
37
+ cb(null, avatarUploadDir);
38
+ },
39
+ filename(
40
+ _req: any,
41
+ file: any,
42
+ cb: (error: Error | null, filename: string) => void
43
+ ) {
44
+ const ext = path.extname(file.originalname);
45
+ const base = path.basename(file.originalname, ext);
46
+ const unique = Date.now() + "-" + Math.round(Math.random() * 1e9);
47
+ cb(null, base + "-" + unique + ext);
48
+ },
49
+ });
50
+
51
+ const uploadAvatar = multer({ storage });
52
+
53
+ export const authRouter = Router();
54
+
55
+ authRouter.post("/register", authLimiter, register);
56
+
57
+ authRouter.post("/login", authLimiter, login);
58
+
59
+ authRouter.get("/me", requireAuth, me);
60
+
61
+ authRouter.post("/logout", requireAuth, logout);
62
+
63
+ authRouter.post("/refresh", authLimiter, refreshToken);
64
+
65
+ authRouter.put("/password", requireAuth, updatePassword);
66
+
67
+ authRouter.put("/profile", requireAuth, updateProfile);
68
+
69
+ authRouter.post(
70
+ "/avatar",
71
+ requireAuth,
72
+ uploadAvatar.single("avatar"),
73
+ updateAvatar
74
+ );
@@ -0,0 +1,10 @@
1
+ import { Router } from "express";
2
+ import { authRouter } from "@/routes/auth";
3
+ import { rbacRouter } from "@/routes/rbac";
4
+ import petRouter from "@/routes/pets";
5
+
6
+ export const apiRouter = Router();
7
+
8
+ apiRouter.use("/auth", authRouter);
9
+ apiRouter.use("/rbac", rbacRouter);
10
+ apiRouter.use("/pets", petRouter);
@@ -0,0 +1,13 @@
1
+ import { Router } from "express";
2
+ import * as PetController from "@/controllers/petController";
3
+ import { parseMultipart } from "@lapeh/middleware/multipart";
4
+
5
+ const router = Router();
6
+
7
+ router.get("/", PetController.index);
8
+ router.get("/:id", PetController.show);
9
+ router.post("/", parseMultipart, PetController.store);
10
+ router.put("/:id", parseMultipart, PetController.update);
11
+ router.delete("/:id", PetController.destroy);
12
+
13
+ export default router;
@@ -0,0 +1,42 @@
1
+ import { Router } from "express";
2
+ import { requireAdmin, requireAuth } from "@lapeh/middleware/auth";
3
+ import {
4
+ createRole,
5
+ listRoles,
6
+ updateRole,
7
+ deleteRole,
8
+ createPermission,
9
+ listPermissions,
10
+ updatePermission,
11
+ deletePermission,
12
+ assignRoleToUser,
13
+ removeRoleFromUser,
14
+ assignPermissionToRole,
15
+ removePermissionFromRole,
16
+ assignPermissionToUser,
17
+ removePermissionFromUser,
18
+ } from "@/controllers/rbacController";
19
+
20
+ export const rbacRouter = Router();
21
+
22
+ rbacRouter.use(requireAuth);
23
+ rbacRouter.use(requireAdmin);
24
+
25
+ rbacRouter.post("/roles", createRole);
26
+ rbacRouter.get("/roles", listRoles);
27
+ rbacRouter.put("/roles/:id", updateRole);
28
+ rbacRouter.delete("/roles/:id", deleteRole);
29
+
30
+ rbacRouter.post("/permissions", createPermission);
31
+ rbacRouter.get("/permissions", listPermissions);
32
+ rbacRouter.put("/permissions/:id", updatePermission);
33
+ rbacRouter.delete("/permissions/:id", deletePermission);
34
+
35
+ rbacRouter.post("/users/assign-role", assignRoleToUser);
36
+ rbacRouter.post("/users/remove-role", removeRoleFromUser);
37
+
38
+ rbacRouter.post("/roles/assign-permission", assignPermissionToRole);
39
+ rbacRouter.post("/roles/remove-permission", removePermissionFromRole);
40
+
41
+ rbacRouter.post("/users/assign-permission", assignPermissionToUser);
42
+ rbacRouter.post("/users/remove-permission", removePermissionFromUser);
File without changes
@@ -0,0 +1,43 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "CommonJS",
5
+ "outDir": "dist",
6
+ "rootDir": ".",
7
+ "declaration": true,
8
+ "declarationMap": true,
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "noUnusedLocals": true,
14
+ "noUnusedParameters": true,
15
+ "paths": {
16
+ "@lapeh/*": [
17
+ "./node_modules/lapeh/lib/*"
18
+ ],
19
+ "@/*": [
20
+ "./src/*"
21
+ ],
22
+ "@lapeh/core/database": [
23
+ "./node_modules/lapeh/lib/prisma.ts"
24
+ ]
25
+ },
26
+ "baseUrl": "."
27
+ },
28
+ "include": [
29
+ "lib",
30
+ "src",
31
+ "prisma",
32
+ "generated"
33
+ ],
34
+ "exclude": [
35
+ "node_modules",
36
+ "dist"
37
+ ],
38
+ "ts-node": {
39
+ "ignore": [
40
+ "node_modules/(?!lapeh)"
41
+ ]
42
+ }
43
+ }
@@ -0,0 +1,19 @@
1
+ PORT=8000
2
+ DATABASE_PROVIDER="postgresql"
3
+ DATABASE_URL="postgresql://sianu:12341234@localhost:5432/db_example_test?schema=public"
4
+
5
+ # Used for all encryption-related tasks in the framework (JWT, etc.)
6
+ JWT_SECRET="replace_this_with_a_secure_random_string"
7
+
8
+ # Framework Timezone
9
+ TZ="Asia/Jakarta"
10
+
11
+ # Redis Configuration (Optional)
12
+ # If REDIS_URL is not set or connection fails, the framework will automatically
13
+ # switch to an in-memory Redis mock (bundled). No installation required for development.
14
+ # REDIS_URL="redis://lapeh:12341234@localhost:6379"
15
+ # NO_REDIS="true"
16
+
17
+ # To force disable Redis and use in-memory mock even if Redis is available:
18
+ # NO_REDIS="true"
19
+
@@ -0,0 +1,19 @@
1
+ PORT=8000
2
+ DATABASE_PROVIDER="postgresql"
3
+ DATABASE_URL="postgresql://sianu:12341234@localhost:5432/db_example_test?schema=public"
4
+
5
+ # Used for all encryption-related tasks in the framework (JWT, etc.)
6
+ JWT_SECRET="replace_this_with_a_secure_random_string"
7
+
8
+ # Framework Timezone
9
+ TZ="Asia/Jakarta"
10
+
11
+ # Redis Configuration (Optional)
12
+ # If REDIS_URL is not set or connection fails, the framework will automatically
13
+ # switch to an in-memory Redis mock (bundled). No installation required for development.
14
+ # REDIS_URL="redis://lapeh:12341234@localhost:6379"
15
+ # NO_REDIS="true"
16
+
17
+ # To force disable Redis and use in-memory mock even if Redis is available:
18
+ # NO_REDIS="true"
19
+
@@ -0,0 +1,73 @@
1
+ # Panduan Arsitektur: Menuju "Framework as a Dependency" (Next.js Style)
2
+
3
+ Saat ini, Lapeh menggunakan pendekatan **Boilerplate** (seperti Laravel), di mana pengguna mendapatkan seluruh kode sumber (`src/`) dan bertanggung jawab atas `express`, `prisma`, dll.
4
+
5
+ Untuk mengubahnya menjadi seperti **Next.js** (di mana pengguna hanya menginstall `lapeh` dan `package.json` mereka bersih), kita perlu mengubah arsitektur menjadi **Library**.
6
+
7
+ ## 1. Perbedaan Utama
8
+
9
+ | Fitur | Boilerplate (Lapeh Saat Ini) | Library (Next.js Style) |
10
+ | :--- | :--- | :--- |
11
+ | **Instalasi** | `git clone` / `npx create-lapeh` | `npm install lapeh` |
12
+ | **package.json** | Banyak dependency (`express`, `cors`, dll) | Sedikit (`lapeh`, `react`) |
13
+ | **Scripts** | Panjang (`nodemon src/index.ts`) | Pendek (`lapeh dev`) |
14
+ | **Core Code** | Terbuka di `src/core/` | Tersembunyi di `node_modules/lapeh` |
15
+ | **Update** | Susah (harus merge manual) | Mudah (`npm update lapeh`) |
16
+
17
+ ## 2. Langkah Implementasi
18
+
19
+ Saya telah memulai langkah pertama dengan menambahkan **CLI Runner** di `bin/index.js`.
20
+
21
+ ### A. Update CLI (`bin/index.js`) ✅ (Sudah Dilakukan)
22
+ Saya sudah menambahkan command `dev`, `start`, dan `build` ke dalam CLI Lapeh. Ini memungkinkan pengguna menjalankan server tanpa tahu perintah aslinya.
23
+
24
+ ```javascript
25
+ // Contoh penggunaan nanti:
26
+ "scripts": {
27
+ "dev": "lapeh dev",
28
+ "build": "lapeh build",
29
+ "start": "lapeh start"
30
+ }
31
+ ```
32
+
33
+ ### B. Struktur Project Pengguna (Target)
34
+ Nantinya, project pengguna Lapeh hanya akan berisi file bisnis mereka:
35
+
36
+ ```text
37
+ my-app/
38
+ ├── src/
39
+ │ ├── controllers/
40
+ │ ├── routes/
41
+ │ └── models/
42
+ ├── lapeh.config.ts <-- Konfigurasi framework (pengganti edit core)
43
+ └── package.json
44
+ ```
45
+
46
+ Dan `package.json` mereka akan terlihat seperti ini:
47
+
48
+ ```json
49
+ {
50
+ "name": "my-app",
51
+ "dependencies": {
52
+ "lapeh": "^2.0.0"
53
+ },
54
+ "scripts": {
55
+ "dev": "lapeh dev",
56
+ "build": "lapeh build",
57
+ "start": "lapeh start"
58
+ }
59
+ }
60
+ ```
61
+
62
+ ### C. Apa yang Harus Dilakukan Selanjutnya?
63
+
64
+ 1. **Publish Package**: Anda perlu mempublish folder framework ini ke NPM (atau private registry).
65
+ * Pastikan `express`, `cors`, `helmet`, dll ada di `dependencies` (bukan `devDependencies`).
66
+ 2. **Abstraksi `src/index.ts`**:
67
+ * Saat ini `src/index.ts` adalah entry point yang diedit user.
68
+ * Ubah agar `lapeh dev` menjalankan server internal yang **mengimpor** routes/controller user secara dinamis (seperti Next.js pages router).
69
+ 3. **Config Loader**:
70
+ * Buat sistem pembacaan `lapeh.config.ts` untuk mengatur Port, Database URL, dll tanpa mengedit kode core.
71
+
72
+ ## 3. Kesimpulan
73
+ Perubahan yang saya lakukan di `bin/index.js` adalah fondasi untuk CLI style. Untuk mencapai "Clean package.json" sepenuhnya, Anda harus memisahkan **Framework Core** (repo ini) dengan **User Project** (repo baru yang menginstall framework ini).
@@ -0,0 +1,77 @@
1
+ # Dokumentasi Perubahan Lapeh Framework
2
+
3
+ File ini mencatat semua perubahan, pembaruan, dan perbaikan yang dilakukan pada framework Lapeh, diurutkan berdasarkan tanggal.
4
+
5
+ ## [2025-12-27] - Code Quality & Standardization Update
6
+
7
+ ### 🚀 Fitur & Standarisasi
8
+
9
+ - **Standardized Import Paths**:
10
+ - Implementasi path alias `@/` untuk import yang lebih bersih (e.g., `import { prisma } from "@/core/database"`).
11
+ - Penghapusan penggunaan relative paths yang dalam (`../../../`).
12
+ - Konfigurasi `tsconfig.json` tanpa `baseUrl` (mengikuti standar TypeScript 6.0+).
13
+ - **Strict Linting & Code Quality**:
14
+ - Implementasi aturan **ESLint** ketat untuk mencegah "Dead Code".
15
+ - Error otomatis untuk variabel, parameter, dan import yang tidak digunakan (`no-unused-vars`).
16
+ - Script `npm run lint` dan `npm run lint:fix` untuk pembersihan kode otomatis.
17
+ - **Fastify-Style Standardization**:
18
+ - Penerapan standar respon cepat (`sendFastSuccess`) di seluruh controller (`AuthController`, `RbacController`, `PetController`).
19
+ - Penggunaan **Schema-based Serialization** untuk performa JSON maksimal.
20
+ - Konversi otomatis `BigInt` ke `string` dalam respon JSON.
21
+
22
+ ## [2025-12-27] - High Performance & Scalability Update
23
+
24
+ ### 🚀 Fitur Baru
25
+
26
+ - **High Performance Serialization (Fastify-Style)**:
27
+ - Implementasi `fast-json-stringify` untuk serialisasi JSON super cepat (2x-3x lebih cepat dari `JSON.stringify`).
28
+ - Helper `sendFastSuccess` di `src/utils/response.ts` untuk mem-bypass overhead Express.
29
+ - Caching schema serializer otomatis di `src/core/serializer.ts`.
30
+ - **Scalability & Clustering**:
31
+ - Dukungan **Load Balancing** dengan Nginx.
32
+ - Dukungan **Redis Clustering** untuk Rate Limiter (`rate-limit-redis`).
33
+ - File konfigurasi `docker-compose.cluster.yml` untuk simulasi cluster lokal (1 Nginx + 2 App Instances + 1 Redis).
34
+ - **Smart Error Handling**:
35
+ - Deteksi otomatis port bentrok (`EADDRINUSE`) saat startup.
36
+ - Memberikan saran command _copy-paste_ untuk mematikan process yang memblokir port (support Windows, Mac, Linux).
37
+ - **SEO Optimization**:
38
+ - Update metadata `package.json` dan `README.md` agar framework lebih mudah ditemukan di Google/NPM.
39
+
40
+ ## [2025-12-27] - Pembaruan Struktur & Validasi
41
+
42
+ ### 🚀 Fitur Baru
43
+
44
+ - **Laravel-style Validator**:
45
+ - Implementasi utility `Validator` baru di `src/utils/validator.ts` yang meniru gaya validasi Laravel.
46
+ - Mendukung rule string seperti `required|string|min:3|email`.
47
+ - Penambahan rule `unique` untuk pengecekan database otomatis (Prisma).
48
+ - Penambahan rule `mimes`, `image`, `max` (file size) untuk validasi upload file.
49
+ - Penambahan rule `sometimes` untuk field opsional.
50
+ - **Framework Hardening (Keamanan & Stabilitas)**:
51
+ - **Rate Limiting**: Middleware anti-spam/brute-force di `src/middleware/rateLimit.ts`.
52
+ - **Request Logger**: Pencatatan log request masuk di `src/middleware/requestLogger.ts`.
53
+ - **Health Check**: Endpoint `/` kini mengembalikan status kesehatan server.
54
+ - **Graceful Shutdown**: Penanganan penutupan koneksi Database dan Redis yang aman saat server berhenti (`SIGTERM`/`SIGINT`).
55
+ - **Environment Validation**: Validasi variabel `.env` wajib (seperti `DATABASE_URL`, `JWT_SECRET`) saat startup.
56
+ - **Struktur Folder Baru**:
57
+ - Pemisahan konfigurasi inti ke `src/core/` (`server.ts`, `database.ts`, `redis.ts`, `realtime.ts`) agar folder `src` lebih bersih.
58
+ - Sentralisasi route di `src/routes/index.ts` (WIP).
59
+ - **CLI Improvements**:
60
+ - `npx lapeh <project-name> --full` kini otomatis menjalankan server dev setelah instalasi selesai, sehingga user bisa langsung melihat hasil tanpa mengetik perintah tambahan.
61
+
62
+ ### 🛠️ Perbaikan & Refactoring
63
+
64
+ - **Controller Refactoring**:
65
+ - `AuthController`: Migrasi ke `Validator` baru, termasuk validasi upload avatar.
66
+ - `PetController`: Migrasi ke `Validator` baru.
67
+ - `RbacController`: Migrasi sebagian ke `Validator` baru.
68
+ - **Pembersihan**:
69
+ - Penghapusan folder `src/schema/` (Zod schema lama) karena sudah digantikan oleh `Validator` utility.
70
+ - Penghapusan file duplikat/lama di root `src/` setelah migrasi ke `src/core/`.
71
+
72
+ ### 📝 Catatan Teknis
73
+
74
+ - **Validator Async**: Method `fails()`, `passes()`, dan `validated()` kini bersifat `async` untuk mendukung pengecekan database (`unique`).
75
+ - **Type Safety**: Semua perubahan telah diverifikasi dengan `npm run typecheck`.
76
+
77
+ ---
@@ -0,0 +1,94 @@
1
+ # Lapeh Framework Cheatsheet
2
+
3
+ Referensi cepat untuk perintah dan kode yang sering digunakan.
4
+
5
+ ## 💻 CLI Commands
6
+
7
+ | Perintah | Fungsi |
8
+ | :----------------------------------- | :------------------------------------------- |
9
+ | **`npm run dev`** | Menjalankan server development (hot-reload). |
10
+ | **`npm run typecheck`** | Cek error TypeScript (tanpa compile). |
11
+ | **`npm run lint`** | Cek kode kotor/variabel tidak terpakai. |
12
+ | **`npm run lint:fix`** | Perbaiki kode kotor otomatis. |
13
+ | **`npm run make:module <Name>`** | Buat Controller, Route, & Model sekaligus. |
14
+ | **`npm run make:controller <Name>`** | Buat Controller saja. |
15
+ | **`npm run make:model <Name>`** | Buat Model Prisma saja. |
16
+ | **`npm run prisma:migrate`** | Apply perubahan schema ke DB lokal. |
17
+ | **`npm run db:studio`** | Buka GUI Database. |
18
+ | **`npm run db:seed`** | Isi data dummy. |
19
+ | **`npm run db:reset`** | Hapus DB & mulai dari nol. |
20
+
21
+ ## 🛡️ Validator Rules (Laravel-Style)
22
+
23
+ Gunakan di `Validator.make(data, rules)`.
24
+
25
+ | Rule | Deskripsi | Contoh |
26
+ | :----------------- | :---------------------- | :---------------------------------- | -------- |
27
+ | `required` | Wajib ada & tidak null. | `"required"` |
28
+ | `string` | Harus text. | `"required | string"` |
29
+ | `number` | Harus angka. | `"required | number"` |
30
+ | `email` | Format email valid. | `"required | email"` |
31
+ | `min:X` | Min panjang/nilai. | `"min:8"` (pass), `"min:18"` (umur) |
32
+ | `max:X` | Max panjang/nilai. | `"max:255"` |
33
+ | `unique:table,col` | Cek unik di DB. | `"unique:users,email"` |
34
+ | `exists:table,col` | Cek exist di DB. | `"exists:roles,id"` |
35
+ | `image` | File harus gambar. | `"required | image"` |
36
+ | `mimes:types` | File extension. | `"mimes:pdf,docx"` |
37
+
38
+ ## 🔑 Authentication
39
+
40
+ **Middleware di Route:**
41
+
42
+ ```typescript
43
+ import { requireAuth, requireAdmin } from "@/middleware/auth";
44
+
45
+ router.get("/profile", requireAuth, getProfile); // Login User
46
+ router.delete("/user", requireAuth, requireAdmin, del); // Admin Only
47
+ ```
48
+
49
+ **Akses User di Controller:**
50
+
51
+ ```typescript
52
+ // (req as any).user tersedia setelah requireAuth
53
+ const userId = (req as any).user.userId;
54
+ const role = (req as any).user.role;
55
+ ```
56
+
57
+ ## ⚡ Fast Response (Serializer)
58
+
59
+ **1. Schema:**
60
+
61
+ ```typescript
62
+ const schema = {
63
+ type: "object",
64
+ properties: {
65
+ id: { type: "string" },
66
+ name: { type: "string" },
67
+ },
68
+ };
69
+ ```
70
+
71
+ **2. Serializer:**
72
+
73
+ ```typescript
74
+ const serializer = getSerializer("key-name", createResponseSchema(schema));
75
+ ```
76
+
77
+ **3. Send:**
78
+
79
+ ```typescript
80
+ sendFastSuccess(res, 200, serializer, { ...data });
81
+ ```
82
+
83
+ ## 📦 Redis (Cache)
84
+
85
+ ```typescript
86
+ import { redis } from "@lapeh/core/redis";
87
+
88
+ // Set Cache (Key, Value, Mode, Detik)
89
+ await redis.set("profile:1", JSON.stringify(data), "EX", 3600);
90
+
91
+ // Get Cache
92
+ const cached = await redis.get("profile:1");
93
+ if (cached) return JSON.parse(cached);
94
+ ```