# AIR SDA - Panduan Deployment

Panduan ini menjelaskan cara menyiapkan database PostgreSQL+PostGIS dan menjalankan backend Node.js di server Linux Ubuntu 22.04 LTS untuk produksi.

## Persiapan Server

Spesifikasi minimum yang direkomendasikan untuk skala >100 pengguna concurrent: 4 vCPU, 8 GB RAM, 100 GB SSD untuk database, dan 50 GB tambahan untuk storage foto/file. Jika menggunakan replikasi atau load balancer, siapkan 2 node aplikasi dan 1 node database master + 1 replica.

Update sistem dan pasang dependensi dasar. Instal PostgreSQL 14 atau yang lebih baru beserta ekstensi PostGIS 3. Instal Node.js LTS via NodeSource repository. Instal Nginx sebagai reverse proxy dan SSL termination.

## Inisialisasi Database

Buat database dan user khusus aplikasi dengan hak akses terbatas. Aktifkan ekstensi PostGIS pada database sebelum menjalankan schema. File 01_schema.sql berisi semua DDL dan harus dijalankan terlebih dahulu sebagai user superuser atau owner database. Setelah itu jalankan 02_seed.sql untuk memuat master data dan contoh.

Perintah cepat menggunakan psql: `psql -U airsda_admin -d airsda -f database/01_schema.sql` lalu `psql -U airsda_admin -d airsda -f database/02_seed.sql`. Atau dari direktori backend: `npm run migrate -- --seed`.

Pastikan tuning postgresql.conf disesuaikan: shared_buffers sekitar 25 persen dari RAM, effective_cache_size sekitar 75 persen, max_connections 200, dan work_mem 32MB. Untuk PostGIS, aktifkan random_page_cost = 1.1 (asumsi SSD).

## Konfigurasi Backend

Copy file .env.example menjadi .env dan isi dengan kredensial database, JWT_SECRET acak minimal 64 karakter, URL frontend untuk CORS, dan konfigurasi storage. Jangan pernah commit file .env ke repository.

Install dependencies dengan `npm install` di direktori backend. Untuk produksi, gunakan process manager seperti PM2 untuk auto-restart dan cluster mode. Buat ecosystem.config.js untuk PM2 dengan instances cluster sesuai jumlah core CPU.

Jalankan migration awal `npm run migrate -- --seed`. Lalu start aplikasi dengan `pm2 start src/server.js --name airsda-api -i max`.

## Reverse Proxy dengan Nginx

Konfigurasi Nginx mendengarkan port 443 dengan SSL Let's Encrypt, kemudian proxy_pass ke port 3000 backend. Aktifkan compression (gzip), set client_max_body_size 25M untuk upload foto, dan tambahkan header keamanan (X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security).

Untuk static file (uploads), serve langsung dari Nginx dengan path /uploads/ mengarah ke folder uploads di server, bypass Node.js untuk performa optimal.

## SSL dan Domain

Gunakan certbot untuk generate SSL Let's Encrypt gratis. Setup cron auto-renewal. Untuk lingkungan internal tanpa domain publik, gunakan sertifikat self-signed atau internal CA institusi.

## Storage Foto dan File

Untuk skala kecil, simpan di disk lokal di folder uploads. Untuk skala besar atau multi-node, gunakan object storage S3-compatible (AWS S3, MinIO self-hosted, atau IBM Cloud Object Storage). Update variabel S3_BUCKET, S3_REGION, S3_ACCESS_KEY, S3_SECRET_KEY di .env. Backend perlu library aws-sdk tambahan untuk implementasi S3 (saat ini stub menggunakan disk lokal).

## Backup Strategy

Setup cron job harian untuk pg_dump dengan kompresi: `pg_dump -Fc airsda > /backup/airsda-$(date +\%Y\%m\%d).dump`. Simpan retention 30 hari rolling. Untuk Recovery Point Objective lebih agresif, aktifkan WAL archiving ke storage terpisah.

Backup folder uploads dengan rsync ke server backup terpisah. Foto besar sebaiknya disimpan ke S3 yang sudah punya versioning dan replication built-in.

## Monitoring

Pasang Prometheus + Grafana untuk monitoring server. Backend Node.js dapat expose /metrics endpoint dengan prom-client (tambahkan sendiri). Untuk logging terpusat, kirim log Winston ke ELK stack atau Loki.

Alerting penting: koneksi database mendekati max_connections, disk usage di atas 80 persen, response time API di atas 1 detik, dan error rate di atas 1 persen.

## Hardening Keamanan

Aktifkan firewall ufw dengan hanya port 22, 80, 443 yang terbuka. Database hanya boleh diakses dari localhost atau private network. Pasang fail2ban untuk ban IP yang gagal login berulang. Rate limit di backend sudah ada (default 200 request per 15 menit per IP), sesuaikan jika perlu.

Rotate JWT_SECRET secara periodik (setiap 6 bulan). Aktifkan automatic security update apt unattended-upgrades. Audit user database secara berkala, hapus akun yang tidak aktif lebih dari 6 bulan.

## High Availability

Untuk multi-node aplikasi, gunakan load balancer (HAProxy, Nginx, atau cloud LB) di depan. Pastikan JWT_SECRET sama di semua node. Storage uploads harus shared (NFS atau S3) atau replikasi antar node.

Database: setup streaming replication PostgreSQL ke 1 atau 2 standby. Untuk failover otomatis, gunakan Patroni + etcd atau repmgr. Untuk read scalability, arahkan query SELECT ke replica via PgBouncer atau application-level routing.

## Deployment Frontend

File air-sda.html adalah aplikasi web statis. Bisa di-host di Nginx yang sama, di S3+CloudFront, atau di GitHub Pages untuk akses publik. Untuk koneksi ke backend, ubah hardcoded localhost URL di JavaScript menjadi domain backend produksi.

## Testing Setelah Deploy

Verifikasi dengan curl ke /health endpoint, login dengan akun seed superadmin (password sesuai bcrypt hash di seed - gunakan akun baru yang dibuat manual via API setelah login admin awal), upload satu foto, buat satu inspeksi, dan generate satu laporan. Cek log Winston untuk error.
