Lewati ke konten utama

Database Schema Overview

Summary of the PostgreSQL schema used by Kesles Merchant. DDL details are in merchant_database/<db_name>/migrations/v1/.

For the list of VIEWs (regular & materialized) per consumer tier

Last updated: 2026-06-23 — legacy psp.*/sales_orders/purchasing/inventory tables DROPPED from main DB (mig 086-101); merchants.tid DROPPED (mig 104); integration, sandbox, document schemas added (mig 107-109); notification DB split into per-service schemas whatsapp/email/firebase (mig 010-012). db_kesles_merchant at v1/112.

Database Topology

DatabaseStatusOwner ServiceMigrations
db_kesles_merchant🟢 LIVE — runtime utamamerchant_core_apiv1/112
db_kesles_merchant_auth🟢 LIVE — extraction COMPLETE 2026-05-30auth_service (port 8081)v1/012
db_kesles_merchant_order🟢 LIVEorder_service (port 8083)v1/009
db_kesles_merchant_payment🟢 LIVEpayment_service (port 8085)v1/008
db_kesles_merchant_inventory🟢 LIVEinventory_service (port 8084)v1/016
db_kesles_merchant_partner🟢 LIVEpartner_service (port 8086)v1/006
db_kesles_merchant_marketing🟢 LIVE — extraction Phase 9 COMPLETE 2026-05-29marketing_service (port 8095)v1/002
db_kesles_merchant_content🟢 LIVEcontent_service (port 8090)v1/001
db_kesles_merchant_notification🟢 LIVE — cutover 2026-05-26whatsapp_service, email_service, firebase_servicev1/012
db_reference🟢 LIVE — master datashared (read-only oleh semua service)61 SQL files

Cross-DB FK policy: tidak ada FK constraint antar database. Relasi lintas DB disimpan sebagai plain UUID kolom biasa, divalidasi di app layer. Lihat comment cross-DB UUID → pada DDL.

Schema Per Database

db_kesles_merchant — Runtime Utama

Catatan penting: schema iam, auth, kyc, notification, content, marketing sudah KOSONG total — semua tabel telah di-DROP dan dipindah ke DB masing-masing. Schema shell mungkin masih ada tetapi tidak ada tabel.

SchemaOwner ServiceStatus
merchantmerchant_core_apiAKTIF — merchants, outlets, terminals, registration
pspdashboard_apiAKTIF — hanya tersisa outbound_requests + merchant_psp_pairings + view v_active_merchants. api_keys/event_log DROPPED (mig 087-088), view device DROPPED (mig 101). Sole SOT db_kesles_merchant_payment.psp.*.
integrationintegration_api / dashboard_apiAKTIF — merchant_accounts, merchant_sandbox_access (mig 107-108)
sandboxintegration_apiAKTIF — transactions, webhook log (mig 108)
documentmerchant_core_apiAKTIF — signers + jenis dokumen → penandatangan (mig 109)
fraudmerchant_core_apiAKTIF — fraud signal, baseline, ML feature vector (mig 080-082, 2026-06-05)
legalauth_serviceAKTIF — legal documents (pindah dari iam via mig 060)
reportmerchant_core_api⚠️ KOSONG — DROP SCHEMA report CASCADE (mig v1/106). Report aggregate pindah ke db_kesles_merchant_planning; index report kini di tabel merchant.*.
planningmerchant_core_api⚠️ KOSONG — DROP SCHEMA planning CASCADE (mig v1/106). Sole SOT db_kesles_merchant_planning (planning_service, port 8097).
partnerdashboard_api⚠️ KOSONG — DROP SCHEMA CASCADE mig v1/071 (2026-06-03). Sole SOT: db_kesles_merchant_partner.
iammerchant_core_api⚠️ KOSONG — seluruh tabel dropped mig v1/057 (2026-05-30). Schema shell removed cascade. auth_service adalah sole SOT.
authmerchant_core_api⚠️ KOSONG — dropped mig v1/057 bersama iam.
kycmerchant_core_api⚠️ KOSONG — dropped mig v1/057 bersama iam.
notificationwhatsapp-service⚠️ KOSONG — seluruh tabel di-DROP (mig v1/043+044, 2026-05-26). Shell di-DROP mig v1/067.
contentmerchant_core_api⚠️ KOSONG — extracted ke db_kesles_merchant_content. DROP mig v1/068.
marketingmerchant_core_api⚠️ KOSONG — extracted ke db_kesles_merchant_marketing. DROP mig v1/072 (2026-05-29).

