From 9141f99f6a250255a5a55af23f5bb38d0aa139a3 Mon Sep 17 00:00:00 2001 From: Wira Irawan Date: Sat, 16 May 2026 23:41:14 +0700 Subject: [PATCH] Fix grade seed path for production deploy --- docs/deploy-production.md | 163 +++++++++++++++++++++++++++++-- scripts/data/.gitkeep | 1 + scripts/seed-grades-from-xls.mjs | 19 +++- 3 files changed, 171 insertions(+), 12 deletions(-) create mode 100644 scripts/data/.gitkeep diff --git a/docs/deploy-production.md b/docs/deploy-production.md index ab1e6b1..1d9b86e 100644 --- a/docs/deploy-production.md +++ b/docs/deploy-production.md @@ -52,6 +52,25 @@ git clone https://git.iptek.co/wirabasalamah/AbelBirdNest-Stock.git . Kalau server butuh autentikasi git internal, siapkan credential sesuai kebijakan server Git Anda. +Catatan: + +- perintah di atas hanya benar jika `/var/www/abelbirdnest-web` masih kosong +- jika Anda sudah menjalankan clone biasa dan hasilnya menjadi: + `/var/www/abelbirdnest-web/AbelBirdNest-Stock` + maka lanjutkan semua perintah deploy dari folder itu: + +```bash +cd /var/www/abelbirdnest-web/AbelBirdNest-Stock +``` + +- alternatifnya, jika ingin struktur tanpa subfolder tambahan, hapus isi folder tujuan lalu clone ulang dengan titik: + +```bash +rm -rf /var/www/abelbirdnest-web/AbelBirdNest-Stock +cd /var/www/abelbirdnest-web +git clone https://git.iptek.co/wirabasalamah/AbelBirdNest-Stock.git . +``` + ## 4. Environment Production Salin `.env.production.example` menjadi `.env.production`, lalu isi nilainya. @@ -79,14 +98,77 @@ Catatan: - `AUTH_BOOTSTRAP=false` wajib untuk production. - `APP_URL` harus domain production final. -## 5. Install Dependency, Database & Migration +## 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 'ganti-dengan-password-yang-kuat'; +``` + +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:ganti-dengan-password-yang-kuat@127.0.0.1:5432/abelbirdnest_prod" +``` + +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" +``` + +Catatan: + +- untuk `psql`, jangan tambahkan `?schema=public` +- untuk Prisma `DATABASE_URL`, tetap gunakan `?schema=public` + +## 6. Install Dependency, Database & Migration Repo ini sudah disiapkan memakai migration Prisma. Jalankan: ```bash -cd /var/www/abelbirdnest-web +cd /var/www/abelbirdnest-web/AbelBirdNest-Stock npm install npm run prisma:generate npm run prisma:migrate:deploy @@ -104,13 +186,74 @@ Data seed yang dibawa: - bank - currency -## 6. Build Production +### Khusus Seed Grade + +Seed `grade` membutuhkan file sumber `Grade.xls`. + +Sebelum menjalankan: ```bash +npm run seed:master +``` + +unggah dulu file `Grade.xls` ke server, misalnya ke: + +```bash +/var/www/abelbirdnest-web/AbelBirdNest-Stock/scripts/data/Grade.xls +``` + +Contoh dari laptop lokal: + +```bash +scp "Grade.xls" user@server:/var/www/abelbirdnest-web/AbelBirdNest-Stock/scripts/data/Grade.xls +``` + +Lalu jalankan: + +```bash +cd /var/www/abelbirdnest-web/AbelBirdNest-Stock +npm run seed:grades +``` + +Alternatif jika file ada di lokasi lain: + +```bash +node scripts/seed-grades-from-xls.mjs /path/ke/Grade.xls +``` + +atau: + +```bash +GRADE_XLS_PATH=/path/ke/Grade.xls npm run seed:grades +``` + +Urutan pertama kali untuk fresh database: + +```bash +cd /var/www/abelbirdnest-web/AbelBirdNest-Stock +npm install +npm run prisma:generate +npm run prisma:migrate:deploy +npm run seed:banks +npm run seed:currencies +npm run seed:grades +``` + +Catatan: + +- `prisma:migrate:deploy` akan membuat seluruh tabel dari migration yang ada di repo +- `seed:banks` dan `seed:currencies` bisa langsung dijalankan +- `seed:grades` butuh file `Grade.xls` lebih dulu +- user login production tetap harus dibuat terpisah, jangan mengandalkan akun dev/default + +## 7. Build Production + +```bash +cd /var/www/abelbirdnest-web/AbelBirdNest-Stock npm run build ``` -## 7. Jalankan App di Port 3007 +## 8. Jalankan App di Port 3007 Manual: @@ -142,7 +285,7 @@ Untuk verifikasi: sudo systemctl is-enabled abelbirdnest-web ``` -## 8. Reverse Proxy Nginx +## 9. Reverse Proxy Nginx Gunakan file: @@ -159,7 +302,7 @@ sudo nginx -t sudo systemctl reload nginx ``` -## 9. Health Check +## 10. Health Check Endpoint health: @@ -173,12 +316,12 @@ Contoh: curl https://abelbirdnest.id/api/v1/health ``` -## 10. Update Deployment Berikutnya +## 11. Update Deployment Berikutnya Jika aplikasi sudah live dan ada update dari git: ```bash -cd /var/www/abelbirdnest-web +cd /var/www/abelbirdnest-web/AbelBirdNest-Stock git pull origin main npm install npm run prisma:migrate:deploy @@ -188,7 +331,7 @@ sudo systemctl restart abelbirdnest-web Jika branch utama nanti bukan `main`, sesuaikan perintah `git pull`. -## 11. Checklist Go-Live +## 12. Checklist Go-Live - `AUTH_BOOTSTRAP=false` - `AUTH_SECRET` sudah production-grade @@ -201,7 +344,7 @@ Jika branch utama nanti bukan `main`, sesuaikan perintah `git pull`. - login, reset password, dan email verifikasi sudah dites - create purchase, receipt, lot, sale sudah dites -## 12. Catatan Penting +## 13. Catatan Penting - Jangan pakai `npm run db:push` untuk production. - Jangan pakai akun default development. diff --git a/scripts/data/.gitkeep b/scripts/data/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/scripts/data/.gitkeep @@ -0,0 +1 @@ + diff --git a/scripts/seed-grades-from-xls.mjs b/scripts/seed-grades-from-xls.mjs index a528cf4..23c2432 100644 --- a/scripts/seed-grades-from-xls.mjs +++ b/scripts/seed-grades-from-xls.mjs @@ -1,18 +1,33 @@ import path from "node:path"; +import fs from "node:fs"; +import { fileURLToPath } from "node:url"; import XLSX from "xlsx"; import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient(); +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); -const sourcePath = - process.argv[2] ?? "/Users/wirabasalamah/work/abelbirdnest/data gudang/Grade.xls"; +const defaultSourcePath = path.join(__dirname, "data", "Grade.xls"); +const sourcePath = process.argv[2] ?? process.env.GRADE_XLS_PATH ?? defaultSourcePath; function formatCode(prefix, sequence) { return `${prefix}${String(sequence).padStart(5, "0")}`; } async function main() { + if (!fs.existsSync(sourcePath)) { + throw new Error( + [ + `File grade tidak ditemukan: ${sourcePath}`, + "Simpan file Grade.xls di scripts/data/Grade.xls", + "atau jalankan: node scripts/seed-grades-from-xls.mjs /path/ke/Grade.xls", + "atau set env: GRADE_XLS_PATH=/path/ke/Grade.xls" + ].join("\n") + ); + } + const workbook = XLSX.readFile(sourcePath); const sheetName = workbook.SheetNames[0]; const rows = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], { defval: "" });