Setup lokal (macOS) — ahu-ocr-akta-notaris PoC
Untuk: agen Claude Code yang menjalankan setup di Mac lokal (macOS 26.5.2).
Tujuan: replikasi environment dev VMdev_3supaya bisabun test+ jalanin app secara lokal.
Sumber kebenaran: ini di-generate dari.env+docker-compose.dev-db.yaml+package.json
VM dev_3 (2026-07-15). Ikuti persis; kalau ada yang gagal, laporkan — jangan menebak.
⚠️ Baca dulu — batas "bisa run di lokal"
App ini bergantung pada layanan on-prem AHU yang TIDAK ada di internet publik:
| Layanan | Alamat | Dipakai untuk |
|---|---|---|
| GPU/OCR/LLM gateway | 192.168.83.20:8200 |
classify, OCR (PaddleOCR), LLM cleanup/extract |
| SABH DB (MySQL) | 192.168.72.102:3306 |
company lookup + registry state |
| PP registry (PG) | 192.168.80.127:5434 |
pendirian PP lookup |
| Apostille registry (MySQL) | 192.168.72.33:3306 |
apostille |
Konsekuensinya, ada 2 mode:
- Mode A — Dev logika + unit test (OFFLINE, direkomendasikan untuk mulai). Semua unit test murni
jalan tanpa jaringan AHU — termasuk seluruh test berakhirnya yang jadi fokus branch ini
(rules-berakhirnya,supporting-doc-classifier,bukti-pengumuman-extract). Cuma butuh Postgres lokal. - Mode B — Jalankan app end-to-end (BUTUH akses jaringan AHU). Upload → classify → OCR → extract
perlu gateway:8200+ DB registry. Dari Mac lokal ini cuma jalan kalau kamu VPN ke jaringan AHU
atau bikin SSH tunnel (lihat Lampiran A). Tanpa itu, app boot tapi tiap proses dokumen gagal/timeout.
Test integrasi yang memanggil gateway/registry akan gagal di Mode A — itu wajar, bukan bug branch ini
(cara membedakannya ada di bagian "Menjalankan test").
1. Prasyarat (macOS 26.5.2)
# Homebrew (kalau belum ada)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Bun — WAJIB versi >= 1.3.14 (VM pakai 1.3.14)
brew install oven-sh/bun/bun # atau: curl -fsSL https://bun.sh/install | bash
bun --version # pastikan >= 1.3.14 ; kalau kurang: bun upgrade
# Git
brew install git
# Postgres 16 — pilih SATU:
# (a) Docker Desktop (paling mirip VM — Postgres 16 via container) → brew install --cask docker
# (b) Postgres native → brew install postgresql@16
Node tidak wajib (semua lewat Bun + bunx prisma), tapi kalau mau aman: brew install node.
2. Clone repo + branch
Repo privat (akses SSH GitHub ke org Virtue-Digital-Indonesia diperlukan).
git clone git@github.com:Virtue-Digital-Indonesia/ahu-ocr-akta-notaris-POC.git
cd ahu-ocr-akta-notaris-POC
git fetch origin
git checkout fix/berakhirnya-status-badan-hukum # branch kerja berakhirnya
Struktur yang relevan: backend/, frontend/, contract/ (shared, punya zod sendiri di root).
3. Install dependencies (TIGA lokasi — jangan lewat satu pun)
contract/ mengambil zod dari node_modules ROOT; backend & frontend punya deps sendiri.
Lupa bun install di root = error Vite Failed to resolve import "zod" from contract/review.ts.
bun install # ROOT — menyediakan zod untuk contract/ (WAJIB, sering terlewat)
cd backend && bun install # postinstall otomatis `prisma generate`
cd ../frontend && bun install
cd ..
4. Postgres lokal + buat database
App butuh 2 DB: ahu_ocr_dev3 (app) + ahu_ocr_dev3_test (test). Nama boleh apa saja asal DB test
berakhiran _test (ada guard assertTestDatabase).
Opsi (a) — Docker (mirror VM persis)
docker run -d --name ahu-ocr-dev-db \
-e POSTGRES_USER=ahu -e POSTGRES_PASSWORD=ahu_dev -e POSTGRES_DB=postgres \
-p 5432:5432 postgres:16-alpine
# buat kedua database
docker exec -it ahu-ocr-dev-db psql -U ahu -d postgres \
-c "CREATE DATABASE ahu_ocr_dev3;" -c "CREATE DATABASE ahu_ocr_dev3_test;"
(VM pakai port 47030; lokal pakai 5432 biar simpel — sesuaikan .env di langkah 5.)
Opsi (b) — Postgres native
brew services start postgresql@16
createuser -s ahu 2>/dev/null; psql postgres -c "ALTER USER ahu PASSWORD 'ahu_dev';"
createdb -O ahu ahu_ocr_dev3; createdb -O ahu ahu_ocr_dev3_test
5. File backend/.env
Buat backend/.env. DATABASE_URL/TEST_DATABASE_URL menunjuk Postgres lokal (port 5432).
URL layanan on-prem dibiarkan seperti VM — hanya terpakai di Mode B (butuh VPN/tunnel).
Secret (<ISI…>) minta ke Efran / salin dari .env VM hanya kalau kamu butuh fitur registry;
untuk test berakhirnya (Mode A) tidak diperlukan.
PORT=3001
DATABASE_URL=postgresql://ahu:ahu_dev@127.0.0.1:5432/ahu_ocr_dev3
TEST_DATABASE_URL=postgresql://ahu:ahu_dev@127.0.0.1:5432/ahu_ocr_dev3_test
# ── Layanan on-prem (Mode B; via VPN/tunnel — lihat Lampiran A) ──
OCR_PROVIDER=azure-on-prem
OCR_LAYOUT_PROVIDER=paddleocr
GPU_SERVER_URL=http://192.168.83.20:8200
CLASSIFIER_URL=http://192.168.83.20:8200/api/classifier/classify
CLEANUP_LLM_URL=http://192.168.83.20:8200/v1
AKTA_TXN_CLASSIFIER_URL=http://192.168.83.20:8200/v1
AKTA_TXN_CLASSIFIER_MODEL=Qwen/Qwen3.6-35B-A3B-FP8
JENIS_PERUBAHAN_EARLY_URL=http://192.168.83.20:8200/v1
JENIS_PERUBAHAN_EARLY_MODEL=Qwen/Qwen3.6-35B-A3B-FP8
AZURE_ON_PREM_BASE_URL=http://192.168.83.20:8200
AZURE_ON_PREM_API_KEY=
AZURE_ON_PREM_KTP_MODEL=indonesian_ktp_v4
AZURE_MODEL_NPWP=indonesian_npwp_v5
AZURE_MODEL_NPWP_LAMA=indonesian_old_npwp_v4
AZURE_MODEL_DOMISILI=domicile_statement_v3
AZURE_MODEL_CONTACT_INFO=contact_info_pt_v5
AZURE_MODEL_BUKTI_SETOR=deposit_statement_v4
AZURE_MODEL_SP_PENDIRIAN_PP=sp_pendirian_pp_v4
PADDLE_OCR_URL=http://192.168.83.20:8200
PADDLE_OCR_TIMEOUT_MS=300000
GPU_SERVER_TIMEOUT_MS=300000
KTP_EXTRACTION_SOURCE=paddleocr
NPWP_EXTRACTION_SOURCE=paddleocr
PASSPORT_EXTRACTION_SOURCE=paddleocr
DOMISILI_EXTRACTION_SOURCE=paddleocr
CONTACT_INFO_EXTRACTION_SOURCE=paddleocr
BUKTI_SETOR_EXTRACTION_SOURCE=paddleocr
SP_PENDIRIAN_PP_MODE=custom-model
# ── Registry eksternal — Mode B only. Untuk offline, matikan PP registry: ──
PP_REGISTRY_MODE=mock
# (kalau butuh real: PP_REGISTRY_MODE=real + isi host/kredensial di bawah)
# SABH_DB_HOST=192.168.72.102 ... SABH_DB_PASSWORD=<ISI>
# PP_REGISTRY_DB_HOST=192.168.80.127 ... PP_REGISTRY_DB_PASSWORD=<ISI>
# APOSTILLE_REGISTRY_DB_HOST=192.168.72.33 ... APOSTILLE_REGISTRY_DB_PASSWORD=<ISI>
SECURITY_JWT_SECRET=<ISI-string-acak-panjang>
SECURITY_DEV_LOGIN_SECRET=<ISI-string-acak-panjang>
MAX_FILE_SIZE_MB=20
VOTING_SWEEPER_ENABLED=false
VOTE_BASE_URL=http://localhost:3001
6. Prisma: generate client + push schema
cd backend
bun run db:generate # prisma generate + regen contract/enums.gen.ts (JANGAN edit enums.gen.ts manual)
bun run db:push # push schema ke DB APP (ahu_ocr_dev3), baca DATABASE_URL dari .env
Test DB — JANGAN pakai bun run db:push:test. Script itu hardcode localhost:5433/ahu_ocr_test
(sisa dari repo non-worktree) dan akan ke DB yang salah. Push ke test DB pakai TEST_DATABASE_URL:
DATABASE_URL="$(grep '^TEST_DATABASE_URL=' .env | cut -d= -f2-)" bunx prisma db push
Catatan:
prisma db pushtidak membuat trigger/fungsi SQL custom (mis. audit append-only) —
jadi beberapa test apostille/audit yang butuh trigger akan gagal. Itu pre-existing, bukan berakhirnya.
7. Menjalankan test
cd backend
# (A) Test fokus branch ini — MURNI, jalan OFFLINE, harus HIJAU semua:
bun test \
src/flow-engine/__tests__/rules-berakhirnya.test.ts \
src/services/__tests__/supporting-doc-classifier.test.ts \
src/services/__tests__/bukti-pengumuman-extract.test.ts \
--timeout 20000
# (B) Seluruh suite:
bun run test
Full suite akan punya sejumlah fail pre-existing (apostille/verifikator/admin — butuh trigger DB,
MinIO, atau jaringan registry). Cara memastikan tidak ada regresi dari perubahan kamu: bandingkan set
fail dengan/ tanpa perubahan pada environment yang SAMA:
git stash && bun run test 2>&1 | grep -oE '\(fail\) .*' | sed 's/ \[[0-9.]*ms\]$//' | sort -u > /tmp/base.txt
git stash pop && bun run test 2>&1 | grep -oE '\(fail\) .*' | sed 's/ \[[0-9.]*ms\]$//' | sort -u > /tmp/mine.txt
comm -13 /tmp/base.txt /tmp/mine.txt # kosong = nol regresi
Typecheck: cd backend && bunx tsc --noEmit dan cd frontend && bunx tsc --noEmit
(ada 2–3 error pre-existing di file non-berakhirnya; file berakhirnya harus bersih).
8. Menjalankan app (Mode B — butuh gateway)
# terminal 1 — backend (baca PORT dari .env, mis. 3001)
cd backend && bun run dev
# terminal 2 — frontend (Vite; proxy /api ke backend)
cd frontend && VITE_API_PROXY_TARGET=http://localhost:3001 bun run dev
# buka http://localhost:5173 (port Vite default)
Kalau belum VPN/tunnel ke AHU, halaman jalan tapi setiap upload/classify gagal (gateway :8200
tak terjangkau). Sambungkan dulu lewat Lampiran A.
Lampiran A — Menjangkau layanan on-prem dari Mac lokal
Pilih salah satu:
-
VPN AHU — kalau kamu punya akses VPN ke subnet
192.168.x, cukup itu;.envbisa dibiarkan
apa adanya (URL192.168.83.20:8200dst. langsung kena). -
SSH tunnel lewat host yang bisa menjangkau
192.168.83.20(mis. valserver):
bash ssh -N \ -L 8200:192.168.83.20:8200 \ -L 3306:192.168.72.102:3306 \ developer@<valserver-ip>
Lalu ubah.envsupaya menunjuklocalhost:
GPU_SERVER_URL/CLASSIFIER_URL/CLEANUP_LLM_URL/AZURE_ON_PREM_BASE_URL/PADDLE_OCR_URL → http://localhost:8200/...
danSABH_DB_HOST=127.0.0.1(port 3306). Biarkan tunnel terbuka selama app jalan.
Lampiran B — Gotcha yang sudah diketahui
bun installdi ROOT wajib (untukcontract/zod) — selain backend & frontend.db:push:testsalah target — pakai one-linerTEST_DATABASE_URL(langkah 6).- Test frontend yang render PDF gagal di headless (
DOMMatrix is not defined, react-pdf/pdfjs) —
pre-existing, bukan logika. - enums.gen.ts di-generate (
bun run db:gen-enums) — jangan diedit tangan. - Fokus branch ini cuma butuh Mode A (offline + Postgres lokal). Untuk demo end-to-end pakai data
sample nyata, perlu Mode B (gateway) — dan sample PDF berakhirnya ada di VM Efran, di luar repo
(dokumen hukum, tidak boleh masuk git).
```