db_kesles_merchant_auth — Auth Domain

Extraction COMPLETE 2026-05-30. auth_service adalah sole source of truth untuk semua data identity/auth/kyc.

SchemaTabel
identityusers, auth_identities, user_emails, roles, permissions, role_permissions, user_roles, platforms, user_platform_access, user_account_settings, user_security_pins, legal_documents
authuser_sessions, user_devices, device_login_challenges, otp_request_locks, otp_challenges, email_verification_tokens, password_reset_tokens, dashboard_login_otp_challenges, dashboard_password_reset_tokens, auth_audit_logs, pin_reset_gates
kycsubmissions, documents, audit_events

Total: 26 tabel (identity 12 + auth 11 + kyc 3). Migrasi v1/001–012.

Status: Data live dari auth_service (port 8081). JWT_ISSUER=kesles-merchant-auth. iam.* di db_kesles_merchant sudah DROPPED cascade (mig 057, 27 objects dropped).

db_kesles_merchant_order — Order Domain

Owner service: order_service (port 8083). Sole source of truth untuk order/shipping domain.

Schema: orders

sales_orders — header order pembelian device/produk Kesles
sales_order_items — line item per order
sales_quotations — snapshot harga saat order dibuat
shipping_orders — pengiriman per order
shipping_order_units — unit per pengiriman
merchant_deposits — deposit merchant terkait order
sales_order_payments — payment lifecycle per order (mig 004):
payment_type: full | down_payment | installment | settlement
payment_method: transfer | qris
status: pending → submitted → verified → completed / failed / cancelled

--- Shipping reference tables (mig 005) ---
shipping_service_fee_config — singleton konfigurasi biaya layanan pengiriman
ref_komerce_destination — cache destinasi Komerce API
ref_komerce_shipping_rate — cache tarif ongkir per rute + kurir + berat
ref_shipping_origin — konfigurasi lokasi asal pengiriman (gudang Kesles)
worker_komerce_seed_state — singleton state worker sync data Komerce

Flow B payment note: orders.sales_order_payments adalah tabel payment untuk Flow B (merchant beli produk Kesles). Bukan di payment.transactions. PSP event link via cross-DB UUID psp_event_id → db_kesles_merchant_payment.psp.event_log.id.

db_kesles_merchant_payment — Payment Domain

Schema: psp (3 tabel) + payment (8 tabel) + worker (2 tabel). Total: 13 tabel.

--- GROUP A: PSP integration ---
psp.api_keys — HMAC auth untuk inbound dari payment.kesles.com
psp.event_log — inbound PSP webhook, idempotency via external_event_id (5yr retention)
psp.outbound_requests — log HTTP call keluar ke payment.kesles.com

--- GROUP B: Payment core ---
payment.qris_config — SINGLETON korporat PT Inti Kesles Nusantara (1 row via unique((1)))
NMID: ID9999999999999 — dipakai Flow B (merchant beli produk Kesles)
payment.transactions — Flow A ONLY: customer → merchant via PSP/bank
BUKAN Flow B (merchant beli produk → orders.sales_order_payments)
payment.settlements — batch settlement dari bank acquirer
payment.transaction_daily_fees — aggregate biaya layanan harian per merchant
payment.refunds — refund event log + lifecycle
payment.transactions_daily_agg — pre-aggregated analytics harian per (merchant, outlet) (mig 008)
payment.transactions_monthly_agg — pre-aggregated analytics per (merchant, outlet, bulan)
payment.merchant_financials — monthly PnL snapshot per merchant

--- GROUP C: Worker ---
worker.job_runs — audit log eksekusi background job
worker.recon_findings — immutable reconciliation evidence

QRIS architecture:

  • Per-merchant QRIS (Flow A — customer bayar ke merchant): merchants.nmid/mid/tid di db_kesles_merchant
  • Korporat QRIS (Flow B — merchant beli produk Kesles): payment.qris_config singleton di db_kesles_merchant_payment

db_kesles_merchant_inventory — Inventory Domain

Owner service: inventory_service (port 8084). db_kesles_merchant_inventory adalah sole source of truth.

Schema: inventory (migrasi v1/001–016)

warehouses — master gudang regional
products — katalog produk (device model, aksesori)
product_categories — kategori produk
product_specs_payment_device — spesifikasi teknis payment device per produk
product_inventory_items — per-unit inventory (terminal individual, berseri)
terminal_unit_extensions — data ekstensi per terminal unit (atribut tambahan)
product_inventory_stock — stok bulk non-serialized
product_purchase_cost_history — history HPP per produk
terminal_unit_status_logs — log perubahan status unit (IMEI/SN)
terminal_unit_activity_logs — log penerimaan/aktivitas barang

Multi-tenant ready: tenant_id sentinel 00000000-0000-0000-0000-000000000001 = Kesles single-tenant.

Schema: purchasing

Migrasi v1/009–010. Purchasing domain tetap di db_kesles_merchant_inventory (tidak diekstrak ke service terpisah).

purchasing.vendors — master vendor/supplier
purchasing.purchase_orders — purchase order (PO) header
purchasing.purchase_order_items — line item per PO
purchasing.goods_receipts — penerimaan barang (GR) header
purchasing.goods_receipt_items — line item per GR
purchasing.goods_receipt_serial_events — event serialisasi unit saat terima barang
purchasing.purchase_invoices — invoice dari vendor
purchasing.purchase_invoice_items — line item per invoice
purchasing.vendor_payments — pembayaran ke vendor
purchasing.vendor_payment_applications — aplikasi pembayaran ke invoice

db_kesles_merchant_partner — Partner Domain

Schema: partner (15 tabel, migrasi v1/001–006)

partners — partner entity (reseller, agency, affiliate, community, sales)
partner_users — user × partner many-to-many
partner_reps — PIC/sales rep per partner
partner_commercial_plans — paket komersial per partner
commercial_plan_service_fee_tiers — tier level biaya layanan per commercial plan
revenue_share_rules — aturan bagi hasil
api_credentials — HMAC credential + allowed_ip_ranges
merchant_access — partner × merchant grant
merchant_consents — consent scope + expiry
api_audit_logs — request log
access_scope_changes — audit perubahan scope
webhook_deliveries — log webhook ke partner
partner_settlement_lines — settlement line partner
partner_device_subsidy_orders — order subsidi device
partner_device_subsidy_allocations — alokasi subsidi per unit

db_kesles_merchant_marketing — Marketing Domain

Extraction COMPLETE 2026-05-29. db_kesles_merchant.marketing.* sudah DROPPED total (Phase 9).

Schema: marketing (5 tabel, migrasi v1/001–002)

promo_page_settings — konfigurasi halaman promo
promo_items — item promo (diskon, voucher, bundle)
user_promo_claims — klaim promo per user
promo_schedules — jadwal kirim promo (mig 002)
promo_send_logs — log eksekusi pengiriman promo terjadwal

db_kesles_merchant_content — Content Domain

Schema: content (6 tabel, migrasi v1/001)

umkm_academy_topics — topik UMKM Academy
umkm_academy_articles — artikel per topik
umkm_academy_settings — reading preferences per user
umkm_academy_article_views — view/dwell tracking per artikel per user
umkm_academy_featured_tips — tips unggulan yang ditampilkan di homepage
umkm_academy_videos — konten video UMKM Academy

db_kesles_merchant_notification — Notification Domain

Cutover COMPLETE 2026-05-26. 3/3 service live di DB ini. Tabel domain di-split ke schema per-service (whatsapp/email/firebase) via mig 010; schema notification tinggal tabel SHARED. Compat view di-DROP mig 012. Migrasi v1/001–012.

--- schema whatsapp (whatsapp_service) ---
whatsapp.whatsapp_provider_configs — konfigurasi provider WhatsApp (API key, endpoint)
whatsapp.whatsapp_templates — template pesan WhatsApp terdaftar
whatsapp.whatsapp_messages — log pengiriman pesan WhatsApp per user
whatsapp.whatsapp_send_attempts — attempt log pengiriman per pesan WhatsApp
whatsapp.whatsapp_delivery_events — event status pengiriman WhatsApp
whatsapp.template_catalog — katalog template (mig 011)

