lapeeh 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +14 -0
- package/LICENSE +21 -0
- package/bin/index.js +934 -0
- package/doc/en/ARCHITECTURE_GUIDE.md +79 -0
- package/doc/en/CHANGELOG.md +203 -0
- package/doc/en/CHEATSHEET.md +90 -0
- package/doc/en/CLI.md +111 -0
- package/doc/en/CONTRIBUTING.md +119 -0
- package/doc/en/DEPLOYMENT.md +171 -0
- package/doc/en/FAQ.md +69 -0
- package/doc/en/FEATURES.md +99 -0
- package/doc/en/GETTING_STARTED.md +84 -0
- package/doc/en/INTRODUCTION.md +62 -0
- package/doc/en/PACKAGES.md +63 -0
- package/doc/en/PERFORMANCE.md +98 -0
- package/doc/en/ROADMAP.md +104 -0
- package/doc/en/SECURITY.md +95 -0
- package/doc/en/STRUCTURE.md +79 -0
- package/doc/en/TUTORIAL.md +145 -0
- package/doc/id/ARCHITECTURE_GUIDE.md +76 -0
- package/doc/id/CHANGELOG.md +203 -0
- package/doc/id/CHEATSHEET.md +90 -0
- package/doc/id/CLI.md +139 -0
- package/doc/id/CONTRIBUTING.md +119 -0
- package/doc/id/DEPLOYMENT.md +171 -0
- package/doc/id/FAQ.md +69 -0
- package/doc/id/FEATURES.md +169 -0
- package/doc/id/GETTING_STARTED.md +91 -0
- package/doc/id/INTRODUCTION.md +62 -0
- package/doc/id/PACKAGES.md +63 -0
- package/doc/id/PERFORMANCE.md +100 -0
- package/doc/id/ROADMAP.md +107 -0
- package/doc/id/SECURITY.md +94 -0
- package/doc/id/STRUCTURE.md +79 -0
- package/doc/id/TUTORIAL.md +145 -0
- package/docker-compose.yml +24 -0
- package/ecosystem.config.js +17 -0
- package/eslint.config.mjs +26 -0
- package/gitignore.template +30 -0
- package/lib/bootstrap.ts +210 -0
- package/lib/core/realtime.ts +34 -0
- package/lib/core/redis.ts +139 -0
- package/lib/core/serializer.ts +63 -0
- package/lib/core/server.ts +70 -0
- package/lib/core/store.ts +116 -0
- package/lib/middleware/auth.ts +63 -0
- package/lib/middleware/error.ts +50 -0
- package/lib/middleware/multipart.ts +13 -0
- package/lib/middleware/rateLimit.ts +14 -0
- package/lib/middleware/requestLogger.ts +27 -0
- package/lib/middleware/visitor.ts +178 -0
- package/lib/utils/logger.ts +100 -0
- package/lib/utils/pagination.ts +56 -0
- package/lib/utils/response.ts +88 -0
- package/lib/utils/validator.ts +394 -0
- package/nodemon.json +6 -0
- package/package.json +126 -0
- package/readme.md +357 -0
- package/scripts/check-update.js +92 -0
- package/scripts/config-clear.js +45 -0
- package/scripts/generate-jwt-secret.js +38 -0
- package/scripts/init-project.js +84 -0
- package/scripts/make-module.js +89 -0
- package/scripts/release.js +494 -0
- package/scripts/seed-json.js +158 -0
- package/scripts/verify-rbac-functional.js +187 -0
- package/src/config/app.ts +9 -0
- package/src/config/cors.ts +5 -0
- package/src/modules/Auth/auth.controller.ts +519 -0
- package/src/modules/Rbac/rbac.controller.ts +533 -0
- package/src/routes/auth.ts +74 -0
- package/src/routes/index.ts +7 -0
- package/src/routes/rbac.ts +42 -0
- package/storage/logs/.gitkeep +0 -0
- package/tsconfig.build.json +12 -0
- package/tsconfig.json +30 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Deployment Guide
|
|
2
|
+
|
|
3
|
+
This guide will help you deploy your lapeeh application from `localhost` to a Production Server (VPS/Cloud).
|
|
4
|
+
|
|
5
|
+
## Pre-Deployment Preparation
|
|
6
|
+
|
|
7
|
+
Before deploying, ensure:
|
|
8
|
+
|
|
9
|
+
1. **Environment Variables**: Prepare `.env` values for production (Strong JWT Secret, etc.).
|
|
10
|
+
2. **Build**: TypeScript must be compiled to JavaScript.
|
|
11
|
+
|
|
12
|
+
## Strategy 1: VPS (Ubuntu/Debian) with PM2
|
|
13
|
+
|
|
14
|
+
This is the most common and cost-effective way.
|
|
15
|
+
|
|
16
|
+
### 1. Setup Server
|
|
17
|
+
|
|
18
|
+
Ensure Node.js and NPM are installed on the server.
|
|
19
|
+
|
|
20
|
+
### 2. Clone & Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
git clone https://github.com/username/your-repo.git
|
|
24
|
+
cd your-repo
|
|
25
|
+
npm install --production=false # Install devDependencies for build
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 3. Build Application
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm run build
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
This will generate a `dist/` folder.
|
|
35
|
+
|
|
36
|
+
### 4. Setup Production Config
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
cp .env.example .env
|
|
40
|
+
nano .env # Fill with production config
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 5. Run with PM2
|
|
44
|
+
|
|
45
|
+
lapeeh includes an automatic PM2 configuration (`ecosystem.config.js`).
|
|
46
|
+
|
|
47
|
+
1. **Install PM2 Global**:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm install -g pm2
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
2. **Run Application**:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pm2 start ecosystem.config.js
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
This command will:
|
|
60
|
+
|
|
61
|
+
- Run the application in **Cluster** mode (using all available CPU cores).
|
|
62
|
+
- Set `NODE_ENV` to `production`.
|
|
63
|
+
- Enable auto-restart if the app crashes or memory usage exceeds 1GB.
|
|
64
|
+
|
|
65
|
+
3. **Check Status**:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pm2 status
|
|
69
|
+
pm2 logs
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
4. **Save Startup Config (To run on reboot)**:
|
|
73
|
+
```bash
|
|
74
|
+
pm2 save
|
|
75
|
+
pm2 startup
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### ❓ FAQ: Why Does My App Appear Multiple Times in PM2?
|
|
79
|
+
|
|
80
|
+
If you run `pm2 list` and see your app name appear multiple times, **DON'T WORRY**. This is a feature, not a bug.
|
|
81
|
+
|
|
82
|
+
- **Cause**: `instances: "max"` and `exec_mode: "cluster"` configuration in `ecosystem.config.js`.
|
|
83
|
+
- **Function**: PM2 detects the number of CPU cores on your VPS and creates 1 worker process for each core.
|
|
84
|
+
- **Benefit**: Your application becomes **Multi-Threaded**. Requests are distributed evenly across all processes, improving performance.
|
|
85
|
+
|
|
86
|
+
**How to change to Single Instance (Save RAM):**
|
|
87
|
+
If your server RAM is limited (e.g., 512MB/1GB), modify `ecosystem.config.js`:
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
module.exports = {
|
|
91
|
+
apps: [
|
|
92
|
+
{
|
|
93
|
+
name: "my-app",
|
|
94
|
+
// ...
|
|
95
|
+
instances: 1, // Change "max" to 1
|
|
96
|
+
// ...
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
};
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Then run `pm2 reload ecosystem.config.js`.
|
|
103
|
+
|
|
104
|
+
### 7. Advanced: Running Multiple Apps (Multi-App)
|
|
105
|
+
|
|
106
|
+
You can combine multiple Node.js apps in one `ecosystem.config.js`.
|
|
107
|
+
|
|
108
|
+
### 8. Reverse Proxy (Nginx)
|
|
109
|
+
|
|
110
|
+
Do not expose port 8000 directly. Use Nginx in front of it.
|
|
111
|
+
Nginx block config:
|
|
112
|
+
|
|
113
|
+
```nginx
|
|
114
|
+
server {
|
|
115
|
+
server_name api.your-domain.com;
|
|
116
|
+
location / {
|
|
117
|
+
proxy_pass http://localhost:8000;
|
|
118
|
+
proxy_http_version 1.1;
|
|
119
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
120
|
+
proxy_set_header Connection 'upgrade';
|
|
121
|
+
proxy_set_header Host $host;
|
|
122
|
+
proxy_cache_bypass $http_upgrade;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Strategy 2: Docker (Container)
|
|
128
|
+
|
|
129
|
+
lapeeh includes a `Dockerfile`.
|
|
130
|
+
|
|
131
|
+
**Minimal Dockerfile:**
|
|
132
|
+
|
|
133
|
+
```dockerfile
|
|
134
|
+
FROM node:18-alpine
|
|
135
|
+
|
|
136
|
+
WORKDIR /app
|
|
137
|
+
|
|
138
|
+
COPY package*.json ./
|
|
139
|
+
RUN npm install
|
|
140
|
+
|
|
141
|
+
COPY . .
|
|
142
|
+
RUN npm run build
|
|
143
|
+
|
|
144
|
+
EXPOSE 8000
|
|
145
|
+
CMD ["npm", "run", "start:prod"]
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Deploy:**
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
docker build -t my-lapeeh-app .
|
|
152
|
+
docker run -p 8000:8000 --env-file .env my-lapeeh-app
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Strategy 3: PaaS (Railway / Render / Vercel)
|
|
156
|
+
|
|
157
|
+
Platforms like Railway.app are very easy as they detect `package.json`.
|
|
158
|
+
|
|
159
|
+
1. Push code to GitHub.
|
|
160
|
+
2. Connect repo on Railway/Render.
|
|
161
|
+
3. Set Environment Variables in their dashboard.
|
|
162
|
+
4. Set **Build Command**: `npm run build`.
|
|
163
|
+
5. Set **Start Command**: `npm run start:prod`.
|
|
164
|
+
|
|
165
|
+
## Production Security Checklist
|
|
166
|
+
|
|
167
|
+
- [ ] `NODE_ENV=production` must be set.
|
|
168
|
+
- [ ] `JWT_SECRET` must be long and random.
|
|
169
|
+
- [ ] Database credentials (if used) must be secure.
|
|
170
|
+
- [ ] Rate Limiting active (lapeeh default is active).
|
|
171
|
+
- [ ] Use HTTPS (SSL) via Nginx or Cloudflare.
|
package/doc/en/FAQ.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Frequently Asked Questions (FAQ)
|
|
2
|
+
|
|
3
|
+
Kumpulan pertanyaan umum dan solusi untuk masalah yang sering dihadapi.
|
|
4
|
+
|
|
5
|
+
## Database
|
|
6
|
+
|
|
7
|
+
### Q: Database apa yang didukung?
|
|
8
|
+
|
|
9
|
+
**A:**
|
|
10
|
+
lapeeh bersifat **Database Agnostic**. Anda bisa menggunakan PostgreSQL, MySQL, MongoDB, atau database apapun. Framework tidak membatasi pilihan database Anda. Kami menyediakan wrapper `db` generik yang bisa Anda konfigurasi sesuai kebutuhan.
|
|
11
|
+
|
|
12
|
+
## Redis & Caching
|
|
13
|
+
|
|
14
|
+
### Q: Saya tidak ingin pakai Redis di local, ribet installnya.
|
|
15
|
+
|
|
16
|
+
**A:**
|
|
17
|
+
Tenang, lapeeh 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.
|
|
18
|
+
|
|
19
|
+
### Q: Bagaimana cara clear cache Redis?
|
|
20
|
+
|
|
21
|
+
**A:**
|
|
22
|
+
Jika punya akses CLI Redis: `redis-cli FLUSHALL`.
|
|
23
|
+
Atau via kode:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { redis } from "@/core/redis";
|
|
27
|
+
await redis.flushall();
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Fitur & Kustomisasi
|
|
31
|
+
|
|
32
|
+
### Q: Bagaimana cara handle File Upload?
|
|
33
|
+
|
|
34
|
+
**A:**
|
|
35
|
+
Gunakan `multer`. Framework sudah menyiapkannya di `src/routes/auth.ts` sebagai contoh (upload avatar).
|
|
36
|
+
Anda bisa copy logic konfigurasi `multer` tersebut ke route lain.
|
|
37
|
+
|
|
38
|
+
### Q: Bagaimana cara menambah middleware global baru?
|
|
39
|
+
|
|
40
|
+
**A:**
|
|
41
|
+
Buka `src/core/server.ts`. Di sana ada bagian `// Global Middlewares`. Tambahkan middleware Express Anda di situ:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
app.use(myCustomMiddleware);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Q: Saya ingin mengubah port server.
|
|
48
|
+
|
|
49
|
+
**A:**
|
|
50
|
+
Cukup ubah variabel `PORT` di file `.env`. Defaultnya adalah `8000`.
|
|
51
|
+
|
|
52
|
+
## Troubleshooting
|
|
53
|
+
|
|
54
|
+
### Q: Error `EADDRINUSE: address already in use :::8000`
|
|
55
|
+
|
|
56
|
+
**A:**
|
|
57
|
+
Artinya port 8000 sedang dipakai program lain (atau instance lapeeh sebelumnya yang nyangkut).
|
|
58
|
+
**Solusi:**
|
|
59
|
+
|
|
60
|
+
1. Matikan terminal.
|
|
61
|
+
2. Jalankan perintah kill (framework biasanya memberi saran commandnya saat error muncul).
|
|
62
|
+
- Windows: `taskkill /F /IM node.exe` (Hati-hati ini mematikan semua node process).
|
|
63
|
+
- Atau cari PID nya: `netstat -ano | findstr :8000`.
|
|
64
|
+
|
|
65
|
+
### Q: Error `Unique constraint failed` saat seeding
|
|
66
|
+
|
|
67
|
+
**A:**
|
|
68
|
+
Data yang mau dimasukkan sudah ada (misal email `sa@sa.com`).
|
|
69
|
+
Jalankan `npm run db:reset` untuk menghapus semua data dan mulai dari nol.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Features & Core Concepts
|
|
2
|
+
|
|
3
|
+
This document explains the key features of lapeeh Framework and how to use them in depth.
|
|
4
|
+
|
|
5
|
+
## 1. Data Validation (Simple & Powerful)
|
|
6
|
+
|
|
7
|
+
The framework provides a `Validator` utility inspired by expressive modern validation styles, using `zod` behind the scenes but with an API that is more string-based and readable.
|
|
8
|
+
|
|
9
|
+
**Location:** `@lapeeh/utils/validator`
|
|
10
|
+
|
|
11
|
+
### Basic Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { Validator } from "@lapeeh/utils/validator";
|
|
15
|
+
|
|
16
|
+
export async function createProduct(req: Request, res: Response) {
|
|
17
|
+
const validator = await Validator.make(req.body, {
|
|
18
|
+
name: "required|string|min:3",
|
|
19
|
+
price: "required|number|min:1000",
|
|
20
|
+
email: "required|email|unique:user,email", // Check unique in user table email column
|
|
21
|
+
category_id: "required|exists:category,id", // Check exists in category table id column
|
|
22
|
+
photo: "required|image|max:2048", // Validate file upload (Max 2MB)
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if (validator.fails()) {
|
|
26
|
+
return sendError(res, 400, "Validation failed", validator.errors());
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const data = validator.validated();
|
|
30
|
+
// Continue saving process...
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Available Rules
|
|
35
|
+
|
|
36
|
+
- `required`: Must be filled.
|
|
37
|
+
- `string`, `number`, `boolean`: Data type.
|
|
38
|
+
- `email`: Valid email format.
|
|
39
|
+
- `min:X`, `max:X`: String length or number value.
|
|
40
|
+
- `unique:table,column`: Ensure value does not exist in database (Async).
|
|
41
|
+
- `exists:table,column`: Ensure value exists in database (Async).
|
|
42
|
+
- `image`: File must be an image (jpg, png, webp, etc).
|
|
43
|
+
- `mimes:types`: File must be a specific type (e.g., `mimes:pdf,docx`).
|
|
44
|
+
|
|
45
|
+
## 2. High Performance Response (Fastify-Like)
|
|
46
|
+
|
|
47
|
+
For endpoints requiring high performance (e.g., large data lists), use schema-based serialization. This is much faster than standard Express `res.json`.
|
|
48
|
+
|
|
49
|
+
**Location:** `@/utils/response`, `@/core/serializer`
|
|
50
|
+
|
|
51
|
+
### Implementation Steps
|
|
52
|
+
|
|
53
|
+
1. **Define Output Schema**
|
|
54
|
+
Match with the fields you want to show to the user.
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
const productSchema = {
|
|
58
|
+
type: "object",
|
|
59
|
+
properties: {
|
|
60
|
+
id: { type: "string" }, // BigInt automatically becomes string
|
|
61
|
+
name: { type: "string" },
|
|
62
|
+
price: { type: "number" },
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
2. **Create Serializer (Cached)**
|
|
68
|
+
Store outside the handler function so it compiles only once.
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { getSerializer, createResponseSchema } from "@/core/serializer";
|
|
72
|
+
|
|
73
|
+
const productSerializer = getSerializer(
|
|
74
|
+
"product-single",
|
|
75
|
+
createResponseSchema(productSchema)
|
|
76
|
+
);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
3. **Send Response**
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { sendFastSuccess } from "@lapeeh/utils/response";
|
|
83
|
+
|
|
84
|
+
// Inside controller
|
|
85
|
+
sendFastSuccess(res, 200, productSerializer, {
|
|
86
|
+
status: "success",
|
|
87
|
+
message: "Data retrieved",
|
|
88
|
+
data: productData,
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## 3. Authentication & Authorization (RBAC)
|
|
93
|
+
|
|
94
|
+
The authentication system uses JWT (JSON Web Token) and supports Role-Based Access Control.
|
|
95
|
+
|
|
96
|
+
### Auth Middleware
|
|
97
|
+
|
|
98
|
+
- `requireAuth`: Ensures user is logged in (sends header `Authorization: Bearer <token>`).
|
|
99
|
+
- `requireAdmin`: Ensures user is logged in AND has role `admin` or `super_admin`.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Getting Started with lapeeh Framework
|
|
2
|
+
|
|
3
|
+
Welcome to the official documentation for **lapeeh Framework**. This guide will help you get started with installation, configuration, and understanding the basic project structure.
|
|
4
|
+
|
|
5
|
+
## System Requirements
|
|
6
|
+
|
|
7
|
+
Before you begin, ensure your system meets the following requirements:
|
|
8
|
+
|
|
9
|
+
- **Node.js**: Version 18.x or newer.
|
|
10
|
+
- **Package Manager**: NPM (bundled with Node.js).
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
The easiest way to start is by using the `npx` CLI generator.
|
|
15
|
+
|
|
16
|
+
### 1. Create a New Project
|
|
17
|
+
|
|
18
|
+
Run the following command in your terminal:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Standard Interactive Setup
|
|
22
|
+
npx lapeeh@latest init your-project-name
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### 2. Initial Setup
|
|
26
|
+
|
|
27
|
+
Once the project is created, navigate into the project directory and run the setup wizard:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
cd your-project-name
|
|
31
|
+
npm run first
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
This script will automatically perform the following:
|
|
35
|
+
|
|
36
|
+
1. Copy `.env.example` to `.env`.
|
|
37
|
+
2. Install all dependencies (`npm install`).
|
|
38
|
+
3. Generate a secure **JWT Secret**.
|
|
39
|
+
|
|
40
|
+
### 3. Run Development Server
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm run dev
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The server will run at `http://localhost:8000` (or the port specified in `.env`).
|
|
47
|
+
|
|
48
|
+
## Directory Structure
|
|
49
|
+
|
|
50
|
+
Here is the standard folder structure of lapeeh Framework:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
my-app/
|
|
54
|
+
├── bin/ # CLI scripts for npx
|
|
55
|
+
├── doc/ # Project documentation
|
|
56
|
+
├── scripts/ # Utility scripts (Generator, Compiler)
|
|
57
|
+
├── src/ # Main application source code
|
|
58
|
+
│ ├── controllers/ # Business logic (Request handlers)
|
|
59
|
+
│ ├── core/ # Core configuration (Redis, Server)
|
|
60
|
+
│ ├── middleware/ # Express Middleware (Auth, RateLimit)
|
|
61
|
+
│ ├── routes/ # API routing definitions
|
|
62
|
+
│ ├── utils/ # Helper functions (Response, Validator)
|
|
63
|
+
│ └── index.ts # Application entry point
|
|
64
|
+
├── .env # Environment variables (Secrets)
|
|
65
|
+
├── package.json # NPM Dependencies & Scripts
|
|
66
|
+
└── tsconfig.json # TypeScript Configuration
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Environment Configuration (.env)
|
|
70
|
+
|
|
71
|
+
The `.env` file stores important configurations. Here are the key variables:
|
|
72
|
+
|
|
73
|
+
```ini
|
|
74
|
+
# Server
|
|
75
|
+
PORT=8000
|
|
76
|
+
NODE_ENV=development
|
|
77
|
+
|
|
78
|
+
# Security
|
|
79
|
+
JWT_SECRET="super-long-and-random-secret"
|
|
80
|
+
ACCESS_TOKEN_EXPIRES_IN=3600 # 1 hour
|
|
81
|
+
|
|
82
|
+
# Redis (Optional - automatically mocked if absent)
|
|
83
|
+
REDIS_URL="redis://localhost:6379"
|
|
84
|
+
```
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Introduction to lapeeh Framework
|
|
2
|
+
|
|
3
|
+
## What is lapeeh?
|
|
4
|
+
|
|
5
|
+
**lapeeh** is a Backend Framework for Node.js built on top of **Express** and **TypeScript**.
|
|
6
|
+
|
|
7
|
+
If you have ever used other modern frameworks, you will feel very familiar. lapeeh adopts the philosophy of ease-of-use & clean structure, while maintaining the flexibility and speed of Express.
|
|
8
|
+
|
|
9
|
+
The name "lapeeh" comes from the Minang language which means "Loose" or "Free", symbolizing the freedom for developers to build applications quickly without being burdened by complicated configurations.
|
|
10
|
+
|
|
11
|
+
## Why was lapeeh Created?
|
|
12
|
+
|
|
13
|
+
In the Node.js ecosystem, developers often experience "Decision Fatigue":
|
|
14
|
+
|
|
15
|
+
- "Which ORM to use? Prisma, TypeORM, or Drizzle?"
|
|
16
|
+
- "Validation using Joi, Zod, or express-validator?"
|
|
17
|
+
- "How about the folder structure? MVC? Clean Architecture?"
|
|
18
|
+
- "How to handle Auth?"
|
|
19
|
+
|
|
20
|
+
lapeeh answers all of that with **Opinionated Defaults**:
|
|
21
|
+
|
|
22
|
+
1. **ORM**: Prisma (Current industry standard).
|
|
23
|
+
2. **Validation**: Zod (Powerful and readable schema validation).
|
|
24
|
+
3. **Structure**: Modular MVC (Controller, Model, Route separated but cohesive).
|
|
25
|
+
4. **Auth**: Ready-to-use JWT + RBAC (Role Based Access Control).
|
|
26
|
+
|
|
27
|
+
## Comparison with Other Frameworks
|
|
28
|
+
|
|
29
|
+
| Feature | Express (Raw) | NestJS | lapeeh Framework |
|
|
30
|
+
| :----------------- | :---------------------------- | :------------------------------- | :------------------------------------- |
|
|
31
|
+
| **Learning Curve** | Low (but confusing structure) | High (Angular-style, Decorators) | **Medium** (Express + Clear Structure) |
|
|
32
|
+
| **Boilerplate** | Empty | Very Heavy | **Just Right (Ready to use)** |
|
|
33
|
+
| **Type Safety** | Manual | Strict | **Strict (Native TypeScript)** |
|
|
34
|
+
| **Dev Speed** | Slow (manual setup) | Medium | **Fast (CLI Generator)** |
|
|
35
|
+
| **Flexibility** | Very High | Rigid | **High** |
|
|
36
|
+
|
|
37
|
+
## "The lapeeh Way" Philosophy
|
|
38
|
+
|
|
39
|
+
1. **Developer Experience (DX) First**: CLI tools, clear error messages, and hot-reload are priorities.
|
|
40
|
+
2. **Performance by Default**: Fast JSON serialization (Fastify-style) and integrated Redis caching.
|
|
41
|
+
3. **Explicit is Better than Implicit**: No "magic" that is too dark. Your controller code is standard Express code that you understand.
|
|
42
|
+
4. **Production Ready**: Security (Helmet, Rate Limit) and Scalability (Docker, Cluster) are not afterthoughts, but built-in.
|
|
43
|
+
|
|
44
|
+
## Request Lifecycle
|
|
45
|
+
|
|
46
|
+
How does lapeeh handle a single request from a user?
|
|
47
|
+
|
|
48
|
+
1. **Incoming Request** (`GET /api/users`)
|
|
49
|
+
2. **Security Middleware**: Helmet (Headers), CORS, Rate Limiter.
|
|
50
|
+
3. **Global Middleware**: Request Logger, Body Parser (JSON).
|
|
51
|
+
4. **Routing**: Matching URL in `src/routes/`.
|
|
52
|
+
5. **Auth Middleware** (Optional): Check JWT token & Role.
|
|
53
|
+
6. **Validator** (Optional): Validate body/query input.
|
|
54
|
+
7. **Controller**: Main business logic executed.
|
|
55
|
+
- Call Database (via `db` adapter).
|
|
56
|
+
- Call Cache (Redis).
|
|
57
|
+
8. **Serializer**: Data formatted & sanitized (e.g., hide password).
|
|
58
|
+
9. **Response**: JSON sent back to user.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
**Next:** Learn about the folder structure in [Project Structure](structure.md).
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Referensi Package & Dependencies
|
|
2
|
+
|
|
3
|
+
Dokumen ini menjelaskan fungsi dari setiap library (package) yang terinstall di lapeeh 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 Driver
|
|
17
|
+
|
|
18
|
+
| Package | Description | Why we use it? |
|
|
19
|
+
| :------- | :----------------- | :------------------------------------------------- |
|
|
20
|
+
| **`pg`** | PostgreSQL Driver. | Native driver for connecting to Postgres database. |
|
|
21
|
+
|
|
22
|
+
## Authentication & Security
|
|
23
|
+
|
|
24
|
+
| Package | Deskripsi | Kenapa Kita Pakai? |
|
|
25
|
+
| :----------------------- | :---------------- | :---------------------------------------------------- |
|
|
26
|
+
| **`jsonwebtoken`** | Implementasi JWT. | Standar token untuk autentikasi stateless (API). |
|
|
27
|
+
| **`bcryptjs`** | Hashing password. | Mengamankan password user di database (satu arah). |
|
|
28
|
+
| **`express-rate-limit`** | Pembatas request. | Mencegah serangan DDoS ringan atau Brute Force login. |
|
|
29
|
+
|
|
30
|
+
## Utilities & Helper
|
|
31
|
+
|
|
32
|
+
| Package | Deskripsi | Kenapa Kita Pakai? |
|
|
33
|
+
| :------------------------ | :------------------------- | :----------------------------------------------------------------------------- |
|
|
34
|
+
| **`zod`** | Schema validation library. | Memvalidasi input user (req.body) dengan syntax yang kuat dan mudah dibaca. |
|
|
35
|
+
| **`fast-json-stringify`** | Serializer JSON cepat. | Mengubah object ke JSON string 2x-3x lebih cepat dari `JSON.stringify` bawaan. |
|
|
36
|
+
| **`uuid`** | Generator ID unik. | Membuat string acak unik (UUID v4). |
|
|
37
|
+
| **`slugify`** | String formatter. | Mengubah "Judul Artikel Keren" menjadi `judul-artikel-keren` (URL friendly). |
|
|
38
|
+
| **`multer`** | Middleware upload file. | Menangani `multipart/form-data` untuk upload gambar/dokumen. |
|
|
39
|
+
| **`winston`** | Logger library. | Mencatat log aplikasi (error/info) ke file atau console dengan format rapi. |
|
|
40
|
+
|
|
41
|
+
## Realtime & Caching
|
|
42
|
+
|
|
43
|
+
| Package | Deskripsi | Kenapa Kita Pakai? |
|
|
44
|
+
| :----------------- | :------------------------ | :-------------------------------------------------------------------------------------------- |
|
|
45
|
+
| **`socket.io`** | Library WebSocket. | Fitur komunikasi real-time dua arah (chat, notifikasi live). |
|
|
46
|
+
| **`ioredis`** | Client Redis yang robust. | Driver terbaik untuk Redis di Node.js. |
|
|
47
|
+
| **`ioredis-mock`** | Simulasi Redis di memori. | Memungkinkan development tanpa perlu install Redis server asli (sangat berguna untuk pemula). |
|
|
48
|
+
|
|
49
|
+
## Development Tools (DevDependencies)
|
|
50
|
+
|
|
51
|
+
Package ini hanya dipakai saat koding, tidak ikut terinstall di server production.
|
|
52
|
+
|
|
53
|
+
| Package | Deskripsi | Fungsi |
|
|
54
|
+
| :--------------- | :-------------------- | :----------------------------------------------------------------------------- |
|
|
55
|
+
| **`typescript`** | Compiler TS. | Mengubah kode `.ts` menjadi `.js`. |
|
|
56
|
+
| **`nodemon`** | Auto-restarter. | Restart server otomatis setiap kita save file. |
|
|
57
|
+
| **`eslint`** | Linter (Polisi Kode). | Mencari potensi error dan variabel yang tidak terpakai. |
|
|
58
|
+
| **`@types/*`** | Type Definitions. | Provides intellisense (code suggestions) for plain JavaScript libraries. |
|
|
59
|
+
| **`tsc-alias`** | Path resolver. | Resolves `@/core` aliases to relative `../core` paths during production build. |
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
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,98 @@
|
|
|
1
|
+
# Panduan Performa & Skalabilitas lapeeh Framework
|
|
2
|
+
|
|
3
|
+
Dokumen ini menjelaskan cara memaksimalkan performa aplikasi lapeeh 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. lapeeh 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(
|
|
31
|
+
"user-list",
|
|
32
|
+
createResponseSchema({
|
|
33
|
+
type: "array",
|
|
34
|
+
items: userSchema,
|
|
35
|
+
})
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
export async function getUsers(req: Request, res: Response) {
|
|
39
|
+
// Contoh pengambilan data dari database
|
|
40
|
+
const users = await db.users.findMany();
|
|
41
|
+
|
|
42
|
+
// 3. Kirim response super cepat
|
|
43
|
+
return sendFastSuccess(res, 200, userListSerializer, {
|
|
44
|
+
status: "success",
|
|
45
|
+
message: "Data fetched",
|
|
46
|
+
data: users,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 2. Horizontal Scaling (Load Balancer & Cluster)
|
|
54
|
+
|
|
55
|
+
lapeeh dirancang untuk siap di-scale secara horizontal (menambah jumlah server, bukan memperbesar spesifikasi server).
|
|
56
|
+
|
|
57
|
+
### Arsitektur Cluster
|
|
58
|
+
|
|
59
|
+
- **Nginx**: Bertindak sebagai Load Balancer yang membagi trafik ke server-server aplikasi.
|
|
60
|
+
- **Redis**: Menyimpan Session, Rate Limit, dan Cache agar bisa diakses oleh semua server (Shared State).
|
|
61
|
+
- **App Instances**: Beberapa instance aplikasi lapeeh yang berjalan paralel.
|
|
62
|
+
|
|
63
|
+
### Cara Menjalankan Cluster (Docker)
|
|
64
|
+
|
|
65
|
+
Kami telah menyediakan konfigurasi siap pakai di `docker-compose.cluster.yml`.
|
|
66
|
+
|
|
67
|
+
1. **Build & Run Cluster**:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
docker-compose -f docker-compose.cluster.yml up --build
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
2. **Akses Aplikasi**:
|
|
74
|
+
Buka `http://localhost:8080`.
|
|
75
|
+
Nginx akan otomatis membagi request Anda ke `app-1` atau `app-2`.
|
|
76
|
+
|
|
77
|
+
3. **Cek Status**:
|
|
78
|
+
```bash
|
|
79
|
+
docker-compose -f docker-compose.cluster.yml ps
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Konfigurasi Rate Limiter Terdistribusi
|
|
83
|
+
|
|
84
|
+
Middleware `src/middleware/rateLimit.ts` telah diupdate untuk menggunakan Redis Store.
|
|
85
|
+
Ini artinya jika User A terkena limit di Server 1, dia juga akan terblokir di Server 2.
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
// src/middleware/rateLimit.ts
|
|
89
|
+
store: redis ? new RedisStore({ sendCommand: ... }) : undefined
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 3. Tips Optimasi Lainnya
|
|
95
|
+
|
|
96
|
+
- **Gunakan `.lean()` / Select**: Saat query database, selalu pilih field yang dibutuhkan saja.
|
|
97
|
+
- **Compression**: Aktifkan gzip/brotli di Nginx (sudah ada di config default Nginx umumnya).
|
|
98
|
+
- **Keep-Alive**: Gunakan koneksi database yang persistent (sudah dihandle oleh Prisma).
|