lapeh 2.4.6 → 2.4.7
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/doc/en/CLI.md +101 -0
- package/doc/en/FEATURES.md +99 -0
- package/doc/en/GETTING_STARTED.md +101 -0
- package/doc/en/INTRODUCTION.md +60 -0
- package/doc/en/STRUCTURE.md +90 -0
- package/doc/id/ARCHITECTURE_GUIDE.md +73 -0
- package/doc/id/CHANGELOG.md +97 -0
- package/doc/id/CHEATSHEET.md +94 -0
- package/doc/id/CONTRIBUTING.md +105 -0
- package/doc/id/DEPLOYMENT.md +245 -0
- package/doc/id/FAQ.md +81 -0
- package/doc/id/PACKAGES.md +66 -0
- package/doc/id/PERFORMANCE.md +91 -0
- package/doc/id/ROADMAP.md +93 -0
- package/doc/id/SECURITY.md +93 -0
- package/doc/id/TUTORIAL.md +192 -0
- package/package.json +2 -2
- /package/doc/{ARCHITECTURE_GUIDE.md → en/ARCHITECTURE_GUIDE.md} +0 -0
- /package/doc/{CHANGELOG.md → en/CHANGELOG.md} +0 -0
- /package/doc/{CHEATSHEET.md → en/CHEATSHEET.md} +0 -0
- /package/doc/{CONTRIBUTING.md → en/CONTRIBUTING.md} +0 -0
- /package/doc/{DEPLOYMENT.md → en/DEPLOYMENT.md} +0 -0
- /package/doc/{FAQ.md → en/FAQ.md} +0 -0
- /package/doc/{PACKAGES.md → en/PACKAGES.md} +0 -0
- /package/doc/{PERFORMANCE.md → en/PERFORMANCE.md} +0 -0
- /package/doc/{ROADMAP.md → en/ROADMAP.md} +0 -0
- /package/doc/{SECURITY.md → en/SECURITY.md} +0 -0
- /package/doc/{TUTORIAL.md → en/TUTORIAL.md} +0 -0
- /package/doc/{CLI.md → id/CLI.md} +0 -0
- /package/doc/{FEATURES.md → id/FEATURES.md} +0 -0
- /package/doc/{GETTING_STARTED.md → id/GETTING_STARTED.md} +0 -0
- /package/doc/{INTRODUCTION.md → id/INTRODUCTION.md} +0 -0
- /package/doc/{STRUCTURE.md → id/STRUCTURE.md} +0 -0
|
@@ -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
|
+
```
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Panduan Kontribusi (Contributing Guide)
|
|
2
|
+
|
|
3
|
+
Terima kasih atas ketertarikan Anda untuk berkontribusi pada pengembangan **Lapeh Framework**! 🎉
|
|
4
|
+
|
|
5
|
+
Proyek ini bersifat **Open Source** dan kami sangat menghargai setiap bentuk kontribusi, baik itu perbaikan bug, penambahan fitur, dokumentasi, maupun sekadar laporan error (issue).
|
|
6
|
+
|
|
7
|
+
Dokumen ini akan memandu Anda tentang cara berkontribusi dengan benar dan efisien.
|
|
8
|
+
|
|
9
|
+
## 🚀 Memulai Kontribusi
|
|
10
|
+
|
|
11
|
+
### 1. Persiapan Lingkungan (Prerequisites)
|
|
12
|
+
Pastikan Anda sudah menginstal:
|
|
13
|
+
- **Node.js** (v18 ke atas)
|
|
14
|
+
- **Git**
|
|
15
|
+
- **Code Editor** (VS Code disarankan, dengan ekstensi ESLint & Prettier)
|
|
16
|
+
|
|
17
|
+
### 2. Fork & Clone Repository
|
|
18
|
+
1. **Fork** repository ini ke akun GitHub Anda (tombol "Fork" di pojok kanan atas).
|
|
19
|
+
2. **Clone** hasil fork ke komputer lokal Anda:
|
|
20
|
+
```bash
|
|
21
|
+
git clone https://github.com/USERNAME_ANDA/lapeh.git
|
|
22
|
+
cd lapeh
|
|
23
|
+
```
|
|
24
|
+
3. **Tambahkan Remote Upstream** (agar bisa sinkron dengan repo asli):
|
|
25
|
+
```bash
|
|
26
|
+
git remote add upstream https://github.com/robyajo/lapeh.git
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 3. Instalasi Dependencies
|
|
30
|
+
```bash
|
|
31
|
+
npm install
|
|
32
|
+
```
|
|
33
|
+
Jangan lupa jalankan setup awal untuk database lokal (pastikan PostgreSQL/MySQL jalan):
|
|
34
|
+
```bash
|
|
35
|
+
cp .env.example .env
|
|
36
|
+
npm run prisma:migrate
|
|
37
|
+
npm run db:seed
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 🛠️ Workflow Pengembangan
|
|
41
|
+
|
|
42
|
+
### 1. Buat Branch Baru
|
|
43
|
+
Jangan bekerja langsung di branch `main`. Buat branch baru yang deskriptif:
|
|
44
|
+
```bash
|
|
45
|
+
git checkout -b feature/tambah-validasi-email
|
|
46
|
+
# atau
|
|
47
|
+
git checkout -b fix/typo-dokumentasi
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 2. Standar Koding (Coding Standards)
|
|
51
|
+
Kami menerapkan aturan yang ketat demi menjaga kualitas kode.
|
|
52
|
+
- **TypeScript**: Gunakan tipe data eksplisit. Hindari `any` sebisa mungkin.
|
|
53
|
+
- **Linter**: Pastikan tidak ada error ESLint. Variabel tidak terpakai harus dihapus atau diberi prefix `_`.
|
|
54
|
+
- **Formatter**: Kode harus rapi.
|
|
55
|
+
|
|
56
|
+
Sebelum commit, **WAJIB** jalankan perintah ini untuk memastikan kode Anda bersih:
|
|
57
|
+
```bash
|
|
58
|
+
npm run typecheck # Cek error TypeScript
|
|
59
|
+
npm run lint # Cek error Linter
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 3. Commit Message Convention
|
|
63
|
+
Gunakan format **Conventional Commits** agar history mudah dibaca:
|
|
64
|
+
- `feat: ...` untuk fitur baru.
|
|
65
|
+
- `fix: ...` untuk perbaikan bug.
|
|
66
|
+
- `docs: ...` untuk perubahan dokumentasi.
|
|
67
|
+
- `chore: ...` untuk perubahan kecil (config, script).
|
|
68
|
+
- `refactor: ...` untuk perbaikan struktur kode tanpa mengubah fitur.
|
|
69
|
+
|
|
70
|
+
**Contoh:**
|
|
71
|
+
```text
|
|
72
|
+
feat: add email validation rule to validator
|
|
73
|
+
fix: resolve EADDRINUSE error on windows
|
|
74
|
+
docs: update installation guide
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 📮 Mengirim Pull Request (PR)
|
|
78
|
+
|
|
79
|
+
1. **Push** branch Anda ke GitHub:
|
|
80
|
+
```bash
|
|
81
|
+
git push origin feature/nama-fitur
|
|
82
|
+
```
|
|
83
|
+
2. Buka repository fork Anda di GitHub, lalu klik **Compare & pull request**.
|
|
84
|
+
3. Isi judul dan deskripsi PR dengan jelas:
|
|
85
|
+
- Jelaskan apa yang Anda ubah.
|
|
86
|
+
- Sertakan screenshot (jika ada perubahan visual/output).
|
|
87
|
+
- Referensikan Issue jika ada (contoh: `Closes #123`).
|
|
88
|
+
4. Tunggu review dari maintainer. Kami mungkin akan meminta revisi kecil.
|
|
89
|
+
5. Setelah disetujui, kode Anda akan di-merge! 🚀
|
|
90
|
+
|
|
91
|
+
## 🐛 Melaporkan Bug (Issues)
|
|
92
|
+
|
|
93
|
+
Jika Anda menemukan bug tapi belum bisa memperbaikinya, silakan buat **Issue** baru.
|
|
94
|
+
- Gunakan judul yang jelas.
|
|
95
|
+
- Jelaskan langkah-langkah untuk mereproduksi bug (Steps to Reproduce).
|
|
96
|
+
- Sertakan log error atau screenshot.
|
|
97
|
+
- Sebutkan versi Node.js dan OS yang digunakan.
|
|
98
|
+
|
|
99
|
+
## 💡 Ide & Diskusi
|
|
100
|
+
|
|
101
|
+
Punya ide fitur baru? Jangan ragu untuk membukanya di **GitHub Discussions** atau buat Issue dengan label `enhancement` sebelum mulai koding, agar kita bisa mendiskusikan desainnya terlebih dahulu.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
Selamat berkontribusi! Kode Anda akan membantu developer lain membangun aplikasi dengan lebih cepat dan menyenangkan. ❤️
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# Deployment Guide
|
|
2
|
+
|
|
3
|
+
Panduan ini akan membantu Anda membawa aplikasi Lapeh dari `localhost` ke Server Production (VPS/Cloud).
|
|
4
|
+
|
|
5
|
+
## Persiapan Pra-Deploy
|
|
6
|
+
|
|
7
|
+
Sebelum deploy, pastikan:
|
|
8
|
+
|
|
9
|
+
1. **Environment Variables**: Siapkan nilai `.env` untuk production (DB URL asli, JWT Secret yang kuat).
|
|
10
|
+
2. **Build**: TypeScript harus dikompilasi ke JavaScript.
|
|
11
|
+
|
|
12
|
+
## Strategi 1: VPS (Ubuntu/Debian) dengan PM2
|
|
13
|
+
|
|
14
|
+
Ini adalah cara paling umum dan hemat biaya.
|
|
15
|
+
|
|
16
|
+
### 1. Setup Server
|
|
17
|
+
|
|
18
|
+
Pastikan Node.js, NPM, dan Database (PostgreSQL/MySQL) sudah terinstall di server.
|
|
19
|
+
|
|
20
|
+
### 2. Clone & Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
git clone https://github.com/username/repo-anda.git
|
|
24
|
+
cd repo-anda
|
|
25
|
+
npm install --production=false # Install devDependencies juga untuk build
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 3. Build Aplikasi
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm run build
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Ini akan menghasilkan folder `dist/`.
|
|
35
|
+
|
|
36
|
+
### 4. Setup Database Production
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Setup .env dulu
|
|
40
|
+
cp .env.example .env
|
|
41
|
+
nano .env # Isi dengan config production
|
|
42
|
+
|
|
43
|
+
# Jalankan migrasi (Hanya deploy schema, jangan reset!)
|
|
44
|
+
npm run prisma:deploy
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 5. Jalankan dengan PM2
|
|
48
|
+
|
|
49
|
+
Lapeh kini menyertakan konfigurasi otomatis PM2 (`ecosystem.config.js`).
|
|
50
|
+
|
|
51
|
+
1. **Install PM2 Global**:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install -g pm2
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
2. **Jalankan Aplikasi**:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pm2 start ecosystem.config.js
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Perintah ini akan:
|
|
64
|
+
|
|
65
|
+
- Menjalankan aplikasi dalam mode **Cluster** (menggunakan semua core CPU yang tersedia).
|
|
66
|
+
- Mengatur `NODE_ENV` ke `production`.
|
|
67
|
+
- Mengaktifkan auto-restart jika aplikasi crash atau penggunaan memori melebihi 1GB.
|
|
68
|
+
|
|
69
|
+
3. **Cek Status**:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pm2 status
|
|
73
|
+
pm2 logs
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
4. **Simpan Config Startup (Agar jalan saat server reboot)**:
|
|
77
|
+
```bash
|
|
78
|
+
pm2 save
|
|
79
|
+
pm2 startup
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### ❓ FAQ: Mengapa Aplikasi Saya Muncul Ganda di PM2?
|
|
83
|
+
|
|
84
|
+
Jika Anda menjalankan `pm2 list` dan melihat nama aplikasi Anda muncul lebih dari satu kali (misal: `my-app` ada 2 atau 4 baris), **JANGAN KHAWATIR**. Ini adalah fitur, bukan bug.
|
|
85
|
+
|
|
86
|
+
- **Penyebab**: Konfigurasi `instances: "max"` dan `exec_mode: "cluster"` di `ecosystem.config.js`.
|
|
87
|
+
- **Fungsi**: PM2 mendeteksi jumlah inti CPU (Core) di VPS Anda dan membuat 1 proses worker untuk setiap core.
|
|
88
|
+
- Jika VPS punya 2 vCPU -> Muncul 2 proses.
|
|
89
|
+
- Jika VPS punya 4 vCPU -> Muncul 4 proses.
|
|
90
|
+
- **Keuntungan**: Aplikasi Anda menjadi **Multi-Threaded**. Request yang masuk akan dibagi rata ke semua proses, meningkatkan performa 2x-4x lipat dibanding mode biasa.
|
|
91
|
+
|
|
92
|
+
**Cara mengubah ke Single Instance (Hemat RAM):**
|
|
93
|
+
Jika RAM server Anda terbatas (misal 512MB/1GB) dan ingin menghemat resource, ubah `ecosystem.config.js`:
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
module.exports = {
|
|
97
|
+
apps: [
|
|
98
|
+
{
|
|
99
|
+
name: "my-app",
|
|
100
|
+
// ...
|
|
101
|
+
instances: 1, // Ubah "max" menjadi 1
|
|
102
|
+
// ...
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
};
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Lalu jalankan `pm2 reload ecosystem.config.js`.
|
|
109
|
+
|
|
110
|
+
### 7. Advanced: Menjalankan Beberapa Aplikasi (Multi-App)
|
|
111
|
+
|
|
112
|
+
Jika Anda memiliki beberapa aplikasi Node.js dalam satu VPS (misalnya: Backend API, Frontend React SSR, dan API Lapeh), Anda bisa menggabungkannya dalam satu file `ecosystem.config.js`.
|
|
113
|
+
|
|
114
|
+
Berikut adalah contoh konfigurasi **Real World** untuk menjalankan 3 aplikasi sekaligus:
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
module.exports = {
|
|
118
|
+
apps: [
|
|
119
|
+
// 1. APLIKASI LAIN (Contoh: Backend MERN)
|
|
120
|
+
{
|
|
121
|
+
name: "api-mern-news",
|
|
122
|
+
cwd: "/var/www/html/node/api-mern-news",
|
|
123
|
+
script: "dist/src/index.js",
|
|
124
|
+
env: {
|
|
125
|
+
NODE_ENV: "production",
|
|
126
|
+
PORT: 4000,
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
// 2. APLIKASI LAIN (Contoh: Frontend React/Next.js)
|
|
131
|
+
{
|
|
132
|
+
name: "web-mern-news",
|
|
133
|
+
cwd: "/var/www/html/node/web-mern-news",
|
|
134
|
+
script: "npm",
|
|
135
|
+
args: "start", // Menjalankan 'npm start'
|
|
136
|
+
env: {
|
|
137
|
+
NODE_ENV: "production",
|
|
138
|
+
PORT: 3001,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
// 3. APLIKASI LAPEH FRAMEWORK
|
|
143
|
+
{
|
|
144
|
+
name: "api-lapeh-project",
|
|
145
|
+
cwd: "/var/www/html/node/my-lapeh-project",
|
|
146
|
+
|
|
147
|
+
// PENTING: Gunakan binary Lapeh dari node_modules lokal
|
|
148
|
+
script: "./node_modules/lapeh/bin/index.js",
|
|
149
|
+
|
|
150
|
+
// Argument 'start' untuk mode produksi
|
|
151
|
+
args: "start",
|
|
152
|
+
|
|
153
|
+
// Mode Cluster (Gunakan semua Core CPU)
|
|
154
|
+
instances: "max",
|
|
155
|
+
exec_mode: "cluster",
|
|
156
|
+
|
|
157
|
+
// Restart jika memori bocor > 1GB
|
|
158
|
+
max_memory_restart: "1G",
|
|
159
|
+
|
|
160
|
+
// Matikan watch di production
|
|
161
|
+
watch: false,
|
|
162
|
+
|
|
163
|
+
env: {
|
|
164
|
+
NODE_ENV: "production",
|
|
165
|
+
PORT: 8001,
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
};
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Tips:**
|
|
173
|
+
|
|
174
|
+
1. Sesuaikan `cwd` (Current Working Directory) dengan lokasi folder proyek Anda di VPS.
|
|
175
|
+
2. Pastikan port tidak bentrok antar aplikasi (contoh di atas: 4000, 3001, 8001).
|
|
176
|
+
3. Simpan file ini di root folder proyek utama atau di folder khusus konfigurasi server Anda.
|
|
177
|
+
4. Jalankan semua aplikasi sekaligus dengan: `pm2 start ecosystem.config.js`.
|
|
178
|
+
|
|
179
|
+
### 8. Reverse Proxy (Nginx)
|
|
180
|
+
|
|
181
|
+
Jangan expose port 4000 langsung. Gunakan Nginx di depannya.
|
|
182
|
+
Config Nginx block:
|
|
183
|
+
|
|
184
|
+
```nginx
|
|
185
|
+
server {
|
|
186
|
+
server_name api.domain-anda.com;
|
|
187
|
+
location / {
|
|
188
|
+
proxy_pass http://localhost:4000;
|
|
189
|
+
proxy_http_version 1.1;
|
|
190
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
191
|
+
proxy_set_header Connection 'upgrade';
|
|
192
|
+
proxy_set_header Host $host;
|
|
193
|
+
proxy_cache_bypass $http_upgrade;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Strategi 2: Docker (Container)
|
|
199
|
+
|
|
200
|
+
Lapeh sudah menyertakan `Dockerfile` (jika belum, buat sederhana saja).
|
|
201
|
+
|
|
202
|
+
**Dockerfile Minimal:**
|
|
203
|
+
|
|
204
|
+
```dockerfile
|
|
205
|
+
FROM node:18-alpine
|
|
206
|
+
|
|
207
|
+
WORKDIR /app
|
|
208
|
+
|
|
209
|
+
COPY package*.json ./
|
|
210
|
+
RUN npm install
|
|
211
|
+
|
|
212
|
+
COPY . .
|
|
213
|
+
RUN npm run build
|
|
214
|
+
|
|
215
|
+
EXPOSE 4000
|
|
216
|
+
CMD ["npm", "run", "start:prod"]
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Deploy:**
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
docker build -t my-lapeh-app .
|
|
223
|
+
docker run -p 4000:4000 --env-file .env my-lapeh-app
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Strategi 3: PaaS (Railway / Render / Vercel)
|
|
227
|
+
|
|
228
|
+
Platform seperti Railway.app sangat mudah karena mendeteksi `package.json`.
|
|
229
|
+
|
|
230
|
+
1. Push kode ke GitHub.
|
|
231
|
+
2. Connect repo di Railway/Render.
|
|
232
|
+
3. Set Environment Variables di dashboard mereka.
|
|
233
|
+
4. Set **Build Command**: `npm run build`.
|
|
234
|
+
5. Set **Start Command**: `npm run start:prod`.
|
|
235
|
+
|
|
236
|
+
**Catatan Khusus Vercel (Serverless):**
|
|
237
|
+
Lapeh didesain sebagai _Long-Running Server_ (Express). Deploy ke Vercel dimungkinkan tapi butuh wrapper serverless (seperti `vercel-express`). Untuk performa terbaik, disarankan menggunakan VPS atau Container (Railway/Fly.io).
|
|
238
|
+
|
|
239
|
+
## Checklist Keamanan Production
|
|
240
|
+
|
|
241
|
+
- [ ] `NODE_ENV=production` harus diset.
|
|
242
|
+
- [ ] `JWT_SECRET` harus panjang dan acak.
|
|
243
|
+
- [ ] Database tidak boleh terekspos ke publik (gunakan private network atau firewall).
|
|
244
|
+
- [ ] Rate Limiting aktif (default Lapeh sudah aktif).
|
|
245
|
+
- [ ] Gunakan HTTPS (SSL) via Nginx atau Cloudflare.
|
package/doc/id/FAQ.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Frequently Asked Questions (FAQ)
|
|
2
|
+
|
|
3
|
+
Kumpulan pertanyaan umum dan solusi untuk masalah yang sering dihadapi.
|
|
4
|
+
|
|
5
|
+
## Database
|
|
6
|
+
|
|
7
|
+
### Q: Bagaimana cara mengganti database dari PostgreSQL ke MySQL?
|
|
8
|
+
**A:**
|
|
9
|
+
1. Buka `prisma/base.prisma.template`.
|
|
10
|
+
2. Ubah `provider = "postgresql"` menjadi `provider = "mysql"`.
|
|
11
|
+
3. Di `.env`, ubah `DATABASE_URL` formatnya menjadi format MySQL (`mysql://user:pass@host:3306/db`).
|
|
12
|
+
4. Hapus folder `prisma/migrations` (jika baru mulai) atau siapkan strategi migrasi.
|
|
13
|
+
5. Jalankan `npm run prisma:migrate`.
|
|
14
|
+
|
|
15
|
+
### Q: Bagaimana cara membuat relasi antar tabel?
|
|
16
|
+
**A:**
|
|
17
|
+
Definisikan relasi di file `.prisma` masing-masing. Karena file akan digabung, Anda bisa mereferensikan model yang ada di file lain.
|
|
18
|
+
**File `user.prisma`:**
|
|
19
|
+
```prisma
|
|
20
|
+
model User {
|
|
21
|
+
id Int @id
|
|
22
|
+
posts Post[] // Relasi ke Post
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
**File `post.prisma`:**
|
|
26
|
+
```prisma
|
|
27
|
+
model Post {
|
|
28
|
+
id Int @id
|
|
29
|
+
authorId Int
|
|
30
|
+
author User @relation(fields: [authorId], references: [id]) // Relasi ke User
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Redis & Caching
|
|
35
|
+
|
|
36
|
+
### Q: Saya tidak ingin pakai Redis di local, ribet installnya.
|
|
37
|
+
**A:**
|
|
38
|
+
Tenang, Lapeh otomatis mendeteksi jika Redis tidak berjalan dan akan menggunakan **In-Memory Mock** (simulasi Redis di RAM). Aplikasi tetap jalan normal tanpa error. Anda tidak perlu config apa-apa.
|
|
39
|
+
|
|
40
|
+
### Q: Bagaimana cara clear cache Redis?
|
|
41
|
+
**A:**
|
|
42
|
+
Jika punya akses CLI Redis: `redis-cli FLUSHALL`.
|
|
43
|
+
Atau via kode:
|
|
44
|
+
```typescript
|
|
45
|
+
import { redis } from "@/core/redis";
|
|
46
|
+
await redis.flushall();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Fitur & Kustomisasi
|
|
50
|
+
|
|
51
|
+
### Q: Bagaimana cara handle File Upload?
|
|
52
|
+
**A:**
|
|
53
|
+
Gunakan `multer`. Framework sudah menyiapkannya di `src/routes/auth.ts` sebagai contoh (upload avatar).
|
|
54
|
+
Anda bisa copy logic konfigurasi `multer` tersebut ke route lain.
|
|
55
|
+
|
|
56
|
+
### Q: Bagaimana cara menambah middleware global baru?
|
|
57
|
+
**A:**
|
|
58
|
+
Buka `src/core/server.ts`. Di sana ada bagian `// Global Middlewares`. Tambahkan middleware Express Anda di situ:
|
|
59
|
+
```typescript
|
|
60
|
+
app.use(myCustomMiddleware);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Q: Saya ingin mengubah port server.
|
|
64
|
+
**A:**
|
|
65
|
+
Cukup ubah variabel `PORT` di file `.env`. Defaultnya adalah `4000`.
|
|
66
|
+
|
|
67
|
+
## Troubleshooting
|
|
68
|
+
|
|
69
|
+
### Q: Error `EADDRINUSE: address already in use :::4000`
|
|
70
|
+
**A:**
|
|
71
|
+
Artinya port 4000 sedang dipakai program lain (atau instance Lapeh sebelumnya yang nyangkut).
|
|
72
|
+
**Solusi:**
|
|
73
|
+
1. Matikan terminal.
|
|
74
|
+
2. Jalankan perintah kill (framework biasanya memberi saran commandnya saat error muncul).
|
|
75
|
+
- Windows: `taskkill /F /IM node.exe` (Hati-hati ini mematikan semua node process).
|
|
76
|
+
- Atau cari PID nya: `netstat -ano | findstr :4000`.
|
|
77
|
+
|
|
78
|
+
### Q: Error `Unique constraint failed` saat seeding
|
|
79
|
+
**A:**
|
|
80
|
+
Data yang mau dimasukkan sudah ada (misal email `sa@sa.com`).
|
|
81
|
+
Jalankan `npm run db:reset` untuk menghapus semua data dan mulai dari nol.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Referensi Package & Dependencies
|
|
2
|
+
|
|
3
|
+
Dokumen ini menjelaskan fungsi dari setiap library (package) yang terinstall di Lapeh Framework, sehingga Anda mengerti kegunaan "alat-alat" yang ada di dalam kotak peralatan Anda.
|
|
4
|
+
|
|
5
|
+
## Core Framework (Fondasi)
|
|
6
|
+
|
|
7
|
+
Package-package ini adalah nyawa dari framework ini.
|
|
8
|
+
|
|
9
|
+
| Package | Deskripsi | Kenapa Kita Pakai? |
|
|
10
|
+
| :--- | :--- | :--- |
|
|
11
|
+
| **`express`** | Web Framework untuk Node.js. | Standar industri, ringan, dan komunitasnya terbesar. |
|
|
12
|
+
| **`dotenv`** | Memuat variabel dari file `.env`. | Agar konfigurasi rahasia (DB password, API Key) tidak di-hardcode. |
|
|
13
|
+
| **`cors`** | Cross-Origin Resource Sharing. | Mengizinkan frontend (React/Vue) dari domain berbeda untuk mengakses API kita. |
|
|
14
|
+
| **`helmet`** | Middleware keamanan HTTP headers. | Melindungi aplikasi dari serangan umum (XSS, Clickjacking) dengan mengatur header HTTP secara otomatis. |
|
|
15
|
+
|
|
16
|
+
## Database & ORM
|
|
17
|
+
|
|
18
|
+
| Package | Deskripsi | Kenapa Kita Pakai? |
|
|
19
|
+
| :--- | :--- | :--- |
|
|
20
|
+
| **`@prisma/client`** | Query builder & ORM. | Type-safe query database. Autocomplete-nya sangat membantu developer. |
|
|
21
|
+
| **`pg`** | Driver PostgreSQL. | Driver native untuk koneksi ke database Postgres. |
|
|
22
|
+
| **`@prisma/adapter-*`** | Adapter serverless. | (Opsional) Persiapan untuk deployment ke environment serverless (seperti Vercel/Neon). |
|
|
23
|
+
|
|
24
|
+
## Authentication & Security
|
|
25
|
+
|
|
26
|
+
| Package | Deskripsi | Kenapa Kita Pakai? |
|
|
27
|
+
| :--- | :--- | :--- |
|
|
28
|
+
| **`jsonwebtoken`** | Implementasi JWT. | Standar token untuk autentikasi stateless (API). |
|
|
29
|
+
| **`bcryptjs`** | Hashing password. | Mengamankan password user di database (satu arah). |
|
|
30
|
+
| **`express-rate-limit`** | Pembatas request. | Mencegah serangan DDoS ringan atau Brute Force login. |
|
|
31
|
+
|
|
32
|
+
## Utilities & Helper
|
|
33
|
+
|
|
34
|
+
| Package | Deskripsi | Kenapa Kita Pakai? |
|
|
35
|
+
| :--- | :--- | :--- |
|
|
36
|
+
| **`zod`** | Schema validation library. | Memvalidasi input user (req.body) dengan syntax yang kuat dan mudah dibaca. |
|
|
37
|
+
| **`fast-json-stringify`** | Serializer JSON cepat. | Mengubah object ke JSON string 2x-3x lebih cepat dari `JSON.stringify` bawaan. |
|
|
38
|
+
| **`uuid`** | Generator ID unik. | Membuat string acak unik (UUID v4). |
|
|
39
|
+
| **`slugify`** | String formatter. | Mengubah "Judul Artikel Keren" menjadi `judul-artikel-keren` (URL friendly). |
|
|
40
|
+
| **`multer`** | Middleware upload file. | Menangani `multipart/form-data` untuk upload gambar/dokumen. |
|
|
41
|
+
| **`winston`** | Logger library. | Mencatat log aplikasi (error/info) ke file atau console dengan format rapi. |
|
|
42
|
+
|
|
43
|
+
## Realtime & Caching
|
|
44
|
+
|
|
45
|
+
| Package | Deskripsi | Kenapa Kita Pakai? |
|
|
46
|
+
| :--- | :--- | :--- |
|
|
47
|
+
| **`socket.io`** | Library WebSocket. | Fitur komunikasi real-time dua arah (chat, notifikasi live). |
|
|
48
|
+
| **`ioredis`** | Client Redis yang robust. | Driver terbaik untuk Redis di Node.js. |
|
|
49
|
+
| **`ioredis-mock`** | Simulasi Redis di memori. | Memungkinkan development tanpa perlu install Redis server asli (sangat berguna untuk pemula). |
|
|
50
|
+
|
|
51
|
+
## Development Tools (DevDependencies)
|
|
52
|
+
|
|
53
|
+
Package ini hanya dipakai saat koding, tidak ikut terinstall di server production.
|
|
54
|
+
|
|
55
|
+
| Package | Deskripsi | Fungsi |
|
|
56
|
+
| :--- | :--- | :--- |
|
|
57
|
+
| **`typescript`** | Compiler TS. | Mengubah kode `.ts` menjadi `.js`. |
|
|
58
|
+
| **`nodemon`** | Auto-restarter. | Restart server otomatis setiap kita save file. |
|
|
59
|
+
| **`eslint`** | Linter (Polisi Kode). | Mencari potensi error dan variabel yang tidak terpakai. |
|
|
60
|
+
| **`@types/*`** | Definisi Tipe. | Memberikan intellisense (saran kode) untuk library JavaScript biasa. |
|
|
61
|
+
| **`prisma`** | Prisma CLI. | Alat untuk migrasi database (`prisma migrate`) dan generate client. |
|
|
62
|
+
| **`tsc-alias`** | Path resolver. | Mengubah alias `@/core` menjadi path relatif `../core` saat build production. |
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
Dengan memahami daftar ini, Anda tahu persis apa yang terjadi di balik layar aplikasi Anda. Tidak ada "Bloatware", setiap package punya tujuan spesifik.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Panduan Performa & Skalabilitas Lapeh Framework
|
|
2
|
+
|
|
3
|
+
Dokumen ini menjelaskan cara memaksimalkan performa aplikasi Lapeh Anda menggunakan fitur-fitur canggih seperti Fast-Serialization dan Clustering.
|
|
4
|
+
|
|
5
|
+
## 1. High Performance Serialization (Fastify-Style)
|
|
6
|
+
|
|
7
|
+
Express secara default menggunakan `JSON.stringify()` yang lambat karena harus memeriksa tipe data setiap field secara runtime. Lapeh mengadopsi teknik **Schema Based Serialization** (seperti Fastify) yang bisa meningkatkan throughput JSON hingga **2x-3x lipat**.
|
|
8
|
+
|
|
9
|
+
### Cara Penggunaan
|
|
10
|
+
|
|
11
|
+
Gunakan `sendFastSuccess` di controller Anda untuk endpoint yang membutuhkan performa tinggi (misalnya: list data yang besar).
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { Request, Response } from "express";
|
|
15
|
+
import { getSerializer, createResponseSchema } from "../core/serializer";
|
|
16
|
+
import { sendFastSuccess } from "../utils/response";
|
|
17
|
+
|
|
18
|
+
// 1. Definisikan Schema Output (JSON Schema Standard)
|
|
19
|
+
const userSchema = {
|
|
20
|
+
type: "object",
|
|
21
|
+
properties: {
|
|
22
|
+
id: { type: "integer" },
|
|
23
|
+
name: { type: "string" },
|
|
24
|
+
email: { type: "string" },
|
|
25
|
+
// Password tidak dimasukkan, jadi otomatis tidak akan terkirim (aman!)
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// 2. Compile Serializer (Otomatis dicache oleh framework)
|
|
30
|
+
const userListSerializer = getSerializer("user-list", createResponseSchema({
|
|
31
|
+
type: "array",
|
|
32
|
+
items: userSchema
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
export async function getUsers(req: Request, res: Response) {
|
|
36
|
+
const users = await prisma.users.findMany();
|
|
37
|
+
|
|
38
|
+
// 3. Kirim response super cepat
|
|
39
|
+
return sendFastSuccess(res, 200, userListSerializer, {
|
|
40
|
+
status: "success",
|
|
41
|
+
message: "Data fetched",
|
|
42
|
+
data: users
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 2. Horizontal Scaling (Load Balancer & Cluster)
|
|
50
|
+
|
|
51
|
+
Lapeh dirancang untuk siap di-scale secara horizontal (menambah jumlah server, bukan memperbesar spesifikasi server).
|
|
52
|
+
|
|
53
|
+
### Arsitektur Cluster
|
|
54
|
+
- **Nginx**: Bertindak sebagai Load Balancer yang membagi trafik ke server-server aplikasi.
|
|
55
|
+
- **Redis**: Menyimpan Session, Rate Limit, dan Cache agar bisa diakses oleh semua server (Shared State).
|
|
56
|
+
- **App Instances**: Beberapa instance aplikasi Lapeh yang berjalan paralel.
|
|
57
|
+
|
|
58
|
+
### Cara Menjalankan Cluster (Docker)
|
|
59
|
+
|
|
60
|
+
Kami telah menyediakan konfigurasi siap pakai di `docker-compose.cluster.yml`.
|
|
61
|
+
|
|
62
|
+
1. **Build & Run Cluster**:
|
|
63
|
+
```bash
|
|
64
|
+
docker-compose -f docker-compose.cluster.yml up --build
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
2. **Akses Aplikasi**:
|
|
68
|
+
Buka `http://localhost:8080`.
|
|
69
|
+
Nginx akan otomatis membagi request Anda ke `app-1` atau `app-2`.
|
|
70
|
+
|
|
71
|
+
3. **Cek Status**:
|
|
72
|
+
```bash
|
|
73
|
+
docker-compose -f docker-compose.cluster.yml ps
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Konfigurasi Rate Limiter Terdistribusi
|
|
77
|
+
Middleware `src/middleware/rateLimit.ts` telah diupdate untuk menggunakan Redis Store.
|
|
78
|
+
Ini artinya jika User A terkena limit di Server 1, dia juga akan terblokir di Server 2.
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
// src/middleware/rateLimit.ts
|
|
82
|
+
store: redis ? new RedisStore({ sendCommand: ... }) : undefined
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 3. Tips Optimasi Lainnya
|
|
88
|
+
|
|
89
|
+
- **Gunakan `.lean()` / Select**: Saat query database, selalu pilih field yang dibutuhkan saja.
|
|
90
|
+
- **Compression**: Aktifkan gzip/brotli di Nginx (sudah ada di config default Nginx umumnya).
|
|
91
|
+
- **Keep-Alive**: Gunakan koneksi database yang persistent (sudah dihandle oleh Prisma).
|