--- schema email (email_service) ---
email.email_messages — log pengiriman email per user
email.email_send_attempts — attempt log pengiriman per email
email.template_catalog — katalog template (mig 011)

--- schema firebase (firebase_service) ---
firebase.fcm_push_tokens — FCM token registry per device (sole SOT — mig 040 drop legacy)
firebase.fcm_broadcasts — broadcast announcement (mig 006)
firebase.fcm_broadcast_sends — per-recipient send log broadcast
firebase.phone_verifications — Firebase Phone Auth verification log (dipindah dari iam — mig 039)
firebase.template_catalog — katalog template (mig 011)

--- schema notification (SHARED lintas-service) ---
notification.user_notification_prefs — preferensi notifikasi per user (mig 007)

db_reference — Master Data (Shared, Read-Only)

Schema: public

ref_province — Indonesian province master
ref_city — city/regency master
ref_district — sub-district (kecamatan) master
ref_subdistrict — village (kelurahan/desa) master
ref_postal_code — postal code master
ref_business_scale — business scale (for Smart Financial Review)
ref_business_category — business category
ref_business_type — business type
ref_payment_service_provider — PSP master (Kesles PSP + external)
ref_payment_jenis_kartu_psp — card/instrument category per PSP
ref_payment_qr_payment_type — QR payment type (QRIS, QRIS Cross-border)

Schema: merchant

Dibuat via mig 013. Tabel merchant-specific dipisah dari public untuk domain separation dan permission granularity.

merchant.ref_mcc_code — MCC (ISO 18245) + MDR category + rate + risk level
merchant.ref_shipping_service — jenis layanan pengiriman (reguler, express, dll)
merchant.ref_shipping_partner — mitra kurir (JNE, J&T, Komerce, self-courier, dll)
merchant.ref_shipping_partner_service — layanan per mitra kurir (mapping service_code)
merchant.ref_shipping_partner_coverage — cakupan wilayah per mitra kurir
merchant.ref_shipping_origin — konfigurasi lokasi asal pengiriman (gudang Kesles)
merchant.ref_shipping_rate — tarif ongkir per rute + kurir + berat + service
merchant.ref_shipping_destination_region_group — pengelompokan region tujuan untuk kalkulasi tarif
merchant.ref_shipping_fallback_rule — aturan fallback jika tarif tidak ditemukan
merchant.ref_shipping_priority_destination — destinasi prioritas (override tarif khusus)

Protected: seluruh tabel db_reference tidak boleh di-reset/truncate. Lihat scripts/README.md § "Tabel Yang Tidak Boleh Terhapus".

Core Tables — db_kesles_merchant

merchant.*

merchants — main merchant entity (profile, status, NMID/MID per-merchant). Kolom `tid` DROPPED (mig 104)
merchant_users — user × merchant many-to-many (role per merchant; + outlet_id mig 097)
merchant_registration_requests — KYC registration lifecycle (mig 078: + kolom nik untuk NIK dedup fraud)
merchant_outlets — outlet per merchant (mig 095)
company_profile — profil perusahaan + default signer (mig 018)
company_bank_accounts — rekening bank perusahaan (+ outlet_id mig 098)
terminals — payment terminal per outlet
device_activity_logs — device + PSP pairing log

--- DROPPED by mig 076 (2026-06-05) — sole SOT di db_kesles_merchant_payment ---
transactions — ⛔ DROPPED — payment.transactions di db_kesles_merchant_payment
transaction_daily_fees — ⛔ DROPPED — payment.transaction_daily_fees
settlements — ⛔ DROPPED — payment.settlements
refunds — ⛔ DROPPED — payment.refunds
v_transaction_with_fee — ⛔ DROPPED VIEW
v_merchant_daily_summary — ⛔ DROPPED VIEW

--- DROPPED — sole SOT di db_kesles_merchant_order (order_service) ---
sales_orders — ⛔ DROPPED (mig 089) — orders.sales_orders
sales_order_items — ⛔ DROPPED (mig 089) — orders.sales_order_items
shipping_orders — ⛔ DROPPED (mig 094) — orders.shipping_orders
sales_quotations — ⛔ DROPPED (mig 094) — orders.sales_quotations
merchant_deposits — ⛔ DROPPED (mig 094) — orders.merchant_deposits

