Skip to content

Repository files navigation

Wilayah.id — Microservice

API dan database wilayah administrasi pemerintahan Indonesia sesuai Kepmendagri No 300.2.2-2430 Tahun 2025.

Live preview: https://wilayah.indoplatform.id

Fitur

  • 4-level hierarchical data: Provinsi → Kabupaten/Kota → Kecamatan → Kelurahan/Desa
  • 9 public REST API endpoints dengan caching 24 jam
  • JSON response terstruktur dengan pagination
  • Protected admin endpoints (IP whitelist + API key)
  • Auto-sync dari 2 sumber resmi:
    • cahyadsn/wilayah (GitHub, MIT License) — bulk SQL import
    • wilayah.id — incremental REST API
  • Admin dashboard dengan HTTP Basic Auth
  • Auto-compress upload (max 3MB per file)
  • SQLite-friendly syntax dengan PostgreSQL native types

Stack

  • Framework: Next.js 14.2 App Router, TypeScript strict
  • ORM: Prisma 5.22 + PostgreSQL 17
  • Auth: HTTP Basic Auth + bcrypt + jwt (jose)
  • UI: Tailwind 3 + Radix UI + lucide-react
  • Cache: in-memory + HTTP Cache-Control: public, max-age=86400

Setup Lokal

pnpm install
pnpm db:push        # Buat schema di DB lokal
pnpm db:seed         # Opsional: import data dari SQL
pnpm dev             # http://localhost:3010

Environment

Copy .env.example.env:

DATABASE_URL="postgresql://postgres@localhost:5432/wilayah?schema=public"
NEXTAUTH_SECRET="<generate-random-32-byte>"
NEXTAUTH_URL="http://localhost:3010"
WILAYAH_ID_API_BASE="https://wilayah.id/api"
NEXT_PUBLIC_INTERNAL_API_KEY="<generate-random>"
WILAYAH_INTERNAL_API_KEY="<generate-random>"
SESSION_SECRET="<generate-random>"

Generate secrets:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

API Public

Semua endpoint return JSON dengan struktur { data, meta, pagination }.

GET /api/v1/provinsi                    → list 38 provinsi Indonesia
GET /api/v1/provinsi/{kode}            → detail provinsi + list kabupaten (kode 2 digit BPS)
GET /api/v1/kabupaten?provinsi={kode} → list kabupaten/kota per provinsi
GET /api/v1/kabupaten/{kode}          → detail kabupaten + list kecamatan (kode 4 digit)
GET /api/v1/kecamatan?kabupaten={kode} → list kecamatan per kabupaten
GET /api/v1/kecamatan/{kode}           → detail kecamatan + list kelurahan (kode 6 digit)
GET /api/v1/kelurahan?kecamatan={kode} → list kelurahan per kecamatan
GET /api/v1/kelurahan/{kode}           → detail kelurahan (kode 10 digit)
GET /api/v1/search?q={keyword}          → search cross-level (min 2 karakter)

Response shape:

{
  "data": [...],
  "meta": { "total": 38, "page": 1, "pageSize": 50, "level": 1 },
  "pagination": { "page": 1, "pageSize": 50, "totalPages": 1, "hasNext": false, "hasPrev": false }
}

Headers:

  • Cache-Control: public, max-age=86400, stale-while-revalidate=3600 (24h cache)
  • ETag untuk conditional GET

Admin API (requires X-Internal-Api-Key + IP whitelist)

POST /api/admin/sync      → trigger sync (body: { source: "CAHYADSN_SQL" | "WILAYAH_ID_API", trigger: "MANUAL" | "SCHEDULED" | "INITIAL" })
GET  /api/admin/sync/log → last 20 sync runs
GET  /api/admin/stats    → table counts
GET  /api/admin/whitelist → list IP whitelist
POST /api/admin/whitelist → add IP (body: { ipAddress, label })
DELETE /api/admin/whitelist?id={id} → remove IP

IP Whitelist

Public API endpoints (/api/v1/*) dilindungi IP whitelist. Default allow:

  • 127.0.0.1, ::1, localhost
  • IP yang ada di tabel ip_whitelist

Admin IP whitelist dimanage via dashboard /admin atau API di atas.

Admin Dashboard

Path: /admin

Login dengan HTTP Basic Auth (user disimpan di tabel User dengan role: "ADMIN").

Fitur:

  • Stats total records (5 model utama)
  • Sinkronisasi data (Sync dari SQL / Refresh dari wilayah.id API)
  • Riwayat sinkronisasi (auto-refresh 5 detik)
  • IP Whitelist manager (CRUD)

Sinkronisasi

  1. Dari SQL (cahyadsn/wilayah): Download JSON dari GitHub, bulk upsert via Prisma.
  2. Dari wilayah.id API: Incremental fetch per parent code, cek updated_at.

Deploy

# 1. Buat DB di Postgres
psql -U postgres -c "CREATE DATABASE wilayah;"

# 2. Push schema
pnpm db:push

# 3. Sync data (via UI atau API)
curl -X POST https://wilayah.indoplatform.id/api/admin/sync \
  -H "Content-Type: application/json" \
  -H "X-Internal-Api-Key: YOUR_KEY" \
  -d '{"source": "WILAYAH_ID_API", "trigger": "INITIAL"}'

# 4. Setup systemd service (lihat scripts/deploy/)

Sumber Data

  • cahyadsn/wilayah (GitHub, MIT License) — database SQL
  • wilayah.id — API publik untuk incremental refresh

Database Schema

5 model utama (prisma/schema.prisma):

model Provinsi {
  id        Int      @id  // BPS 2-digit code
  kode      String   @unique @db.VarChar(4)
  nama      String
  kabupaten Kabupaten[]
}

model Kabupaten {
  id         Int      @id  // 4-digit code
  kode       String   @unique @db.VarChar(6)
  provinsiId Int
  nama       String
  jenis      String   // "KABUPATEN" | "KOTA"
  kecamatan  Kecamatan[]
}

model Kecamatan {
  id          Int      @id  // 6-digit code
  kode        String   @unique @db.VarChar(8)
  kabupatenId Int
  nama        String
  kelurahan   Kelurahan[]
}

model Kelurahan {
  id          Int      @id  // 10-digit code
  kode        String   @unique @db.VarChar(13)
  kecamatanId Int
  nama        String
}

// Infrastructure
model SyncLog      { ... }   // sync history
model IpWhitelist  { ... }   // IP whitelist rules

License

MIT — Data licensed under Kepmendagri No 300.2.2-2430 Tahun 2025 (public domain).

About

Merge updated database of indonesian area

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages