# Deploy Production

Dokumen ini menyiapkan deploy production untuk:

- domain `abelbirdnest.id`
- reverse proxy `nginx`
- aplikasi Next.js di port `3007`
- database `PostgreSQL`
- source code dari git `https://git.iptek.co/wirabasalamah/AbelBirdNest-Stock.git`
- user service khusus `abelbirdnest`

## 1. Persiapan Server

Siapkan:

- Node.js LTS
- npm
- PostgreSQL
- nginx
- certbot / SSL Let’s Encrypt

Direktori contoh:

```bash
/var/www/abelbirdnest-web
```

## 2. Buat User Khusus Aplikasi

Jalankan sebagai `root` atau dengan `sudo`:

```bash
sudo useradd -r -m -d /var/www/abelbirdnest-web -s /bin/bash abelbirdnest
sudo mkdir -p /var/www/abelbirdnest-web
sudo chown -R abelbirdnest:abelbirdnest /var/www/abelbirdnest-web
```

Catatan:

- user `abelbirdnest` dipakai khusus untuk menjalankan service aplikasi
- jangan jalankan app production dengan user pribadi atau `root`

## 3. Clone Repo dari Git

Masuk sebagai user aplikasi:

```bash
sudo -u abelbirdnest -H bash
cd /var/www/abelbirdnest-web
git clone https://git.iptek.co/wirabasalamah/AbelBirdNest-Stock.git .
```

Kalau server butuh autentikasi git internal, siapkan credential sesuai kebijakan server Git Anda.

## 4. Environment Production

Salin `.env.production.example` menjadi `.env.production`, lalu isi nilainya.

Yang wajib:

```env
NODE_ENV=production
PORT=3007
APP_URL=https://abelbirdnest.id
DATABASE_URL=postgresql://...
AUTH_SECRET=...
AUTH_BOOTSTRAP=false
SMTP_HOST=...
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=...
SMTP_PASSWORD=...
SMTP_FROM=...
```

Catatan:

- `AUTH_SECRET` harus random panjang.
- `AUTH_BOOTSTRAP=false` wajib untuk production.
- `APP_URL` harus domain production final.

## 5. Inisialisasi Database PostgreSQL

Contoh di bawah memakai:

- database: `abelbirdnest_prod`
- database user: `abelbirdnest_app`
- host: `127.0.0.1`
- port: `5432`

Masuk ke PostgreSQL sebagai superuser:

```bash
sudo -u postgres psql
```

Buat user database:

```sql
CREATE USER abelbirdnest_app WITH PASSWORD '72ed04ddd2bb520eacae7f4b71a16b0d';
```

Buat database production:

```sql
CREATE DATABASE abelbirdnest_prod OWNER abelbirdnest_app;
```

Pastikan owner database benar:

```sql
ALTER DATABASE abelbirdnest_prod OWNER TO abelbirdnest_app;
```

Opsional tapi disarankan, kunci privilege default:

```sql
REVOKE ALL ON DATABASE abelbirdnest_prod FROM PUBLIC;
GRANT ALL PRIVILEGES ON DATABASE abelbirdnest_prod TO abelbirdnest_app;
```

Keluar dari `psql`:

```sql
\q
```

Tes koneksi:

```bash
psql "postgresql://abelbirdnest_app:72ed04ddd2bb520eacae7f4b71a16b0d@127.0.0.1:5432/abelbirdnest_prod?schema=public"
```

Jika koneksi berhasil, pakai URL itu di `.env.production`:

```env
DATABASE_URL="postgresql://abelbirdnest_app:ganti-dengan-password-yang-kuat@127.0.0.1:5432/abelbirdnest_prod?schema=public"
```

## 6. Install Dependency, Database & Migration

Repo ini sudah disiapkan memakai migration Prisma.

Jalankan:

```bash
cd /var/www/abelbirdnest-web
npm install
npm run prisma:generate
npm run prisma:migrate:deploy
```

Kalau perlu isi master awal:

```bash
npm run seed:master
```

Data seed yang dibawa:

- grade
- bank
- currency

Urutan pertama kali untuk fresh database:

```bash
cd /var/www/abelbirdnest-web
npm install
npm run prisma:generate
npm run prisma:migrate:deploy
npm run seed:master
```

Catatan:

- `prisma:migrate:deploy` akan membuat seluruh tabel dari migration yang ada di repo
- `seed:master` hanya mengisi data awal `grade`, `bank`, dan `currency`
- user login production tetap harus dibuat terpisah, jangan mengandalkan akun dev/default

## 7. User Login Awal Production

Sistem login tidak punya user production bawaan permanen.

Di kode memang ada akun default, tetapi akun itu hanya dibuat jika:

```env
AUTH_BOOTSTRAP=true
```

Jika production langsung memakai:

```env
AUTH_BOOTSTRAP=false
```

maka akun login awal tidak akan ada.

### Opsi yang paling praktis: bootstrap sementara

1. Ubah `.env.production` sementara menjadi:

```env
AUTH_BOOTSTRAP=true
```

2. Build dan jalankan aplikasi:

```bash
cd /var/www/abelbirdnest-web
npm run build
sudo systemctl restart abelbirdnest-web
```

3. Login pertama kali lewat:

- web: `https://abelbirdnest.id/login`
- API: `POST /api/v1/auth/login`

Identity bisa memakai `email` atau `username`.

4. Akun default yang akan tersedia saat bootstrap aktif:

- `admin` / `admin123`
- `owner` / `owner123`
- `purchasing` / `purchasing123`
- `warehouse` / `warehouse123`
- `qc` / `qc123`
- `sales` / `sales123`

Email default:

- `admin@abelbirdnest.local`
- `owner@abelbirdnest.local`
- `purchasing@abelbirdnest.local`
- `warehouse@abelbirdnest.local`
- `qc@abelbirdnest.local`
- `sales@abelbirdnest.local`

5. Setelah berhasil login, segera buat user production final dari menu `Users`.

Minimal disarankan:

- 1 user `SYSTEM_ADMIN` atau `ADMIN`
- 1 user `OWNER`
- user operasional sesuai kebutuhan: `PURCHASING`, `WAREHOUSE`, `QC`, `SALES`

6. Setelah user production final selesai dibuat dan sudah dites login:

- ubah lagi `.env.production` menjadi:

```env
AUTH_BOOTSTRAP=false
```

- restart service:

```bash
sudo systemctl restart abelbirdnest-web
```

7. Opsional tapi sangat disarankan:

- nonaktifkan atau hapus akun default bootstrap dari menu `Users`
- ganti semua password default jika akun tersebut tetap dipertahankan sementara

### Catatan keamanan

- Jangan biarkan `AUTH_BOOTSTRAP=true` aktif terus di production.
- Jangan gunakan password default untuk operasi harian.
- Setelah bootstrap selesai, verifikasi bahwa login masih normal memakai user production yang baru dibuat.

## 8. Build Production

```bash
npm run build
```

## 9. Jalankan App di Port 3007

Manual:

```bash
PORT=3007 npm run start
```

Atau gunakan `systemd` dari:

```bash
deploy/systemd/abelbirdnest-web.service
```

Contoh setup:

```bash
sudo cp deploy/systemd/abelbirdnest-web.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable abelbirdnest-web
sudo systemctl start abelbirdnest-web
sudo systemctl status abelbirdnest-web
```

Autostart saat server restart terjadi karena service di-`enable`.

Untuk verifikasi:

```bash
sudo systemctl is-enabled abelbirdnest-web
```

## 10. Reverse Proxy Nginx

Gunakan file:

```bash
deploy/nginx/abelbirdnest.id.conf
```

Pasang:

```bash
sudo cp deploy/nginx/abelbirdnest.id.conf /etc/nginx/sites-available/abelbirdnest.id.conf
sudo ln -s /etc/nginx/sites-available/abelbirdnest.id.conf /etc/nginx/sites-enabled/abelbirdnest.id.conf
sudo nginx -t
sudo systemctl reload nginx
```

## 11. Health Check

Endpoint health:

```bash
GET /api/v1/health
```

Contoh:

```bash
curl https://abelbirdnest.id/api/v1/health
```

## 12. Update Deployment Berikutnya

Jika aplikasi sudah live dan ada update dari git:

```bash
cd /var/www/abelbirdnest-web
git pull origin main
npm install
npm run prisma:migrate:deploy
npm run build
sudo systemctl restart abelbirdnest-web
```

## 13. Alternatif Deploy: Build di Lokal, Jalankan di Server

Repo ini sekarang mendukung output Next.js `standalone`, sehingga build dilakukan di lingkungan Linux lokal/container lalu artifact di-upload ke server. Server production tidak menjalankan `npm run build`.

### Kapan jalur ini dipakai

Pakai cara ini jika:

- server production terlalu kecil untuk `next build`
- build sering mati karena RAM habis
- Anda ingin memisahkan proses build dan runtime

### Prasyarat

- build harus dilakukan di Linux Alpine, atau container Linux Alpine
- versi Node saat build harus sama dengan server
- server Alpine perlu `nodejs` dan `openssl` terpasang
- untuk server RAM 1 GB, runtime disarankan memakai `NODE_OPTIONS=--max-old-space-size=512`
- database migration tetap dijalankan di server

### Script yang disediakan

Build artifact Linux:

```bash
deploy/scripts/build-linux-release.sh
```

Upload artifact ke server:

```bash
deploy/scripts/upload-linux-release.sh
```

### Contoh build artifact di lokal

Pastikan Docker tersedia di mesin lokal/build machine. Script default memakai image `node:20-alpine` agar artifact cocok dengan server Alpine Linux. `.env.production` production tetap disimpan di server, bukan dibawa di artifact.

```bash
./deploy/scripts/build-linux-release.sh
```

Artifact default yang dihasilkan memakai timestamp:

```bash
abelbirdnest-release-YYYYMMDD-HHMMSS.tar.gz
```

Isi artifact:

- server Next.js standalone
- static assets `.next/static`
- folder `public`
- folder `prisma`
- tidak membawa `.env.production`

### Contoh upload ke server

```bash
./deploy/scripts/upload-linux-release.sh abelbirdnest@server /var/www/abelbirdnest-web/AbelBirdNest-Stock
```

Setelah upload, script akan:

- copy artifact ke server
- extract ke `/var/www/abelbirdnest-web/AbelBirdNest-Stock/releases/<timestamp>`
- update symlink `/var/www/abelbirdnest-web/AbelBirdNest-Stock/current`

### Langkah setelah upload di server

Masuk ke server:

```bash
ssh abelbirdnest@server
cd /var/www/abelbirdnest-web/AbelBirdNest-Stock/current
```

Artifact standalone dibuat untuk runtime. Jangan menjalankan `npm install`, `npm run build`, atau `prisma migrate deploy` di server kecil. Jika rilis membawa migration database, jalankan migration dari mesin build/admin yang punya dependency lengkap dan akses ke database production.

Untuk menjalankan standalone app secara manual:

```bash
PORT=3007 node server.js
```

Jika memakai `systemd`, `WorkingDirectory` service harus diarahkan ke:

```bash
/var/www/abelbirdnest-web/AbelBirdNest-Stock/current
```

dan `ExecStart` menjadi:

```bash
/usr/bin/node server.js
```

Jika branch utama nanti bukan `main`, sesuaikan perintah `git pull`.

## 12. Checklist Go-Live

- `AUTH_BOOTSTRAP=false`
- `AUTH_SECRET` sudah production-grade
- `APP_URL=https://abelbirdnest.id`
- SSL aktif
- database backup aktif
- `npm run build` lulus
- `npm run prisma:migrate:deploy` lulus
- `npm run seed:master` selesai jika dibutuhkan
- login, reset password, dan email verifikasi sudah dites
- create purchase, receipt, lot, sale sudah dites

## 13. Catatan Penting

- Jangan pakai `npm run db:push` untuk production.
- Jangan pakai akun default development.
- Jangan simpan `.env.production` di repo.
- Pastikan ownership file tetap `abelbirdnest:abelbirdnest`.