--- DROPPED — sole SOT di db_kesles_merchant_inventory (inventory_service) ---
purchasing.* — ⛔ DROPPED (mig 093) — purchasing.* di inventory DB
payment_terminal_inventory, payment_device_models, terminal *_logs — ⛔ DROPPED (mig 100)
qris_config — ⛔ DROPPED (mig 086) — payment.qris_config di db_kesles_merchant_payment

QRIS per-merchant (Flow A): kolom merchants.nmid, merchants.mid adalah QRIS identity masing-masing merchant untuk menerima pembayaran customer (merchants.tid sudah DROPPED mig 104; TID kini per-terminal di inventory.terminal_unit_extensions.tid). Berbeda dengan payment.qris_config yang merupakan QRIS korporat Kesles untuk Flow B.

psp.* (di db_kesles_merchant)

Sole SOT untuk PSP integration ada di db_kesles_merchant_payment.psp.*. Di main DB hanya tersisa audit trail + pairing + view aktif.

api_keys — ⛔ DROPPED (mig 088) — payment.psp.api_keys
event_log — ⛔ DROPPED (mig 087) — payment.psp.event_log
outbound_requests — audit trail outbound request dashboard_api (TETAP)
merchant_psp_pairings — MID/TID mapping merchant × PSP (TETAP)
v_active_merchants — view aktif (recreate mig 104, tanpa tid)
v_active_merchant_devices — ⛔ DROPPED VIEW (mig 101)

partner.* — ⛔ DROPPED (mig 071, 2026-06-03)

Schema partner.* di db_kesles_merchant sudah di-DROP CASCADE (mig v1/071). Sole SOT sekarang di db_kesles_merchant_partner. PSP auth middleware lookup partner.api_credentials sudah pindah ke HTTP call ke partner_service /internal/credentials/by-key.

fraud.* — AKTIF sejak mig 080 (2026-06-05)

Fraud signal collection, behavioral baseline, dan ML feature vector. Diisi oleh merchant_core_api background job. Akan diekstrak ke fraud_service setelah extraction scheduled.

fraud.events — risk signal per merchant per event (signal_type, severity, score 0-100, status workflow)
Indexes: (merchant_id, status=pending), (merchant_id), (signal_type, created_at)

fraud.merchant_behavior_baseline — baseline perilaku harian per merchant
avg_tx_per_day, avg_amount, p95_amount, active_hour_from/to, sample_days
Diupdate via POST /internal/fraud/baseline/recompute (core_api cron)

fraud.merchant_feature_vectors — snapshot ML feature harian per merchant (PK: merchant_id + snapshot_date)
signal_count_7d/30d, high_severity_ratio, unique_signal_types, avg_score_30d,
amount_volatility, peak_hour_variance
Diisi oleh cron core_api 1× sehari; akan dipakai training Isolation Forest
setelah 3–6 bulan data terkumpul

Convention

  • Primary key: UUID v4 (gen_random_uuid() — pgcrypto)
  • Timestamps: created_at, updated_at, deleted_at (soft delete) — all timestamptz
  • Foreign key: explicit ON DELETE RESTRICT atau ON DELETE CASCADE. Cross-DB FK tidak dibuat — UUID stored as plain column (Cross-DB Policy).
  • Index: composite index untuk query pattern yang jelas, bukan single-column everywhere
  • Naming: snake_case, plural untuk tabel (merchants), singular untuk kolom (merchant_id)
  • Amount: integer (bigint) + currency VARCHAR(3) ISO 4217. Bukan suffix _idr. IDR = unit terkecil rupiah utuh.

Migration Policy

  • Migration files: merchant_database/<db_name>/migrations/v1/NNN_description.sql
  • Naming: 3-digit sequential prefix + snake_case description
  • Cek nomor terakhir sebelum buat file baru: ls merchant_database/<db>/migrations/v1/ — hindari tabrakan
  • Tracker: public.schema_migrations (v1/001 di setiap DB) — selalu insert row setelah apply
  • Helper: scripts/apply_migration.sh — gunakan ini, bukan psql -f langsung
  • Setiap migration harus dapat di-rollback — down migration tersedia
  • 2-eyes review untuk migration yang DROP/ALTER tabel existing
  • Staging minimal 24 jam sebelum production

