lapeh 2.3.6 → 2.3.8
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/bin/index.js +39 -56
- package/dist/generated/prisma/browser.d.ts +80 -0
- package/dist/generated/prisma/browser.d.ts.map +1 -0
- package/dist/generated/prisma/browser.js +56 -0
- package/dist/generated/prisma/client.d.ts +97 -0
- package/dist/generated/prisma/client.d.ts.map +1 -0
- package/dist/generated/prisma/client.js +68 -0
- package/dist/generated/prisma/commonInputTypes.d.ts +486 -0
- package/dist/generated/prisma/commonInputTypes.d.ts.map +1 -0
- package/dist/generated/prisma/commonInputTypes.js +11 -0
- package/dist/generated/prisma/enums.d.ts +2 -0
- package/dist/generated/prisma/enums.d.ts.map +1 -0
- package/dist/generated/prisma/enums.js +11 -0
- package/dist/generated/prisma/internal/class.d.ts +281 -0
- package/dist/generated/prisma/internal/class.d.ts.map +1 -0
- package/dist/generated/prisma/internal/class.js +76 -0
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +1734 -0
- package/dist/generated/prisma/internal/prismaNamespace.d.ts.map +1 -0
- package/dist/generated/prisma/internal/prismaNamespace.js +260 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +200 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts.map +1 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +231 -0
- package/dist/generated/prisma/models/cache.d.ts +986 -0
- package/dist/generated/prisma/models/cache.d.ts.map +1 -0
- package/dist/generated/prisma/models/cache.js +2 -0
- package/dist/generated/prisma/models/cache_locks.d.ts +976 -0
- package/dist/generated/prisma/models/cache_locks.d.ts.map +1 -0
- package/dist/generated/prisma/models/cache_locks.js +2 -0
- package/dist/generated/prisma/models/failed_jobs.d.ts +1098 -0
- package/dist/generated/prisma/models/failed_jobs.d.ts.map +1 -0
- package/dist/generated/prisma/models/failed_jobs.js +2 -0
- package/dist/generated/prisma/models/job_batches.d.ts +1212 -0
- package/dist/generated/prisma/models/job_batches.d.ts.map +1 -0
- package/dist/generated/prisma/models/job_batches.js +2 -0
- package/dist/generated/prisma/models/jobs.d.ts +1112 -0
- package/dist/generated/prisma/models/jobs.d.ts.map +1 -0
- package/dist/generated/prisma/models/jobs.js +2 -0
- package/dist/generated/prisma/models/migrations.d.ts +979 -0
- package/dist/generated/prisma/models/migrations.d.ts.map +1 -0
- package/dist/generated/prisma/models/migrations.js +2 -0
- package/dist/generated/prisma/models/password_reset_tokens.d.ts +941 -0
- package/dist/generated/prisma/models/password_reset_tokens.d.ts.map +1 -0
- package/dist/generated/prisma/models/password_reset_tokens.js +2 -0
- package/dist/generated/prisma/models/permissions.d.ts +1333 -0
- package/dist/generated/prisma/models/permissions.d.ts.map +1 -0
- package/dist/generated/prisma/models/permissions.js +2 -0
- package/dist/generated/prisma/models/personal_access_tokens.d.ts +1178 -0
- package/dist/generated/prisma/models/personal_access_tokens.d.ts.map +1 -0
- package/dist/generated/prisma/models/personal_access_tokens.js +2 -0
- package/dist/generated/prisma/models/role_permissions.d.ts +1291 -0
- package/dist/generated/prisma/models/role_permissions.d.ts.map +1 -0
- package/dist/generated/prisma/models/role_permissions.js +2 -0
- package/dist/generated/prisma/models/roles.d.ts +1333 -0
- package/dist/generated/prisma/models/roles.d.ts.map +1 -0
- package/dist/generated/prisma/models/roles.js +2 -0
- package/dist/generated/prisma/models/sessions.d.ts +1073 -0
- package/dist/generated/prisma/models/sessions.d.ts.map +1 -0
- package/dist/generated/prisma/models/sessions.js +2 -0
- package/dist/generated/prisma/models/user_permissions.d.ts +1291 -0
- package/dist/generated/prisma/models/user_permissions.d.ts.map +1 -0
- package/dist/generated/prisma/models/user_permissions.js +2 -0
- package/dist/generated/prisma/models/user_roles.d.ts +1291 -0
- package/dist/generated/prisma/models/user_roles.d.ts.map +1 -0
- package/dist/generated/prisma/models/user_roles.js +2 -0
- package/dist/generated/prisma/models/users.d.ts +1513 -0
- package/dist/generated/prisma/models/users.d.ts.map +1 -0
- package/dist/generated/prisma/models/users.js +2 -0
- package/dist/generated/prisma/models.d.ts +17 -0
- package/dist/generated/prisma/models.d.ts.map +1 -0
- package/dist/generated/prisma/models.js +2 -0
- package/dist/lib/bootstrap.d.ts +2 -0
- package/dist/lib/bootstrap.d.ts.map +1 -0
- package/dist/lib/bootstrap.js +133 -0
- package/dist/lib/core/database.d.ts +3 -0
- package/dist/lib/core/database.d.ts.map +1 -0
- package/dist/lib/core/database.js +34 -0
- package/dist/lib/core/realtime.d.ts +3 -0
- package/dist/lib/core/realtime.d.ts.map +1 -0
- package/dist/lib/core/realtime.js +36 -0
- package/dist/lib/core/redis.d.ts +8 -0
- package/dist/lib/core/redis.d.ts.map +1 -0
- package/dist/lib/core/redis.js +123 -0
- package/dist/lib/core/serializer.d.ts +43 -0
- package/dist/lib/core/serializer.d.ts.map +1 -0
- package/dist/lib/core/serializer.js +66 -0
- package/dist/lib/core/server.d.ts +2 -0
- package/dist/lib/core/server.d.ts.map +1 -0
- package/dist/lib/core/server.js +60 -0
- package/dist/lib/middleware/auth.d.ts +4 -0
- package/dist/lib/middleware/auth.d.ts.map +1 -0
- package/dist/lib/middleware/auth.js +55 -0
- package/dist/lib/middleware/error.d.ts +3 -0
- package/dist/lib/middleware/error.d.ts.map +1 -0
- package/dist/lib/middleware/error.js +60 -0
- package/dist/lib/middleware/multipart.d.ts +4 -0
- package/dist/lib/middleware/multipart.d.ts.map +1 -0
- package/dist/lib/middleware/multipart.js +17 -0
- package/dist/lib/middleware/rateLimit.d.ts +2 -0
- package/dist/lib/middleware/rateLimit.d.ts.map +1 -0
- package/dist/lib/middleware/rateLimit.js +19 -0
- package/dist/lib/middleware/requestLogger.d.ts +3 -0
- package/dist/lib/middleware/requestLogger.d.ts.map +1 -0
- package/dist/lib/middleware/requestLogger.js +22 -0
- package/dist/lib/middleware/visitor.d.ts +3 -0
- package/dist/lib/middleware/visitor.d.ts.map +1 -0
- package/dist/lib/middleware/visitor.js +144 -0
- package/dist/lib/utils/logger.d.ts +11 -0
- package/dist/lib/utils/logger.d.ts.map +1 -0
- package/dist/lib/utils/logger.js +81 -0
- package/dist/lib/utils/pagination.d.ts +19 -0
- package/dist/lib/utils/pagination.d.ts.map +1 -0
- package/dist/lib/utils/pagination.js +34 -0
- package/dist/lib/utils/response.d.ts +11 -0
- package/dist/lib/utils/response.d.ts.map +1 -0
- package/dist/lib/utils/response.js +57 -0
- package/dist/lib/utils/validator.d.ts +38 -0
- package/dist/lib/utils/validator.d.ts.map +1 -0
- package/dist/lib/utils/validator.js +369 -0
- package/dist/prisma/seed.d.ts +2 -0
- package/dist/prisma/seed.d.ts.map +1 -0
- package/dist/prisma/seed.js +381 -0
- package/dist/src/controllers/authController.d.ts +11 -0
- package/dist/src/controllers/authController.d.ts.map +1 -0
- package/dist/src/controllers/authController.js +414 -0
- package/dist/src/controllers/petController.d.ts +7 -0
- package/dist/src/controllers/petController.d.ts.map +1 -0
- package/dist/src/controllers/petController.js +163 -0
- package/dist/src/controllers/rbacController.d.ts +16 -0
- package/dist/src/controllers/rbacController.d.ts.map +1 -0
- package/dist/src/controllers/rbacController.js +437 -0
- package/dist/src/core/database.d.ts +3 -0
- package/dist/src/core/database.d.ts.map +1 -0
- package/dist/src/core/database.js +34 -0
- package/dist/src/core/realtime.d.ts +3 -0
- package/dist/src/core/realtime.d.ts.map +1 -0
- package/dist/src/core/realtime.js +36 -0
- package/dist/src/core/redis.d.ts +8 -0
- package/dist/src/core/redis.d.ts.map +1 -0
- package/dist/src/core/redis.js +123 -0
- package/dist/src/core/serializer.d.ts +43 -0
- package/dist/src/core/serializer.d.ts.map +1 -0
- package/dist/src/core/serializer.js +66 -0
- package/dist/src/core/server.d.ts +2 -0
- package/dist/src/core/server.d.ts.map +1 -0
- package/dist/src/core/server.js +60 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +98 -0
- package/dist/src/middleware/auth.d.ts +4 -0
- package/dist/src/middleware/auth.d.ts.map +1 -0
- package/dist/src/middleware/auth.js +48 -0
- package/dist/src/middleware/error.d.ts +3 -0
- package/dist/src/middleware/error.d.ts.map +1 -0
- package/dist/src/middleware/error.js +60 -0
- package/dist/src/middleware/multipart.d.ts +4 -0
- package/dist/src/middleware/multipart.d.ts.map +1 -0
- package/dist/src/middleware/multipart.js +17 -0
- package/dist/src/middleware/rateLimit.d.ts +2 -0
- package/dist/src/middleware/rateLimit.d.ts.map +1 -0
- package/dist/src/middleware/rateLimit.js +19 -0
- package/dist/src/middleware/requestLogger.d.ts +3 -0
- package/dist/src/middleware/requestLogger.d.ts.map +1 -0
- package/dist/src/middleware/requestLogger.js +22 -0
- package/dist/src/middleware/visitor.d.ts +3 -0
- package/dist/src/middleware/visitor.d.ts.map +1 -0
- package/dist/src/middleware/visitor.js +144 -0
- package/dist/src/prisma.d.ts +3 -0
- package/dist/src/prisma.d.ts.map +1 -0
- package/dist/src/prisma.js +34 -0
- package/dist/src/realtime.d.ts +3 -0
- package/dist/src/realtime.d.ts.map +1 -0
- package/dist/src/realtime.js +36 -0
- package/dist/src/redis.d.ts +8 -0
- package/dist/src/redis.d.ts.map +1 -0
- package/dist/src/redis.js +122 -0
- package/dist/src/routes/auth.d.ts +2 -0
- package/dist/src/routes/auth.d.ts.map +1 -0
- package/dist/src/routes/auth.js +45 -0
- package/dist/src/routes/index.d.ts +2 -0
- package/dist/src/routes/index.d.ts.map +1 -0
- package/dist/src/routes/index.js +14 -0
- package/dist/src/routes/pets.d.ts +3 -0
- package/dist/src/routes/pets.d.ts.map +1 -0
- package/dist/src/routes/pets.js +45 -0
- package/dist/src/routes/rbac.d.ts +2 -0
- package/dist/src/routes/rbac.d.ts.map +1 -0
- package/dist/src/routes/rbac.js +23 -0
- package/dist/src/schema/auth-schema.d.ts +76 -0
- package/dist/src/schema/auth-schema.d.ts.map +1 -0
- package/dist/src/schema/auth-schema.js +63 -0
- package/dist/src/schema/pet-schema.d.ts +28 -0
- package/dist/src/schema/pet-schema.d.ts.map +1 -0
- package/dist/src/schema/pet-schema.js +14 -0
- package/dist/src/server.d.ts +2 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +31 -0
- package/dist/src/utils/logger.d.ts +11 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +81 -0
- package/dist/src/utils/pagination.d.ts +19 -0
- package/dist/src/utils/pagination.d.ts.map +1 -0
- package/dist/src/utils/pagination.js +34 -0
- package/dist/src/utils/response.d.ts +11 -0
- package/dist/src/utils/response.d.ts.map +1 -0
- package/dist/src/utils/response.js +57 -0
- package/dist/src/utils/validator.d.ts +38 -0
- package/dist/src/utils/validator.d.ts.map +1 -0
- package/dist/src/utils/validator.js +369 -0
- package/lib/bootstrap.ts +6 -0
- package/package.json +26 -14
- package/.env.example +0 -19
- package/doc/ARCHITECTURE_GUIDE.md +0 -73
- package/doc/CHANGELOG.md +0 -77
- package/doc/CHEATSHEET.md +0 -94
- package/doc/CLI.md +0 -139
- package/doc/CONTRIBUTING.md +0 -105
- package/doc/DEPLOYMENT.md +0 -122
- package/doc/FAQ.md +0 -81
- package/doc/FEATURES.md +0 -165
- package/doc/GETTING_STARTED.md +0 -108
- package/doc/INTRODUCTION.md +0 -60
- package/doc/PACKAGES.md +0 -66
- package/doc/PERFORMANCE.md +0 -91
- package/doc/ROADMAP.md +0 -93
- package/doc/SECURITY.md +0 -93
- package/doc/STRUCTURE.md +0 -90
- package/doc/TUTORIAL.md +0 -192
- package/docker-compose.yml +0 -24
- package/eslint.config.mjs +0 -26
- package/framework.md +0 -168
- package/nodemon.json +0 -6
- package/prisma.config.ts +0 -15
- package/src/controllers/authController.ts +0 -469
- package/src/controllers/petController.ts +0 -194
- package/src/controllers/rbacController.ts +0 -478
- package/src/models/core.prisma +0 -163
- package/src/models/pets.prisma +0 -9
- package/src/routes/auth.ts +0 -74
- package/src/routes/index.ts +0 -10
- package/src/routes/pets.ts +0 -13
- package/src/routes/rbac.ts +0 -42
- package/storage/logs/.gitkeep +0 -0
- package/tsconfig.json +0 -30
package/doc/ROADMAP.md
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
# Roadmap & Future Requests (Rencana Pengembangan)
|
|
2
|
-
|
|
3
|
-
Dokumen ini berisi daftar fitur yang direncanakan untuk membuat **Lapeh Framework** setara dengan framework backend enterprise lainnya (seperti NestJS, Laravel, atau Django).
|
|
4
|
-
|
|
5
|
-
Ini adalah **Undangan Terbuka** bagi para kontributor! Jika Anda tertarik mengerjakan salah satu fitur di bawah ini, silakan buat Issue/PR.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 🏗️ Core & Architecture
|
|
10
|
-
|
|
11
|
-
### 1. Dependency Injection (DI) Container
|
|
12
|
-
* **Tujuan**: Membuat kode lebih testable dan modular.
|
|
13
|
-
* **Konsep**: Saat ini Lapeh menggunakan pendekatan import langsung. Implementasi DI sederhana (seperti `InversifyJS` atau custom container) akan memudahkan unit testing dan decoupling.
|
|
14
|
-
* **Inspirasi**: NestJS Providers, Angular DI.
|
|
15
|
-
|
|
16
|
-
### 2. Event Emitter (Pub/Sub)
|
|
17
|
-
* **Tujuan**: Decoupling logic antar modul.
|
|
18
|
-
* **Contoh**: Saat user register -> Emit event `UserRegistered` -> Listener `SendWelcomeEmail` & `CreateWallet` berjalan terpisah.
|
|
19
|
-
* **Status**: Belum ada (bisa pakai `eventemitter3`).
|
|
20
|
-
|
|
21
|
-
### 3. API Documentation Generator (Swagger/OpenAPI)
|
|
22
|
-
* **Tujuan**: Auto-generate dokumentasi API interaktif.
|
|
23
|
-
* **Rencana**: Membaca file route dan validator schema, lalu men-generate spesifikasi Swagger UI secara otomatis di `/api/docs`.
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## 🛠️ Fitur Enterprise (The "Missing" Parts)
|
|
28
|
-
|
|
29
|
-
### 4. Job Queues & Background Workers
|
|
30
|
-
* **Tujuan**: Memproses tugas berat di background agar tidak memblokir HTTP request.
|
|
31
|
-
* **Teknologi**: Integrasi dengan **BullMQ** (Redis).
|
|
32
|
-
* **Fitur**:
|
|
33
|
-
* Decorators/Helpers untuk mendefinisikan Job.
|
|
34
|
-
* Dashboard monitoring job (seperti Horizon di Laravel).
|
|
35
|
-
* Retry mechanism & Failed job handling.
|
|
36
|
-
|
|
37
|
-
### 5. Task Scheduling (Cron Jobs)
|
|
38
|
-
* **Tujuan**: Menjalankan tugas berkala (misal: "Kirim rekap email setiap jam 12 malam").
|
|
39
|
-
* **Rencana**: Wrapper di atas `node-cron` yang terintegrasi dengan struktur framework.
|
|
40
|
-
* **CLI**: `npm run schedule:run`.
|
|
41
|
-
|
|
42
|
-
### 6. Storage Abstraction Layer
|
|
43
|
-
* **Tujuan**: Satu interface untuk upload file ke berbagai provider (Local, AWS S3, Google Cloud Storage, MinIO).
|
|
44
|
-
* **Konsep**:
|
|
45
|
-
```typescript
|
|
46
|
-
// Tidak peduli drivernya apa, kodenya sama:
|
|
47
|
-
await Storage.disk('s3').put('avatars/1.jpg', fileBuffer);
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### 7. Mailer Service
|
|
51
|
-
* **Tujuan**: Standarisasi pengiriman email.
|
|
52
|
-
* **Fitur**:
|
|
53
|
-
* Support SMTP, Mailgun, SES.
|
|
54
|
-
* Support Template Engine (Handlebars/EJS) untuk body email.
|
|
55
|
-
* Queue integration (kirim email di background).
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## 🧪 Testing & Quality Assurance
|
|
60
|
-
|
|
61
|
-
### 8. Native Testing Suite
|
|
62
|
-
* **Tujuan**: Memudahkan user menulis test.
|
|
63
|
-
* **Rencana**:
|
|
64
|
-
* Integrasi **Vitest** atau **Jest** pre-configured.
|
|
65
|
-
* Helper untuk HTTP Testing (supertest wrapper).
|
|
66
|
-
* Helper untuk Database Transaction (rollback setelah test selesai).
|
|
67
|
-
* Command: `npm run test`, `npm run make:test`.
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## 🌐 Globalization & Security
|
|
72
|
-
|
|
73
|
-
### 9. Localization (i18n)
|
|
74
|
-
* **Tujuan**: Mendukung respon API dalam berbagai bahasa.
|
|
75
|
-
* **Fitur**: Mendeteksi header `Accept-Language` dan mengembalikan pesan error/success sesuai bahasa user.
|
|
76
|
-
|
|
77
|
-
### 10. API Versioning
|
|
78
|
-
* **Tujuan**: Mendukung multiple versi API (v1, v2) tanpa merusak klien lama.
|
|
79
|
-
* **Rencana**: Routing strategy berbasis URL prefix (`/api/v1/...`) atau Header.
|
|
80
|
-
|
|
81
|
-
---
|
|
82
|
-
|
|
83
|
-
## 💻 CLI Enhancements
|
|
84
|
-
|
|
85
|
-
### 11. Interactive CLI (TUI)
|
|
86
|
-
* **Tujuan**: Membuat CLI lebih user friendly.
|
|
87
|
-
* **Ide**: Saat menjalankan `npx lapeh`, muncul menu interaktif untuk memilih fitur yang mau diinstall (pilih DB, pilih mau pakai Redis atau tidak, dll).
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
## Tertarik Berkontribusi?
|
|
92
|
-
|
|
93
|
-
Pilih salah satu topik di atas, buat Issue di GitHub dengan judul `[Proposal] Nama Fitur`, dan mari kita diskusikan cara implementasinya! 🚀
|
package/doc/SECURITY.md
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
# Security Best Practices (Panduan Keamanan)
|
|
2
|
-
|
|
3
|
-
Keamanan bukan fitur tambahan, melainkan prioritas utama. Lapeh Framework sudah dikonfigurasi dengan standar keamanan yang baik (Secure by Default), namun Anda tetap perlu memahami cara menjaga aplikasi tetap aman.
|
|
4
|
-
|
|
5
|
-
## 1. Perlindungan Bawaan (Built-in Protection)
|
|
6
|
-
|
|
7
|
-
Secara default, Lapeh sudah mengaktifkan:
|
|
8
|
-
|
|
9
|
-
### Helmet (HTTP Headers)
|
|
10
|
-
|
|
11
|
-
Mengamankan aplikasi dari serangan umum web vulnerabilities dengan mengatur HTTP headers yang tepat.
|
|
12
|
-
|
|
13
|
-
- **XSS Filter**: Aktif.
|
|
14
|
-
- **Frameguard**: Mencegah Clickjacking.
|
|
15
|
-
- **HSTS**: Memaksa browser menggunakan HTTPS (di production).
|
|
16
|
-
|
|
17
|
-
### Rate Limiting
|
|
18
|
-
|
|
19
|
-
Mencegah serangan _Brute Force_ dan _DDoS_ sederhana.
|
|
20
|
-
|
|
21
|
-
- **Default**: 100 request per 15 menit per IP.
|
|
22
|
-
- **Lokasi Config**: `src/middleware/rateLimit.ts`.
|
|
23
|
-
|
|
24
|
-
### CORS (Cross-Origin Resource Sharing)
|
|
25
|
-
|
|
26
|
-
Mengontrol domain mana yang boleh mengakses API Anda.
|
|
27
|
-
|
|
28
|
-
- **Lokasi Config**: `src/core/server.ts`.
|
|
29
|
-
- **Saran**: Di production, ubah `origin: "*"` menjadi domain frontend spesifik Anda (misal `origin: "https://frontend-anda.com"`).
|
|
30
|
-
|
|
31
|
-
## 2. Praktik Terbaik Developer
|
|
32
|
-
|
|
33
|
-
Framework tidak bisa melindungi dari kode yang buruk. Berikut hal yang WAJIB Anda lakukan:
|
|
34
|
-
|
|
35
|
-
### a. Validasi Input (Wajib!)
|
|
36
|
-
|
|
37
|
-
Jangan pernah mempercayai input user. Selalu gunakan `Validator`.
|
|
38
|
-
|
|
39
|
-
**❌ Tidak Aman (Raw Query):**
|
|
40
|
-
|
|
41
|
-
```typescript
|
|
42
|
-
// Bahaya SQL Injection jika pakai raw query manual (walau Prisma aman, tetap hati-hati)
|
|
43
|
-
const user =
|
|
44
|
-
await prisma.$queryRaw`SELECT * FROM users WHERE email = ${req.body.email}`;
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
**✅ Aman (Validator + Prisma Client):**
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
const valid = await Validator.make(req.body, { email: "required|email" });
|
|
51
|
-
// Prisma Client otomatis sanitize input
|
|
52
|
-
const user = await prisma.user.findUnique({
|
|
53
|
-
where: { email: valid.validated().email },
|
|
54
|
-
});
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### b. Manajemen Password
|
|
58
|
-
|
|
59
|
-
- **Hashing**: Jangan pernah simpan password plain text. Gunakan `bcryptjs` (sudah terintegrasi di AuthController).
|
|
60
|
-
- **Strength**: Validasi password minimal 8 karakter.
|
|
61
|
-
```typescript
|
|
62
|
-
password: "required|string|min:8";
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### c. JWT & Session
|
|
66
|
-
|
|
67
|
-
- **Secret Key**: Pastikan `JWT_SECRET` di `.env` adalah string acak yang panjang (32+ karakter).
|
|
68
|
-
- **Expiration**: Token akses (`ACCESS_TOKEN_EXPIRES_IN`) sebaiknya pendek (misal 15 menit - 1 jam). Gunakan Refresh Token (fitur roadmap) untuk sesi panjang.
|
|
69
|
-
|
|
70
|
-
### d. Error Handling
|
|
71
|
-
|
|
72
|
-
Jangan pernah mengekspos detail error sistem (stack trace) ke user di Production.
|
|
73
|
-
|
|
74
|
-
**❌ Buruk:**
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
res.status(500).json({ error: err.message, stack: err.stack }); // Hacker bisa lihat struktur folder server
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
**✅ Aman (Lapeh Default):**
|
|
81
|
-
Lapeh sudah menangani ini. Di mode `production`, error internal hanya akan menampilkan "Internal Server Error" tanpa detail sensitif.
|
|
82
|
-
|
|
83
|
-
## 3. Checklist Sebelum Deploy
|
|
84
|
-
|
|
85
|
-
- [ ] Pastikan `NODE_ENV=production` di server.
|
|
86
|
-
- [ ] Ganti `JWT_SECRET` default dengan yang baru (`npm run generate:jwt`).
|
|
87
|
-
- [ ] Batasi CORS origin hanya ke domain frontend Anda.
|
|
88
|
-
- [ ] Pastikan database tidak bisa diakses publik (gunakan firewall/private IP).
|
|
89
|
-
- [ ] Gunakan HTTPS (SSL/TLS). API tanpa HTTPS sangat mudah disadap.
|
|
90
|
-
|
|
91
|
-
## 4. Melaporkan Celah Keamanan
|
|
92
|
-
|
|
93
|
-
Jika Anda menemukan celah keamanan di framework ini, mohon **JANGAN** buat Issue publik. Kirim email langsung ke maintainer (lihat `package.json`) agar bisa diperbaiki (patched) sebelum diexploitasi orang jahat.
|
package/doc/STRUCTURE.md
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
# Bedah Struktur Proyek
|
|
2
|
-
|
|
3
|
-
Untuk memahami Lapeh Framework sepenuhnya, Anda perlu tahu apa fungsi setiap file dan folder. Berikut adalah "Tour" lengkap ke dalam direktori proyek.
|
|
4
|
-
|
|
5
|
-
## Root Directory
|
|
6
|
-
|
|
7
|
-
| File/Folder | Deskripsi |
|
|
8
|
-
| :------------------- | :---------------------------------------------------------------------------- |
|
|
9
|
-
| `bin/` | Berisi script eksekusi untuk CLI (`npx lapeh`). Anda jarang menyentuh ini. |
|
|
10
|
-
| `doc/` | Dokumentasi proyek ini berada. |
|
|
11
|
-
| `lib/` | **Framework Core**. Bagian internal framework yang jarang Anda sentuh. |
|
|
12
|
-
| `prisma/` | Jantung konfigurasi Database. |
|
|
13
|
-
| `scripts/` | Kumpulan script Node.js untuk utility (generator, compiler schema, dll). |
|
|
14
|
-
| `src/` | **Source Code Utama**. 99% kodingan Anda ada di sini. |
|
|
15
|
-
| `.env` | Variabel rahasia (Database URL, API Keys). **Jangan commit file ini ke Git!** |
|
|
16
|
-
| `docker-compose.yml` | Konfigurasi Docker untuk menjalankan Database & Redis lokal. |
|
|
17
|
-
| `nodemon.json` | Konfigurasi auto-restart saat development. |
|
|
18
|
-
| `package.json` | Daftar library (dependencies) dan perintah (`npm run ...`). |
|
|
19
|
-
| `tsconfig.json` | Konfigurasi TypeScript. |
|
|
20
|
-
|
|
21
|
-
## Folder `src/` (Source Code - User Space)
|
|
22
|
-
|
|
23
|
-
Ini adalah tempat Anda bekerja setiap hari.
|
|
24
|
-
|
|
25
|
-
### `src/controllers/`
|
|
26
|
-
|
|
27
|
-
Berisi logika aplikasi. Controller menerima Request, memprosesnya, dan mengembalikan Response.
|
|
28
|
-
|
|
29
|
-
- **Contoh**: `authController.ts` menangani login/register.
|
|
30
|
-
- **Tips**: Jangan taruh _business logic_ yang terlalu kompleks di sini. Gunakan Service (opsional) jika controller sudah terlalu gemuk.
|
|
31
|
-
|
|
32
|
-
### `src/models/`
|
|
33
|
-
|
|
34
|
-
Berisi definisi tabel database (Schema Prisma).
|
|
35
|
-
|
|
36
|
-
- **Unik di Lapeh**: Kami memecah `schema.prisma` yang besar menjadi file-file kecil per fitur (misal `user.prisma`, `product.prisma`) agar mudah di-manage. Script `prisma:migrate` akan menggabungkannya nanti.
|
|
37
|
-
|
|
38
|
-
### `src/routes/`
|
|
39
|
-
|
|
40
|
-
Mendefinisikan URL endpoint.
|
|
41
|
-
|
|
42
|
-
- Menghubungkan URL (misal `/api/login`) ke fungsi di Controller.
|
|
43
|
-
- Menempelkan Middleware (misal `requireAuth`).
|
|
44
|
-
|
|
45
|
-
## Folder `lib/` (Framework Internals)
|
|
46
|
-
|
|
47
|
-
Bagian ini mirip dengan `node_modules` atau folder `.next` di Next.js. Ini adalah mesin framework.
|
|
48
|
-
|
|
49
|
-
### `lib/core/`
|
|
50
|
-
|
|
51
|
-
Bagian "Mesin" framework.
|
|
52
|
-
|
|
53
|
-
- `server.ts`: Setup Express App.
|
|
54
|
-
- `database.ts`: Instance Prisma Client.
|
|
55
|
-
- `redis.ts`: Koneksi Redis.
|
|
56
|
-
- `serializer.ts`: Logic caching JSON Schema.
|
|
57
|
-
|
|
58
|
-
### `lib/middleware/`
|
|
59
|
-
|
|
60
|
-
Middleware bawaan framework.
|
|
61
|
-
|
|
62
|
-
- `auth.ts`: Cek JWT Token.
|
|
63
|
-
- `rateLimit.ts`: Batasi jumlah request.
|
|
64
|
-
- `requestLogger.ts`: Log setiap request yang masuk.
|
|
65
|
-
|
|
66
|
-
### `lib/utils/`
|
|
67
|
-
|
|
68
|
-
Fungsi bantuan (Helper) bawaan.
|
|
69
|
-
|
|
70
|
-
- `validator.ts`: Validasi input ala Laravel.
|
|
71
|
-
- `response.ts`: Standar format JSON response (`sendFastSuccess`, `sendError`).
|
|
72
|
-
- `logger.ts`: Sistem logging (Winston).
|
|
73
|
-
|
|
74
|
-
## Folder `prisma/`
|
|
75
|
-
|
|
76
|
-
- `migrations/`: History perubahan database (SQL file). Jangan diedit manual.
|
|
77
|
-
- `base.prisma.template`: Header dari schema database (berisi konfigurasi datasource db).
|
|
78
|
-
- `seed.ts`: Script untuk mengisi data awal (Data Seeding).
|
|
79
|
-
|
|
80
|
-
## Folder `scripts/`
|
|
81
|
-
|
|
82
|
-
Script-script "Magic" yang dijalankan `npm run`.
|
|
83
|
-
|
|
84
|
-
- `make-controller.js`: Generator controller.
|
|
85
|
-
- `compile-schema.js`: Penggabung file `.prisma`.
|
|
86
|
-
- `init-project.js`: Wizard setup awal.
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
Dengan memahami struktur ini, Anda tidak akan tersesat saat ingin menambah fitur baru atau mencari bug.
|
package/doc/TUTORIAL.md
DELETED
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
# Tutorial: Membangun API Perpustakaan
|
|
2
|
-
|
|
3
|
-
Dalam tutorial ini, kita akan membangun fitur "Manajemen Buku" sederhana menggunakan semua fitur unggulan Lapeh Framework:
|
|
4
|
-
1. **CLI** untuk generate kode.
|
|
5
|
-
2. **Validator** untuk validasi input.
|
|
6
|
-
3. **Fast Serialization** untuk respon cepat.
|
|
7
|
-
4. **RBAC** untuk proteksi delete (Admin only).
|
|
8
|
-
|
|
9
|
-
## Langkah 1: Generate Model Database
|
|
10
|
-
|
|
11
|
-
Kita butuh tabel `books`. Gunakan CLI `make:model`.
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm run make:model Book
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
File baru akan muncul di `src/models/book.prisma`. Edit file tersebut:
|
|
18
|
-
|
|
19
|
-
```prisma
|
|
20
|
-
// src/models/book.prisma
|
|
21
|
-
|
|
22
|
-
model Book {
|
|
23
|
-
id BigInt @id @default(autoincrement())
|
|
24
|
-
title String
|
|
25
|
-
author String
|
|
26
|
-
isbn String @unique
|
|
27
|
-
publishedAt DateTime
|
|
28
|
-
stock Int @default(0)
|
|
29
|
-
created_at DateTime @default(now())
|
|
30
|
-
updated_at DateTime @updatedAt
|
|
31
|
-
|
|
32
|
-
@@map("books")
|
|
33
|
-
}
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Terapkan perubahan ke database:
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
npm run prisma:migrate
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Langkah 2: Generate Module (Controller & Route)
|
|
43
|
-
|
|
44
|
-
Kita buat controller dan route sekaligus.
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
npm run make:module Book
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Framework akan membuat:
|
|
51
|
-
- `src/controllers/bookController.ts`
|
|
52
|
-
- `src/routes/book.ts`
|
|
53
|
-
|
|
54
|
-
## Langkah 3: Implementasi Controller
|
|
55
|
-
|
|
56
|
-
Buka `src/controllers/bookController.ts` dan kita implementasikan fitur **Create** dan **List** dengan standar framework.
|
|
57
|
-
|
|
58
|
-
### Setup Import & Serializer
|
|
59
|
-
|
|
60
|
-
```typescript
|
|
61
|
-
import { Request, Response } from "express";
|
|
62
|
-
import { prisma } from "@/core/database";
|
|
63
|
-
import { sendFastSuccess, sendError } from "@/utils/response";
|
|
64
|
-
import { Validator } from "@/utils/validator";
|
|
65
|
-
import { getSerializer, createResponseSchema } from "@/core/serializer";
|
|
66
|
-
|
|
67
|
-
// 1. Definisikan Schema Output (untuk Fastify Serialization)
|
|
68
|
-
const bookSchema = {
|
|
69
|
-
type: "object",
|
|
70
|
-
properties: {
|
|
71
|
-
id: { type: "string" }, // BigInt -> String
|
|
72
|
-
title: { type: "string" },
|
|
73
|
-
author: { type: "string" },
|
|
74
|
-
isbn: { type: "string" },
|
|
75
|
-
stock: { type: "number" }
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
// 2. Buat Serializer
|
|
80
|
-
const bookDetailSerializer = getSerializer("book-detail", createResponseSchema(bookSchema));
|
|
81
|
-
const bookListSerializer = getSerializer("book-list", createResponseSchema({
|
|
82
|
-
type: "array",
|
|
83
|
-
items: bookSchema
|
|
84
|
-
}));
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Implementasi Create (dengan Validasi)
|
|
88
|
-
|
|
89
|
-
```typescript
|
|
90
|
-
export async function createBook(req: Request, res: Response) {
|
|
91
|
-
// 1. Validasi Input
|
|
92
|
-
const validator = await Validator.make(req.body, {
|
|
93
|
-
title: "required|string|min:3",
|
|
94
|
-
author: "required|string",
|
|
95
|
-
isbn: "required|string|unique:books,isbn", // Cek unik di tabel books
|
|
96
|
-
stock: "required|number|min:1",
|
|
97
|
-
publishedAt: "required|string" // Format tanggal ISO
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
if (validator.fails()) {
|
|
101
|
-
return sendError(res, 400, "Validation Error", validator.errors());
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const data = validator.validated();
|
|
105
|
-
|
|
106
|
-
// 2. Simpan ke Database
|
|
107
|
-
const book = await prisma.book.create({
|
|
108
|
-
data: {
|
|
109
|
-
title: data.title,
|
|
110
|
-
author: data.author,
|
|
111
|
-
isbn: data.isbn,
|
|
112
|
-
stock: data.stock,
|
|
113
|
-
publishedAt: new Date(data.publishedAt)
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
// 3. Return Response Cepat
|
|
118
|
-
return sendFastSuccess(res, 201, bookDetailSerializer, {
|
|
119
|
-
status: "success",
|
|
120
|
-
message: "Buku berhasil ditambahkan",
|
|
121
|
-
data: { ...book, id: book.id.toString() } // Konversi BigInt manual jika perlu
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### Implementasi List (High Performance)
|
|
127
|
-
|
|
128
|
-
```typescript
|
|
129
|
-
export async function getBooks(req: Request, res: Response) {
|
|
130
|
-
const books = await prisma.book.findMany({
|
|
131
|
-
take: 50, // Limit 50
|
|
132
|
-
orderBy: { created_at: "desc" }
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
// Convert BigInt to string sebelum passing ke serializer (opsional, tapi aman)
|
|
136
|
-
const safeBooks = books.map(b => ({ ...b, id: b.id.toString() }));
|
|
137
|
-
|
|
138
|
-
return sendFastSuccess(res, 200, bookListSerializer, {
|
|
139
|
-
status: "success",
|
|
140
|
-
message: "Daftar buku",
|
|
141
|
-
data: safeBooks
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## Langkah 4: Daftarkan Route & Proteksi
|
|
147
|
-
|
|
148
|
-
Buka `src/routes/book.ts` (atau file yang digenerate). Pastikan route terhubung dan tambahkan middleware auth.
|
|
149
|
-
|
|
150
|
-
```typescript
|
|
151
|
-
import { Router } from "express";
|
|
152
|
-
import { createBook, getBooks } from "../controllers/bookController";
|
|
153
|
-
import { requireAuth, requireAdmin } from "../middleware/auth";
|
|
154
|
-
|
|
155
|
-
export const bookRouter = Router();
|
|
156
|
-
|
|
157
|
-
// Public route (bisa diakses siapa saja)
|
|
158
|
-
bookRouter.get("/", getBooks);
|
|
159
|
-
|
|
160
|
-
// Admin only (Butuh login + role admin)
|
|
161
|
-
bookRouter.post("/", requireAuth, requireAdmin, createBook);
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
Terakhir, daftarkan router ini di `src/routes/index.ts` (jika belum otomatis):
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
import { bookRouter } from "./book";
|
|
168
|
-
// ...
|
|
169
|
-
router.use("/books", bookRouter);
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
## Langkah 5: Testing
|
|
173
|
-
|
|
174
|
-
Jalankan server:
|
|
175
|
-
```bash
|
|
176
|
-
npm run dev
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
Coba hit endpoint:
|
|
180
|
-
1. **POST /api/books** (Tanpa token) -> 401 Unauthorized.
|
|
181
|
-
2. **POST /api/books** (Token User Biasa) -> 403 Forbidden.
|
|
182
|
-
3. **POST /api/books** (Token Admin + Data Invalid) -> 400 Validation Error.
|
|
183
|
-
4. **POST /api/books** (Token Admin + Data Valid) -> 201 Created.
|
|
184
|
-
5. **GET /api/books** -> 200 OK (Super Cepat).
|
|
185
|
-
|
|
186
|
-
## Kesimpulan
|
|
187
|
-
|
|
188
|
-
Dengan Lapeh Framework, Anda telah membuat API yang:
|
|
189
|
-
- **Aman** (Validasi, Auth, RBAC).
|
|
190
|
-
- **Cepat** (Fast Serialization).
|
|
191
|
-
- **Rapi** (Struktur terstandarisasi).
|
|
192
|
-
- **Mudah** (CLI Generator).
|
package/docker-compose.yml
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
version: "3.9"
|
|
2
|
-
services:
|
|
3
|
-
redis:
|
|
4
|
-
image: redis:7-alpine
|
|
5
|
-
command:
|
|
6
|
-
- "redis-server"
|
|
7
|
-
- "--appendonly"
|
|
8
|
-
- "yes"
|
|
9
|
-
- "--user"
|
|
10
|
-
- "default on >12341234 ~* +@all"
|
|
11
|
-
- "--user"
|
|
12
|
-
- "lapeh on >12341234 ~* +@all"
|
|
13
|
-
ports:
|
|
14
|
-
- "6379:6379"
|
|
15
|
-
volumes:
|
|
16
|
-
- redis_data:/data
|
|
17
|
-
healthcheck:
|
|
18
|
-
test: ["CMD", "redis-cli", "ping"]
|
|
19
|
-
interval: 10s
|
|
20
|
-
timeout: 5s
|
|
21
|
-
retries: 5
|
|
22
|
-
|
|
23
|
-
volumes:
|
|
24
|
-
redis_data:
|
package/eslint.config.mjs
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import globals from "globals";
|
|
2
|
-
import pluginJs from "@eslint/js";
|
|
3
|
-
import tseslint from "typescript-eslint";
|
|
4
|
-
|
|
5
|
-
export default [
|
|
6
|
-
{ files: ["**/*.{js,mjs,cjs,ts}"] },
|
|
7
|
-
{ languageOptions: { globals: globals.node } },
|
|
8
|
-
pluginJs.configs.recommended,
|
|
9
|
-
...tseslint.configs.recommended,
|
|
10
|
-
{
|
|
11
|
-
rules: {
|
|
12
|
-
"@typescript-eslint/no-unused-vars": [
|
|
13
|
-
"error",
|
|
14
|
-
{
|
|
15
|
-
"argsIgnorePattern": "^_",
|
|
16
|
-
"varsIgnorePattern": "^_",
|
|
17
|
-
"caughtErrorsIgnorePattern": "^_"
|
|
18
|
-
}
|
|
19
|
-
],
|
|
20
|
-
"@typescript-eslint/no-explicit-any": "warn"
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
ignores: ["dist/", "node_modules/", "generated/", "scripts/"]
|
|
25
|
-
}
|
|
26
|
-
];
|
package/framework.md
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
# Lapeh Framework
|
|
2
|
-
|
|
3
|
-
## Quick Start
|
|
4
|
-
|
|
5
|
-
Untuk memulai project ini (Setup awal):
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm i
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
npm run first
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Perintah di atas akan secara otomatis melakukan:
|
|
16
|
-
|
|
17
|
-
1. Copy `.env.example` ke `.env`
|
|
18
|
-
2. Install dependencies (`npm install`)
|
|
19
|
-
3. Generate JWT Secret baru di `.env`
|
|
20
|
-
4. Setup database (Migrate)
|
|
21
|
-
5. Menjalankan Database Seeder
|
|
22
|
-
|
|
23
|
-
Setelah selesai, Anda bisa langsung menjalankan project:
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
npm run dev
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
### Akun Default
|
|
30
|
-
|
|
31
|
-
Jika seeder dijalankan (via `npm run first` atau `npm run db:seed`), gunakan akun berikut:
|
|
32
|
-
|
|
33
|
-
- **Super Admin**: `sa@sa.com` / `string`
|
|
34
|
-
- **Admin**: `a@a.com` / `string`
|
|
35
|
-
- **User**: `u@u.com` / `string`
|
|
36
|
-
|
|
37
|
-
## Code Standards & Best Practices (Baru)
|
|
38
|
-
|
|
39
|
-
### 1. Import Path Aliases
|
|
40
|
-
Gunakan alias `@/` untuk mengimpor module dari folder `src/`. Hindari relative path yang panjang seperti `../../utils/response`.
|
|
41
|
-
|
|
42
|
-
**Contoh:**
|
|
43
|
-
```typescript
|
|
44
|
-
// ✅ Benar (Recommended)
|
|
45
|
-
import { prisma } from "@/core/database";
|
|
46
|
-
import { sendSuccess } from "@/utils/response";
|
|
47
|
-
|
|
48
|
-
// ❌ Salah (Legacy)
|
|
49
|
-
import { prisma } from "../core/database";
|
|
50
|
-
import { sendSuccess } from "../../utils/response";
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### 2. Strict Linting (Dead Code Elimination)
|
|
54
|
-
Framework ini menerapkan aturan linter yang ketat untuk menjaga kebersihan kode. Variabel, parameter, atau import yang tidak digunakan akan menyebabkan error.
|
|
55
|
-
|
|
56
|
-
- **Variabel tidak terpakai**: Hapus atau beri prefix `_` (underscore).
|
|
57
|
-
```typescript
|
|
58
|
-
// ✅ Benar
|
|
59
|
-
const _unusedVariable = 123;
|
|
60
|
-
function example(_req: Request, res: Response) { ... }
|
|
61
|
-
|
|
62
|
-
// ❌ Error
|
|
63
|
-
const unusedVariable = 123;
|
|
64
|
-
function example(req: Request, res: Response) { ... } // jika req tidak dipakai
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### 3. High Performance Response (Fastify-Style)
|
|
68
|
-
Untuk endpoint dengan throughput tinggi (GET lists, data besar), gunakan `sendFastSuccess` dengan JSON Schema serializer. Ini 2-3x lebih cepat dari `res.json` standar Express.
|
|
69
|
-
|
|
70
|
-
**Langkah-langkah:**
|
|
71
|
-
|
|
72
|
-
1. **Definisikan Schema** (sesuai field Prisma):
|
|
73
|
-
```typescript
|
|
74
|
-
const userSchema = {
|
|
75
|
-
type: "object",
|
|
76
|
-
properties: {
|
|
77
|
-
id: { type: "string" }, // BigInt otomatis dicovert ke string
|
|
78
|
-
name: { type: "string" },
|
|
79
|
-
email: { type: "string" }
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
2. **Buat Serializer**:
|
|
85
|
-
```typescript
|
|
86
|
-
import { getSerializer, createResponseSchema } from "@/core/serializer";
|
|
87
|
-
|
|
88
|
-
const userSerializer = getSerializer("user-detail", createResponseSchema(userSchema));
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
3. **Gunakan di Controller**:
|
|
92
|
-
```typescript
|
|
93
|
-
import { sendFastSuccess } from "@/utils/response";
|
|
94
|
-
|
|
95
|
-
export async function getUser(req, res) {
|
|
96
|
-
const user = await prisma.user.findFirst();
|
|
97
|
-
sendFastSuccess(res, 200, userSerializer, {
|
|
98
|
-
status: "success",
|
|
99
|
-
message: "User found",
|
|
100
|
-
data: user
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## Database Workflow (Prisma)
|
|
106
|
-
|
|
107
|
-
Framework ini menggunakan **Prisma ORM** dengan struktur schema yang modular (dipecah per file). Berikut adalah panduan lengkap dari Development hingga Deployment.
|
|
108
|
-
|
|
109
|
-
### 1. Development (Lokal)
|
|
110
|
-
|
|
111
|
-
Saat mengembangkan aplikasi di local environment:
|
|
112
|
-
|
|
113
|
-
**a. Mengupdate Schema Database**
|
|
114
|
-
Jika Anda mengubah file schema di `src/models/*.prisma` atau konfigurasi di `prisma/base.prisma.template`:
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
npm run prisma:migrate
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
_Perintah ini akan menggabungkan semua file schema, membuat file migrasi baru, menerapkan ke database lokal, dan men-generate ulang Prisma Client._
|
|
121
|
-
|
|
122
|
-
**b. Melihat/Edit Data (GUI)**
|
|
123
|
-
Untuk membuka dashboard visual database:
|
|
124
|
-
|
|
125
|
-
```bash
|
|
126
|
-
npm run db:studio
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
**c. Mengisi Data Awal (Seeding)**
|
|
130
|
-
Jika Anda butuh data dummy atau data awal (seperti roles/permissions):
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
npm run db:seed
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
**d. Reset Database Total**
|
|
137
|
-
Jika database berantakan dan ingin mengulang dari awal (HATI-HATI: Menghapus semua data):
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
npm run db:reset
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
_Perintah ini akan menghapus database, membuat ulang schema dari awal, dan otomatis menjalankan seeder._
|
|
144
|
-
|
|
145
|
-
---
|
|
146
|
-
|
|
147
|
-
### 2. Deployment (Production)
|
|
148
|
-
|
|
149
|
-
Saat deploy ke server production:
|
|
150
|
-
|
|
151
|
-
**a. Setup Awal**
|
|
152
|
-
Pastikan `.env` di production sudah disetup dengan benar (DATABASE_URL, dll).
|
|
153
|
-
|
|
154
|
-
**b. Menerapkan Migrasi**
|
|
155
|
-
Jangan gunakan `migrate dev` di production. Gunakan perintah ini:
|
|
156
|
-
|
|
157
|
-
```bash
|
|
158
|
-
npm run prisma:deploy
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
_Perintah ini hanya akan menerapkan file migrasi yang sudah ada ke database production tanpa mereset data atau meminta konfirmasi interaktif._
|
|
162
|
-
|
|
163
|
-
**c. Generate Client (Opsional)**
|
|
164
|
-
Biasanya dilakukan otomatis saat `npm install` (karena `postinstall`), tapi jika perlu manual:
|
|
165
|
-
|
|
166
|
-
```bash
|
|
167
|
-
npm run prisma:generate
|
|
168
|
-
```
|