This commit is contained in:
189
docs/code-documentation.md
Normal file
189
docs/code-documentation.md
Normal file
@ -0,0 +1,189 @@
|
||||
<!--
|
||||
Project Documentation
|
||||
Scope: WhatsApp Inbox Platform
|
||||
-->
|
||||
|
||||
# WhatsApp Inbox Platform – Dokumentasi Kode
|
||||
|
||||
Dokumen ini menjelaskan arsitektur dan alur utama aplikasi supaya mudah dipahami saat onboarding, debug, atau audit.
|
||||
|
||||
## 1. Gambaran Sistem
|
||||
|
||||
Stack yang dipakai:
|
||||
|
||||
- Frontend + backend: Next.js 15 (App Router).
|
||||
- Database: PostgreSQL + Prisma ORM.
|
||||
- Autentikasi custom: cookie session berbasis payload ter-tanda-tangan.
|
||||
- Job worker: campaign retry worker berbasis script Node.
|
||||
- Proses produksi: PM2 + Nginx sebagai reverse proxy.
|
||||
- Logging dan health check: endpoint internal + script operasi.
|
||||
|
||||
## 2. Struktur Folder Penting
|
||||
|
||||
`app/`
|
||||
Himpunan route Next.js, termasuk endpoint autentikasi dan halaman admin.
|
||||
|
||||
`lib/`
|
||||
Modul inti:
|
||||
|
||||
- auth/session.
|
||||
- prisma client.
|
||||
- util i18n.
|
||||
- request url utility.
|
||||
- audit & rate limit.
|
||||
|
||||
`prisma/`
|
||||
Skema dan migrasi database.
|
||||
|
||||
`scripts/`
|
||||
Operasional dan maintenance:
|
||||
|
||||
- ops scripts.
|
||||
- job scripts.
|
||||
|
||||
`public/`
|
||||
Asset statis.
|
||||
|
||||
## 3. Alur Autentikasi
|
||||
|
||||
### 3.1 Login
|
||||
|
||||
1. POST ke `/auth/login`.
|
||||
2. Validasi rate limit, credential, dan status user.
|
||||
3. Jika valid, session dibuat dan disimpan di cookie `wa_inbox_session`.
|
||||
4. Cookie diset dengan:
|
||||
- `httpOnly`.
|
||||
- `sameSite: "lax"`.
|
||||
- `secure` sesuai env/protocol.
|
||||
- `domain` dari `SESSION_COOKIE_DOMAIN` bila di-set.
|
||||
- `maxAge` dari nilai session TTL.
|
||||
5. Response diarahkan ke route default sesuai role.
|
||||
|
||||
File:
|
||||
- `app/auth/login/route.ts`
|
||||
|
||||
### 3.2 Middleware Guard
|
||||
|
||||
Setiap request (kecuali API) dilewati middleware untuk validasi:
|
||||
|
||||
- Mengecek session cookie.
|
||||
- Redirect ke `/login?next=...` jika tidak ada session.
|
||||
- Mengarahkan user ke default path role jika sudah login dan masuk halaman publik tertentu.
|
||||
- Redirect unauthorized jika role tidak punya akses.
|
||||
- Menangani locale cookie fallback.
|
||||
|
||||
File:
|
||||
- `middleware.ts`
|
||||
|
||||
### 3.3 Parse Session
|
||||
|
||||
Session token dibuat dari payload user lalu ditandatangani dengan HMAC.
|
||||
|
||||
Modul inti:
|
||||
- `lib/auth.ts`
|
||||
|
||||
Berisi:
|
||||
- tipe session.
|
||||
- validasi role.
|
||||
- serialisasi/deserialisasi cookie.
|
||||
- helper konfigurasi session (`getSessionTtlSeconds`, `getSessionCookieDomain`).
|
||||
|
||||
## 4. Konfigurasi Session dan Cookie
|
||||
|
||||
### 4.1 TTL Session
|
||||
|
||||
Nilai diambil dari env:
|
||||
|
||||
- `SESSION_TTL_SECONDS` (prioritas utama).
|
||||
- `SESSION_TTL_HOURS` (fallback legacy).
|
||||
|
||||
Default fallback tetap saat env tidak ada.
|
||||
|
||||
### 4.2 Cookie Hardening
|
||||
|
||||
Untuk environment HTTPS/prod:
|
||||
|
||||
- `COOKIE_SECURE=true`.
|
||||
- `SESSION_COOKIE_DOMAIN=web.zappcare.id` (jika pakai subdomain).
|
||||
- `SESSION_COOKIE_DOMAIN` akan diabaikan untuk localhost/127.0.0.1.
|
||||
|
||||
## 5. Modul dan Script Operasional
|
||||
|
||||
### 5.1 Script Deploy Aman
|
||||
|
||||
`scripts/ops-safe-restart.sh`:
|
||||
|
||||
- cek `.env`.
|
||||
- install dependency (`npm ci`).
|
||||
- build.
|
||||
- deploy migration Prisma (`npm run db:deploy`).
|
||||
- restart/start PM2.
|
||||
- optional healthcheck.
|
||||
- save PM2 state.
|
||||
|
||||
NPM script:
|
||||
- `npm run ops:safe-restart`
|
||||
|
||||
### 5.2 Script Verifikasi Session
|
||||
|
||||
`scripts/ops-session-check.mjs`:
|
||||
|
||||
- login otomatis via akun health check.
|
||||
- verifikasi cookie sesi terbit.
|
||||
- validasi TTL.
|
||||
- cek akses page protected (`/super-admin`) dengan cookie sesi.
|
||||
|
||||
NPM script:
|
||||
- `npm run ops:session-check`
|
||||
|
||||
### 5.3 Dokumentasi Operasional Terkait
|
||||
|
||||
- `ops-runbook.md`
|
||||
- `production-readiness-checklist.md`
|
||||
|
||||
## 6. Catatan Debug Umum
|
||||
|
||||
### Gejala: Kembali ke halaman login setelah klik menu
|
||||
|
||||
Penyebab paling umum:
|
||||
- sesi tidak tersimpan karena cookie `secure/domain` tidak cocok.
|
||||
- domain/protocol HTTPS mismatch.
|
||||
- proses logout tidak sengaja terpicu.
|
||||
- path/role mismatch pada middleware.
|
||||
|
||||
Pengecekan:
|
||||
- lihat response headers:
|
||||
- `X-Auth-Session`
|
||||
- `X-Auth-Session-Has-Cookie`
|
||||
- `X-Auth-Base-Url`
|
||||
- cek cookie di browser devtools (nama `wa_inbox_session`, secure/domain/path/maxAge).
|
||||
- cek log aplikasi (`pm2 logs ...` + `grep AUTH`).
|
||||
|
||||
### Gejala: Loop redirect login (bahasa Inggris / error invalid credential)
|
||||
|
||||
Pastikan:
|
||||
- `AUTH_SECRET` ada di env prod.
|
||||
- `APP_URL` / `OPS_BASE_URL` sesuai domain HTTPS.
|
||||
- `COOKIE_SECURE` sesuai mode.
|
||||
- Nginx tidak strip header `Cookie`.
|
||||
|
||||
## 7. Catatan Implementasi Khusus
|
||||
|
||||
- Logout flow sudah difokuskan ke request non-prefetch agar tidak terpicu by mistake pada prefetch link.
|
||||
- Script yang diubah untuk mencegah kegagalan sesi karena navigasi prefetch.
|
||||
- Penambahan debugging header di middleware/login untuk mempercepat root cause analysis.
|
||||
|
||||
## 8. Dependency Environment Wajib (Ringkas)
|
||||
|
||||
- `DATABASE_URL`
|
||||
- `AUTH_SECRET`
|
||||
- `APP_URL`
|
||||
- `SESSION_TTL_SECONDS`
|
||||
- `COOKIE_SECURE`
|
||||
- `SESSION_COOKIE_DOMAIN` (jika dibutuhkan)
|
||||
- `WHATSAPP_*`, `CAMPAIGN_*`, dan token internal sesuai fitur aktif.
|
||||
|
||||
Lihat juga:
|
||||
- `ops-runbook.md`
|
||||
- `production-readiness-checklist.md`
|
||||
- `.env.example`
|
||||
320
docs/setup-guide.md
Normal file
320
docs/setup-guide.md
Normal file
@ -0,0 +1,320 @@
|
||||
<!--
|
||||
Setup & Deployment Guide
|
||||
Scope: Local and Production
|
||||
-->
|
||||
|
||||
# Guide Setup & Deployment (from zero to production)
|
||||
|
||||
Dokumen ini berisi urutan setup dari awal, termasuk instalasi dependency, konfigurasi environment, deploy, dan pengecekan.
|
||||
|
||||
## A. Prasyarat Dasar
|
||||
|
||||
- Linux server Linux Mint/Ubuntu.
|
||||
- User deploy dengan sudo tanpa password (sudah disiapkan di server Anda).
|
||||
- Akses SSH ke server.
|
||||
- Domain yang mengarah ke server, contoh `web.zappcare.id`.
|
||||
- PostgreSQL sudah ada untuk production.
|
||||
|
||||
## B. Setup Lokal (Developer)
|
||||
|
||||
### B1. Clone dan install
|
||||
|
||||
```bash
|
||||
git clone https://git.iptek.co/wirabasalamah/whatsapp-inbox-platform.git
|
||||
cd whatsapp-inbox-platform
|
||||
npm install
|
||||
```
|
||||
|
||||
### B2. Siapkan `.env`
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Edit `.env` minimal:
|
||||
|
||||
- `DATABASE_URL`
|
||||
- `AUTH_SECRET`
|
||||
- `APP_URL=http://localhost:3002`
|
||||
- `SESSION_TTL_SECONDS=86400`
|
||||
- `COOKIE_SECURE=false` untuk lokal non-HTTPS
|
||||
|
||||
### B3. Jalankan DB lokal
|
||||
|
||||
```bash
|
||||
npx prisma generate
|
||||
npm run db:migrate
|
||||
npm run db:seed
|
||||
```
|
||||
|
||||
### B4. Jalankan aplikasi
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Untuk build check:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## C. Setup Server (Dari Kosong)
|
||||
|
||||
## C1. Install Node.js + Git + Nginx + PostgreSQL + PM2
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y curl git nginx postgresql
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
sudo npm install -g pm2
|
||||
```
|
||||
|
||||
Catatan:
|
||||
|
||||
- Versi Node.js disesuaikan dengan kebutuhan proyek.
|
||||
- Gunakan `pnpm` jika Anda standardize npm/pnpm di server, tapi repo ini diuji dengan npm.
|
||||
|
||||
## C2. Setup user deploy
|
||||
|
||||
Contoh:
|
||||
|
||||
```bash
|
||||
sudo adduser --system --group whatsapp-inbox
|
||||
sudo mkdir -p /var/www/whatsapp-inbox-platform
|
||||
sudo chown -R whatsapp-inbox:whatsapp-inbox /var/www/whatsapp-inbox-platform
|
||||
```
|
||||
|
||||
## C3. Clone repo dan set permission
|
||||
|
||||
```bash
|
||||
sudo -u whatsapp-inbox -H git clone https://git.iptek.co/wirabasalamah/whatsapp-inbox-platform.git /var/www/whatsapp-inbox-platform
|
||||
sudo chown -R whatsapp-inbox:whatsapp-inbox /var/www/whatsapp-inbox-platform
|
||||
sudo chmod -R g+rwX /var/www/whatsapp-inbox-platform
|
||||
```
|
||||
|
||||
## C4. Konfigurasi Database PostgreSQL
|
||||
|
||||
```sql
|
||||
-- psql as postgres
|
||||
CREATE DATABASE whatsapp_inbox;
|
||||
CREATE USER whatsapp_inbox WITH ENCRYPTED PASSWORD 'isi_password_kuat';
|
||||
GRANT ALL PRIVILEGES ON DATABASE whatsapp_inbox TO whatsapp_inbox;
|
||||
```
|
||||
|
||||
Pastikan `DATABASE_URL` mengarah ke:
|
||||
|
||||
`postgresql://whatsapp_inbox:password@127.0.0.1:5432/whatsapp_inbox?schema=public`
|
||||
|
||||
## C5. Set `.env` production
|
||||
|
||||
Buat `.env` di `/var/www/whatsapp-inbox-platform/.env` berdasarkan `.env.example`.
|
||||
|
||||
Wajib isi:
|
||||
|
||||
- `NODE_ENV=production`
|
||||
- `PORT=3002`
|
||||
- `DATABASE_URL=...`
|
||||
- `AUTH_SECRET=...` (random panjang)
|
||||
- `APP_URL=https://web.zappcare.id`
|
||||
- `SESSION_TTL_SECONDS=86400`
|
||||
- `COOKIE_SECURE=true`
|
||||
- `SESSION_COOKIE_DOMAIN=web.zappcare.id`
|
||||
- `CAMPAIGN_RETRY_JOB_TOKEN=...`
|
||||
- `WHATSAPP_WEBHOOK_VERIFY_TOKEN=...`
|
||||
- `WHATSAPP_WEBHOOK_SECRET=...`
|
||||
|
||||
Opsional:
|
||||
|
||||
- `OPS_SESSION_CHECK_EMAIL`, `OPS_SESSION_CHECK_PASSWORD` untuk verifikasi otomatis.
|
||||
|
||||
## C6. Build dan Deploy awal
|
||||
|
||||
```bash
|
||||
cd /var/www/whatsapp-inbox-platform
|
||||
npm ci
|
||||
npm run build
|
||||
npm run db:deploy
|
||||
npm run ops:safe-restart
|
||||
```
|
||||
|
||||
`ops:safe-restart` juga melakukan install+build+migrate jika dipanggil dari state normal.
|
||||
|
||||
## C7. Nginx + SSL
|
||||
|
||||
Konfigurasi Nginx (contoh sederhana):
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name web.zappcare.id;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name web.zappcare.id;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/web.zappcare.id/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/web.zappcare.id/privkey.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3002;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Setup Let’s Encrypt:
|
||||
|
||||
```bash
|
||||
sudo apt install -y certbot python3-certbot-nginx
|
||||
sudo certbot --nginx -d web.zappcare.id
|
||||
```
|
||||
|
||||
Reload nginx:
|
||||
|
||||
```bash
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
## D. Deployment Routine Setelah Update
|
||||
|
||||
### D0. Alur source code ke Git
|
||||
|
||||
Kerjakan perubahan di folder lokal:
|
||||
|
||||
```bash
|
||||
cd /home/wira/work/whatsapp-inbox-platform
|
||||
```
|
||||
|
||||
Pastikan file sensitif seperti `.env` tidak ikut di-commit. Repo ini sudah meng-ignore `.env`.
|
||||
|
||||
Command Git manual dari lokal:
|
||||
|
||||
```bash
|
||||
cd /home/wira/work/whatsapp-inbox-platform
|
||||
git status
|
||||
git add .
|
||||
git commit -m "fix: deskripsi perubahan"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
Jika ingin cek commit terakhir yang sudah siap diambil server:
|
||||
|
||||
```bash
|
||||
cd /home/wira/work/whatsapp-inbox-platform
|
||||
git log --oneline -n 5
|
||||
```
|
||||
|
||||
### D1. Pull dan jalankan restart aman
|
||||
|
||||
```bash
|
||||
cd /var/www/whatsapp-inbox-platform
|
||||
git pull origin main
|
||||
npm run ops:safe-restart
|
||||
```
|
||||
|
||||
Jika app di server dijalankan dengan user deploy `whatsapp-inbox`, gunakan:
|
||||
|
||||
```bash
|
||||
sudo -u whatsapp-inbox -H bash -lc 'cd /var/www/whatsapp-inbox-platform && git pull origin main && npm run ops:safe-restart'
|
||||
```
|
||||
|
||||
Command di atas adalah jalur patch utama untuk update source di server.
|
||||
|
||||
### D1.1. Patch manual di server langkah demi langkah
|
||||
|
||||
Gunakan ini jika ingin melihat proses satu per satu:
|
||||
|
||||
```bash
|
||||
sudo -u whatsapp-inbox -H bash -lc 'cd /var/www/whatsapp-inbox-platform && git status'
|
||||
sudo -u whatsapp-inbox -H bash -lc 'cd /var/www/whatsapp-inbox-platform && git pull origin main'
|
||||
sudo -u whatsapp-inbox -H bash -lc 'cd /var/www/whatsapp-inbox-platform && npm ci'
|
||||
sudo -u whatsapp-inbox -H bash -lc 'cd /var/www/whatsapp-inbox-platform && npm run build'
|
||||
sudo -u whatsapp-inbox -H bash -lc 'cd /var/www/whatsapp-inbox-platform && npm run db:deploy'
|
||||
sudo -u whatsapp-inbox -H bash -lc 'cd /var/www/whatsapp-inbox-platform && npm run ops:safe-restart'
|
||||
```
|
||||
|
||||
Gunakan jalur manual ini jika:
|
||||
|
||||
- ada perubahan dependency baru
|
||||
- ada migration baru
|
||||
- ingin memastikan step build berhasil sebelum restart
|
||||
|
||||
### D1.2. Patch cepat tanpa perubahan dependency
|
||||
|
||||
Kalau hanya ubah source biasa dan `package-lock.json` tidak berubah:
|
||||
|
||||
```bash
|
||||
sudo -u whatsapp-inbox -H bash -lc 'cd /var/www/whatsapp-inbox-platform && git pull origin main && npm run build && npm run ops:safe-restart'
|
||||
```
|
||||
|
||||
### D2. Verifikasi pasca deploy
|
||||
|
||||
```bash
|
||||
cd /var/www/whatsapp-inbox-platform
|
||||
npm run ops:readiness
|
||||
npm run ops:session-check
|
||||
npm run ops:healthcheck
|
||||
```
|
||||
|
||||
### D3. Verifikasi proses berjalan
|
||||
|
||||
```bash
|
||||
pm2 list
|
||||
sudo ss -ltnp | grep 3002
|
||||
```
|
||||
|
||||
## E. Checklist Pasca Login Issue
|
||||
|
||||
Jika masih kena loop ke login:
|
||||
|
||||
- cek cookie `wa_inbox_session` di browser.
|
||||
- cek domain/cookie secure.
|
||||
- cek header:
|
||||
- `X-Auth-Session`
|
||||
- `X-Auth-Session-Has-Cookie`
|
||||
- `X-Auth-Base-Url`
|
||||
- cek logs:
|
||||
|
||||
```bash
|
||||
pm2 logs whatsapp-inbox-platform --lines 200
|
||||
```
|
||||
|
||||
- cek ENV:
|
||||
- `COOKIE_SECURE=true` untuk HTTPS.
|
||||
- `APP_URL` harus `https://web.zappcare.id`.
|
||||
- `SESSION_COOKIE_DOMAIN` kalau lintas subdomain.
|
||||
|
||||
## F. Jalur Emergency/Recovery
|
||||
|
||||
Jika app tidak start:
|
||||
|
||||
- `npm run ops:readiness`
|
||||
- cek DB connect.
|
||||
- jalankan ulang migration jika schema mismatch.
|
||||
- run `npm run ops:safe-restart`.
|
||||
- jika perlu rollback, checkout commit sebelumnya lalu restart ulang.
|
||||
|
||||
```bash
|
||||
git log --oneline -n 10
|
||||
git checkout <commit_id_aman>
|
||||
npm run ops:safe-restart
|
||||
```
|
||||
|
||||
## G. Reference Command Cepat
|
||||
|
||||
- Health app: `npm run ops:healthcheck`
|
||||
- Session check: `npm run ops:session-check`
|
||||
- Ready check: `npm run ops:readiness`
|
||||
- Restart aman: `npm run ops:safe-restart`
|
||||
- View process: `pm2 list`
|
||||
- Tail logs: `pm2 logs`
|
||||
- Folder kerja lokal: `/home/wira/work/whatsapp-inbox-platform`
|
||||
- Folder deploy server: `/var/www/whatsapp-inbox-platform`
|
||||
Reference in New Issue
Block a user