Riwayat Migrasi db_kesles_merchant (v1/071–112)

#NamaKeterangan
071drop_partner_schemaDROP SCHEMA partner CASCADE — sole SOT di db_kesles_merchant_partner
072drop_marketing_schemaDROP SCHEMA marketing CASCADE — Phase 9 cleanup
073drop_audit_schemaDROP SCHEMA audit CASCADE
074report_indexesComposite indexes untuk query report.* (performa laporan)
075business_photo_coordinatesKolom geolokasi untuk foto bisnis merchant
076drop_payment_tables_phase6DROP merchant.transactions/settlements/refunds/transaction_daily_fees + 2 views — sole SOT di db_kesles_merchant_payment
077shipping_orders_snapshot_columnsTambah so_order_number, so_merchant_id, so_registration_id ke merchant.shipping_orders
078fraud_registration_signalsTambah kolom nik + partial index di merchant_registration_requests (NIK dedup fraud)
079shipping_orders_items_snapshotBackfill so_items_snapshot dari sales_order_items + sales_quotations
080fraud_schema_and_eventsCREATE SCHEMA fraud + fraud.events (signal collection, 3 index)
081fraud_merchant_behavior_baselinefraud.merchant_behavior_baseline (daily behavioral baseline)
082fraud_merchant_feature_vectorsfraud.merchant_feature_vectors (ML feature snapshot, PK merchant+date)
083drop_wac_viewsDROP WAC views (pindah ke inventory DB)
084drop_product_purchase_cost_historyDROP merchant.product_purchase_cost_history
085drop_orphan_tablesDROP tabel orphan sisa
086drop_qris_configDROP merchant.qris_config — sole SOT payment.qris_config
087drop_psp_event_logDROP psp.event_log (orphan)
088drop_psp_api_keysDROP psp.api_keys — sole SOT payment.psp.api_keys
089drop_sales_ordersDROP merchant.sales_orders + sales_order_items — sole SOT order DB
090drop_komerce_worker_tablesDROP ref_komerce_* + worker_komerce_seed_state
091drop_shipping_service_fee_configDROP merchant.shipping_service_fee_config
092drop_ref_shipping_originDROP merchant.ref_shipping_origin
093drop_purchasingDROP purchasing.* — sole SOT inventory DB
094drop_merchant_order_tablesDROP merchant_deposits/shipping_orders/shipping_order_units/sales_quotations
095create_merchant_outletsCREATE merchant.merchant_outlets (multi-outlet)
096add_fk_transactions_outletFK transaksi → outlet
097add_outlet_id_to_merchant_usersTambah outlet_id ke merchant_users
098add_outlet_id_to_company_bank_accountsTambah outlet_id ke company_bank_accounts
099add_latest_terminal_to_merchantsTambah latest terminal ke merchants
100drop_legacy_inventory_tablesDROP payment_terminal_inventory/device_models/logs — sole SOT inventory DB
101drop_psp_device_viewDROP psp.v_active_merchant_devices
102fix_psp_active_merchants_viewFix psp.v_active_merchants (no LATERAL join)
103fcm_delivery_logFCM delivery ack/log
104drop_merchants_tidDROP merchants.tid (TID per-terminal di inventory)
105deprecate_invitation_otp_columnsCOMMENT deprecate otp_hash/otp_attempts staff invitation
106drop_legacy_planning_schemasDROP SCHEMA report + planning CASCADE — sole SOT planning DB
107integration_merchant_accountsCREATE SCHEMA integration + merchant_accounts
108sandbox_schemaCREATE SCHEMA sandbox + integration.merchant_sandbox_access + sandbox.transactions
109document_signersCREATE SCHEMA document + document.signers
110dashboard_notification_readspublic.dashboard_notification_reads (read state Notification Center)
111report_indexes_phase2Index report Fase 2 (merchant activation)
112staff_invitation_outlet_targetingStaff invitation outlet targeting