Prepare BizOne portal production wallet and UI
This commit is contained in:
424
PRODUCTION_READINESS.md
Normal file
424
PRODUCTION_READINESS.md
Normal file
@ -0,0 +1,424 @@
|
||||
# Production Readiness Checklist
|
||||
|
||||
Dokumen ini merangkum kesiapan aplikasi BizOne Portal sebelum naik production live.
|
||||
|
||||
Status saat ini:
|
||||
|
||||
- Staging-ready: hampir siap
|
||||
- Production-ready: belum
|
||||
- Rekomendasi: jangan deploy production live sebelum semua item `Blocker` selesai
|
||||
|
||||
## Blocker
|
||||
|
||||
Item berikut wajib selesai sebelum production.
|
||||
|
||||
### 1. Rotate semua secret yang pernah tersimpan di repo
|
||||
|
||||
Status: Belum selesai
|
||||
|
||||
Risiko:
|
||||
|
||||
- Secret/password/token di file example atau dokumentasi harus dianggap bocor jika pernah masuk repo.
|
||||
- Credential lama tidak boleh dipakai di production.
|
||||
|
||||
Yang harus dilakukan:
|
||||
|
||||
- Bersihkan credential asli dari `deploy/debian12/app.env.example`.
|
||||
- Bersihkan credential asli dari `.env.example` jika ada.
|
||||
- Bersihkan potongan secret/password dari `README.md` atau dokumentasi lain.
|
||||
- Generate secret baru untuk production.
|
||||
- Pakai secret baru hanya di `.env` server, bukan di repo.
|
||||
|
||||
Secret yang wajib di-rotate:
|
||||
|
||||
- `DATABASE_URL` password database
|
||||
- `JWT_SECRET`
|
||||
- `JWT_REFRESH_SECRET`
|
||||
- `WEBHOOK_VERIFY_TOKEN`
|
||||
- `WEBHOOK_SHARED_SECRET`
|
||||
- `META_WEBHOOK_APP_SECRET`
|
||||
- `MAIL_PASSWORD`
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Tidak ada credential asli di repo.
|
||||
- Production `.env` hanya ada di server.
|
||||
- Semua secret production berbeda dari secret yang pernah ditulis di repo.
|
||||
|
||||
### 2. Jalankan build final backend
|
||||
|
||||
Status: Belum dijalankan final setelah perubahan terbaru
|
||||
|
||||
Command:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
npm run db:generate
|
||||
npm run build
|
||||
```
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Build backend sukses tanpa error TypeScript.
|
||||
- Prisma client berhasil generate.
|
||||
- `dist/main.js` tersedia dan bisa dijalankan.
|
||||
|
||||
### 3. Jalankan build final frontend
|
||||
|
||||
Status: Belum dijalankan final setelah perubahan UI terbaru
|
||||
|
||||
Command:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm run build
|
||||
```
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Build Next.js sukses.
|
||||
- Tidak ada TypeScript error.
|
||||
- Tidak ada runtime import error.
|
||||
- Tidak ada route yang gagal saat build.
|
||||
|
||||
### 4. Jalankan migration deploy di database production/staging
|
||||
|
||||
Status: Belum diverifikasi final
|
||||
|
||||
Command:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
npm run db:migrate:deploy
|
||||
```
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Migration selesai tanpa error.
|
||||
- Tabel utama tersedia.
|
||||
- Backend health check mengembalikan database `ok`.
|
||||
|
||||
### 5. Smoke test end-to-end production flow
|
||||
|
||||
Status: Belum selesai
|
||||
|
||||
Minimal test:
|
||||
|
||||
- Login admin berhasil.
|
||||
- Ganti password admin berhasil.
|
||||
- Aktifkan 2FA berhasil.
|
||||
- Dashboard bisa dibuka.
|
||||
- User management bisa load.
|
||||
- Contacts bisa load, create, import/export minimal dicek.
|
||||
- Conversations bisa load.
|
||||
- WhatsApp API Setting bisa load dan save.
|
||||
- Sensitive value tidak tampil plain text saat `NODE_ENV=production`.
|
||||
- Webhook verification dari Meta berhasil.
|
||||
- Webhook event masuk ke logs.
|
||||
- Pesan inbound WhatsApp masuk ke Conversations.
|
||||
- Balas pesan dari dashboard berhasil jika token Meta valid.
|
||||
- Audit trail mencatat aksi penting.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Semua flow utama di atas lolos tanpa error 500.
|
||||
- Browser console tidak menunjukkan runtime error kritikal.
|
||||
- Backend log tidak menunjukkan exception berulang.
|
||||
|
||||
## High Priority
|
||||
|
||||
Item berikut sangat disarankan selesai sebelum production, tapi bisa dipisah setelah blocker jika deployment sangat mendesak.
|
||||
|
||||
### 1. Production nginx security headers masuk ke config repo
|
||||
|
||||
Status: Belum masuk final config repo
|
||||
|
||||
Tambahkan ke `deploy/debian12/nginx.portal.bizone.id.conf`:
|
||||
|
||||
```nginx
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
||||
```
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- `nginx -t` sukses.
|
||||
- Header muncul di response HTTPS.
|
||||
|
||||
### 2. Frontend Dockerfile production-ready
|
||||
|
||||
Status: Belum siap
|
||||
|
||||
Masalah:
|
||||
|
||||
- `frontend/Dockerfile` masih menjalankan `npm run dev`.
|
||||
|
||||
Opsi:
|
||||
|
||||
- Jika deployment pakai systemd, Dockerfile ini tidak blocker.
|
||||
- Jika deployment pakai Docker, wajib ubah ke production build.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Docker image frontend menjalankan `next start`, bukan `next dev`.
|
||||
|
||||
### 3. Dependency audit
|
||||
|
||||
Status: Belum dijalankan
|
||||
|
||||
Command:
|
||||
|
||||
```bash
|
||||
npm audit
|
||||
cd backend && npm audit
|
||||
cd ../frontend && npm audit
|
||||
```
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Tidak ada critical vulnerability.
|
||||
- High vulnerability punya keputusan: fix, upgrade, atau accepted risk tertulis.
|
||||
|
||||
### 4. Review penggunaan Next 15.0.0 dan React RC
|
||||
|
||||
Status: Perlu review
|
||||
|
||||
Risiko:
|
||||
|
||||
- React RC dan Next awal versi major bisa punya issue kompatibilitas.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Build final sukses.
|
||||
- Smoke test UI sukses.
|
||||
- Tidak ada issue runtime kritikal.
|
||||
- Jika memungkinkan, upgrade ke versi stabil yang kompatibel.
|
||||
|
||||
### 5. Backup PostgreSQL dan Redis
|
||||
|
||||
Status: Belum ada strategi final
|
||||
|
||||
Minimal PostgreSQL backup:
|
||||
|
||||
```bash
|
||||
pg_dump "$DATABASE_URL" > backup-$(date +%F).sql
|
||||
```
|
||||
|
||||
Yang perlu disiapkan:
|
||||
|
||||
- Backup harian.
|
||||
- Retention minimal 7-14 hari.
|
||||
- Lokasi backup di luar server utama jika memungkinkan.
|
||||
- Restore test minimal satu kali.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Backup otomatis berjalan.
|
||||
- Restore procedure terdokumentasi.
|
||||
|
||||
## Medium Priority
|
||||
|
||||
Item berikut tidak selalu blocker, tapi penting untuk operasional production yang sehat.
|
||||
|
||||
### 1. Monitoring uptime
|
||||
|
||||
Status: Belum ada
|
||||
|
||||
Endpoint yang dipantau:
|
||||
|
||||
```text
|
||||
https://portal.bizone.id/api/health
|
||||
```
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Alert aktif saat endpoint non-200.
|
||||
- Alert aktif saat response terlalu lambat.
|
||||
|
||||
### 2. Log retention
|
||||
|
||||
Status: Belum dikunci
|
||||
|
||||
Cek journald:
|
||||
|
||||
```bash
|
||||
sudo journalctl --disk-usage
|
||||
```
|
||||
|
||||
Rekomendasi:
|
||||
|
||||
- Batasi ukuran journald.
|
||||
- Pastikan log backend/frontend bisa dibaca saat incident.
|
||||
|
||||
### 3. Forced first-login password change
|
||||
|
||||
Status: Belum ada secara code
|
||||
|
||||
Risiko:
|
||||
|
||||
- Seed admin default bisa lupa diganti.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Admin bootstrap dipaksa ganti password saat login pertama, atau proses operasional mewajibkan rotate manual sebelum go-live.
|
||||
|
||||
### 4. Role permission enforcement review
|
||||
|
||||
Status: Perlu review final
|
||||
|
||||
Yang perlu dicek:
|
||||
|
||||
- User biasa tidak bisa akses halaman admin.
|
||||
- Role non-admin tidak bisa mengubah settings, users, roles, audit trail.
|
||||
- API backend menolak akses yang tidak sesuai role.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Permission UI dan backend konsisten.
|
||||
|
||||
### 5. Translation sweep
|
||||
|
||||
Status: Sebagian besar halaman utama sudah dirapikan
|
||||
|
||||
Perlu cek lagi:
|
||||
|
||||
- Detail contact
|
||||
- Detail campaign
|
||||
- Detail template/builder edge case
|
||||
- Auth pages forgot/reset/set password
|
||||
- Notification center
|
||||
- Global search modal
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Tidak ada string penting yang hardcoded di halaman utama production.
|
||||
|
||||
## Done / Already Good
|
||||
|
||||
Item berikut sudah terlihat cukup baik dari code saat ini.
|
||||
|
||||
### 1. Env validation backend production
|
||||
|
||||
Status: Sudah ada
|
||||
|
||||
Catatan:
|
||||
|
||||
- Production menolak secret pendek/placeholder.
|
||||
- Production menolak `WEBHOOK_ALLOW_UNSIGNED=true`.
|
||||
- Production mewajibkan URL HTTPS untuk origin/public API.
|
||||
|
||||
### 2. Sensitive WhatsApp values tidak tampil di production
|
||||
|
||||
Status: Sudah ada
|
||||
|
||||
Catatan:
|
||||
|
||||
- Backend hanya mengembalikan sensitive values saat `!isProduction`.
|
||||
- Pastikan `NODE_ENV=production` benar di server.
|
||||
|
||||
### 3. Cookie secure di production
|
||||
|
||||
Status: Sudah ada
|
||||
|
||||
Catatan:
|
||||
|
||||
- Frontend cookie memakai `secure: process.env.NODE_ENV === 'production'`.
|
||||
- `sameSite` memakai `lax`.
|
||||
|
||||
### 4. CORS dibatasi via `FRONTEND_ORIGIN`
|
||||
|
||||
Status: Sudah ada
|
||||
|
||||
Catatan:
|
||||
|
||||
- Backend membaca allowed origin dari env.
|
||||
|
||||
### 5. Prisma migration deploy tersedia
|
||||
|
||||
Status: Sudah ada
|
||||
|
||||
Command:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
npm run db:migrate:deploy
|
||||
```
|
||||
|
||||
### 6. Systemd deployment tersedia
|
||||
|
||||
Status: Sudah ada
|
||||
|
||||
File:
|
||||
|
||||
- `deploy/debian12/bizone-backend.service`
|
||||
- `deploy/debian12/bizone-frontend.service`
|
||||
|
||||
### 7. Nginx reverse proxy config tersedia
|
||||
|
||||
Status: Ada, perlu hardening headers
|
||||
|
||||
File:
|
||||
|
||||
- `deploy/debian12/nginx.portal.bizone.id.conf`
|
||||
|
||||
### 8. PostgreSQL dan Redis infra compose tersedia
|
||||
|
||||
Status: Sudah ada
|
||||
|
||||
File:
|
||||
|
||||
- `deploy/debian12/docker-compose.infra.yml`
|
||||
|
||||
## Go / No-Go Decision
|
||||
|
||||
### Go staging
|
||||
|
||||
Boleh jika:
|
||||
|
||||
- Backend build sukses.
|
||||
- Frontend build sukses.
|
||||
- Migration deploy sukses.
|
||||
- Staging `.env` aman.
|
||||
|
||||
### Go production
|
||||
|
||||
Boleh jika semua ini selesai:
|
||||
|
||||
- Semua blocker selesai.
|
||||
- Secret sudah di-rotate.
|
||||
- Build backend/frontend final sukses.
|
||||
- Migration production sukses.
|
||||
- Smoke test end-to-end sukses.
|
||||
- Nginx HTTPS aktif.
|
||||
- Backup minimal sudah ada.
|
||||
|
||||
### No-go production
|
||||
|
||||
Jangan production jika salah satu ini masih terjadi:
|
||||
|
||||
- Secret asli masih ada di repo.
|
||||
- Build frontend/backend gagal.
|
||||
- Migration gagal.
|
||||
- Login/admin flow gagal.
|
||||
- Webhook production gagal diverifikasi.
|
||||
- Database belum punya backup.
|
||||
- `NODE_ENV` bukan `production`.
|
||||
- `WEBHOOK_ALLOW_UNSIGNED=true`.
|
||||
|
||||
## Suggested production run order
|
||||
|
||||
1. Bersihkan repo dari secret dan rotate semua credential.
|
||||
2. Siapkan `.env` production di server.
|
||||
3. Jalankan infra PostgreSQL/Redis.
|
||||
4. Jalankan `npm install` root, backend, frontend.
|
||||
5. Jalankan `npm run db:generate`.
|
||||
6. Jalankan backend build.
|
||||
7. Jalankan frontend build.
|
||||
8. Jalankan migration deploy.
|
||||
9. Restart systemd services.
|
||||
10. Reload nginx.
|
||||
11. Smoke test health, login, dashboard, webhook, conversation.
|
||||
12. Aktifkan backup dan monitoring.
|
||||
Reference in New Issue
Block a user