18

Spesifikasi Teknis Dual-Track & Dual-Banking

Updated: Sep 2026Oleh: System

title: "Spesifikasi Teknis: Dual-Track Enterprise & Dual-Banking Architecture" access: "private" unit: "Semua Unit" category: "Spesifikasi Teknis"#

šŸ—ļø Spesifikasi Teknis: Dual-Track Enterprise & Dual-Banking Architecture

Dokumen Resmi Arsitektur Inti: Dokumen ini menjadi Single Source of Truth (SSOT) bagi arsitek perangkat lunak, engineer, auditor, dan pengurus BUMDes untuk memahami landasan teknis, pemisahan skema database, dan logika pemrograman sistem Dual-Track (Pertanian & Peternakan) serta Dual-Banking (Simpan Pinjam) pada ERP BUMDes Bolulango.


šŸ“‹ Daftar Isi#

  1. Latar Belakang & Filosofi Arsitektur
  2. Pilar I: Dual-Track Enterprise Architecture (Pertanian & Peternakan)
  1. Pilar II: Dual-Banking Architecture (Simpan Pinjam USP & USPPS)
  1. Mekanisme Konsolidasi & Auto-Eliminasi Level Holding
  2. Diagram Alur Data & Interaksi Sistem
  3. Panduan Pengembang & Testing Suite

1. Latar Belakang & Filosofi Arsitektur#

Ekosistem BUMDes Bolulango mengelola portofolio unit usaha yang heterogen dengan karakteristik permodalan, regulasi, dan tujuan sosial-ekonomi yang berbeda secara tajam.

Upaya menggabungkan seluruh unit ke dalam satu logika akuntansi dan bisnis yang seragam (monolithic flat-model) terbukti menciptakan dua ancaman fatal:

  1. Pencemaran Kepatuhan Syariah (Sharia Non-Compliance / Commingling): Menggabungkan dana titipan wadiah atau margin murabahah nasabah syariah dengan kas berbunga koperasi konvensional melanggar fatwa DSN-MUI dan PSAK 102/106.
  2. Risiko Pidana Penyalahgunaan Dana Desa: Menggabungkan alokasi mandatori minimal 20% Dana Desa untuk Ketahanan Pangan ke dalam kas komersial spekulatif berisiko memicu temuan audit investigatif Inspektorat dan BPKP.

Oleh karena itu, sistem ERP mengimplementasikan dua arsitektur pemisahan:

  • Dual-Track Enterprise Architecture: Pemisahan jalur bisnis komersial bebas (Profit Center) vs jalur ketahanan pangan sirkular (Impact & Buffer Center) pada sektor pertanian dan peternakan.
  • Dual-Banking Architecture: Pemisahan dua lembaga keuangan mikro desa mandiri (USP Konvensional vs USPPS Syariah) dengan brankas, COA, dan sistem bagi hasil independen.
Memuat diagram alur...

2. Pilar I: Dual-Track Enterprise Architecture (Pertanian & Peternakan)#

A. Matriks Komparasi Karakteristik

Parameter TeknisJalur Komersial RegulerJalur Ketahanan Pangan (Ketapang)
Identitas UnitAGRO-IND (Pertanian Utama), BIO-LIV (Peternakan)KTPG-TANI (Padi/Jagung), KTPG-PAKAN (Feedmill), KTPG-PTR (Ayam)
Level Hirarki (HDM)Tier 1A (Langsung Holding)Tier 2A/2B di bawah Tier 1B Sub-Holding
Tujuan FinansialMemaksimalkan laba bersih komersialMenstabilkan pasokan pangan desa & efisiensi pakan ternak
Mandat PermodalanModal Umum BUMDesMinimal 20% Dana Desa (Akun Ekuitas 3-101.03)
Akun Kas & BankKas Operasional (1-101.01) / Bank Giro (1-102.01)Brankas Kas Ketapang (1-101.03) / Rekening BPD Ketapang (1-102.03)
Formula Transfer StokHarga = HPP + Laba (Jual Beli Komersial)Transfer Price = HPP Riil (At-Cost Transfer)
Pencatatan Laba InternalDiakui sebagai pendapatan penjualanDitiadakan (0% internal profit), dieliminasi akun 9-999

B. Multi-Tenant Unit Routing & Context Isolation

Aplikasi mengidentifikasi konteks unit melalui unit_id yang tersimpan pada sesi pengguna dan disuntikkan ke dalam query basis data:

typescript
// lib/context/unit-context.tsx
export interface ActiveUnitContext {
 id: string;
 code: string; // 'AGRO-IND' vs 'KTPG-TANI'
 name: string;
 businessType: BusinessType; // 'agriculture' vs 'food_security'
 tierLevel: number; // 1: Holding Direct, 2: Sub-Holding
 parentUnitId: string | null;
 bankAccountId: string; // Terkunci ke 1-102.01 vs 1-102.03
}

Row Level Security (RLS) Database Rule:

sql
-- Isolasi tabel operasional pertanian komersial vs ketapang
CREATE POLICY "isolate_agri_records_by_unit" ON agri_crop_cycles
FOR ALL USING (
 unit_id = auth.user_assigned_unit_id() OR
 auth.is_super_admin()
);

C. Two-Track Pricing Engine (Komersial vs At-Cost Sirkular)

Sistem menerapkan algoritma harga dinamis pada modul transfer inventori:

typescript
// lib/actions/inventory-transfer.ts
export async function calculateTransferValuation(
 productId: string,
 sourceUnitCode: string,
 targetUnitCode: string,
 quantity: number
): Promise<{ unitPrice: number; totalValuation: number; isAtCost: boolean }> {
 const isInternalKetapangTransfer = 
 sourceUnitCode.startsWith('KTPG-') && targetUnitCode.startsWith('KTPG-');

 const cogs = await getMovingAverageCogs(productId, sourceUnitCode);

 if (isInternalKetapangTransfer) {
 // TRACK B: Transfer jagung ke pabrik pakan Ketapang -> HPP Riil (Rp 0 Margin)
 return {
 unitPrice: cogs,
 totalValuation: cogs * quantity,
 isAtCost: true
 };
 } else {
 // TRACK A: Penjualan dari AGRO-IND ke pihak luar -> Market Price
 const marketPrice = await getProductSellingPrice(productId);
 return {
 unitPrice: marketPrice,
 totalValuation: marketPrice * quantity,
 isAtCost: false
 };
 }
}

D. Decoupled Treasury & Proteksi 20% Dana Desa

Untuk mencegah kebocoran anggaran Dana Desa Ketapang ke unit komersial:

  1. Server Action Guard: Fungsi transaksi kas menolak instruksi penarikan kas jika unit asal berstatus komersial (AGRO-IND, BIO-LIV, TKRTL-01) namun menunjuk akun kas bank Ketapang (1-102.03).
  2. Trigger Database:
sql
CREATE OR REPLACE FUNCTION enforce_ketapang_treasury_isolation()
RETURNS TRIGGER AS **BEGIN IF NEW.credit_account_id = '1-102.03' AND NEW.unit_id NOT IN ( SELECT id FROM business_units WHERE code LIKE 'KTPG-%' OR code = 'SUB-KTPG' ) THEN RAISE EXCEPTION 'Pelanggaran Kepatuhan: Rekening Bank 1-102.03 terikat 20%% Dana Desa dan hanya boleh digunakan oleh Unit Ketapang.'; END IF; RETURN NEW; END;** LANGUAGE plpgsql;

3. Pilar II: Dual-Banking Architecture (Simpan Pinjam USP & USPPS)#

A. Pemisahan Rezim Kepatuhan & Entitas Mandiri

Sistem mengoperasikan dua entitas mandiri yang beroperasi berdampingan di bawah BUMDes:

  1. Unit Simpan Pinjam Konvensional (USP-01):
  • Landasan Hukum: UU Koperasi No. 25/1992.
  • Model: Simpan pinjam anggota dengan suku bunga jasa wajar koperasi.
  • Akun Kas: 1-101.01 (Kas Tunai - Unit Simpan Pinjam).
  • Akun Piutang: 1-112 (Piutang Simpan Pinjam (USP Loan)).
  • Akun Pendapatan: 4-601 (Pendapatan Bunga Pinjaman USP).
  • Akun Denda: 4-403 (Pendapatan Denda Keterlambatan USP).
  • Akun Rekening Koran: 1-605 (RK Unit Simpan Pinjam).
  1. Unit Simpan Pinjam Syariah / USPPS (USP-SYR):
  • Landasan Hukum: DSN-MUI, PSAK 102 (Murabahah), PSAK 106 (Musyarakah).
  • Model: 0% Riba, menggunakan akad Wadiah, Murabahah, dan Musyarakah bagi hasil.
  • Akun Kas: 1-101.13 (Kas Tunai - Simpan Pinjam Syariah) & 1-102 (Rekening Bank BRI - BUMDes Holding).
  • Akun Piutang: 1-113 (Piutang Pembiayaan Murabahah (USPPS)).
  • Akun Pendapatan Margin: 4-201 (Pendapatan Margin Pembiayaan).
  • Akun Denda Ta'zir: 2-103 (Titipan Dana Sosial / CSR - Kewajiban Kebajikan, Bukan Laba).
  • Akun Rekening Koran: 1-805 (RK Unit Simpan Pinjam Syariah).

B. Skema Database & Isolasi Tabel

Tabel-tabel utama simpan pinjam menyimpan unit_id untuk menegakkan isolasi:

sql
-- Tabel Kontrak Pembiayaan / Pinjaman
CREATE TABLE usp_loans (
 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
 unit_id UUID NOT NULL REFERENCES business_units(id),
 member_id UUID NOT NULL REFERENCES usp_members(id),
 loan_number VARCHAR(50) UNIQUE NOT NULL,
 contract_type VARCHAR(30) NOT NULL, -- 'conventional', 'murabahah', 'musyarakah', 'wadiah'
 principal_amount NUMERIC(15,2) NOT NULL,
 margin_or_interest_rate NUMERIC(5,2) NOT NULL,
 total_repayment_amount NUMERIC(15,2) NOT NULL,
 tenor_months INT NOT NULL,
 is_yarnen BOOLEAN DEFAULT FALSE,
 yarnen_harvest_date DATE,
 land_polygon_id UUID REFERENCES agri_lands(id),
 collectibility_status INT DEFAULT 1, -- Kol 1 (Lancar) s/d Kol 5 (Macet)
 created_at TIMESTAMPTZ DEFAULT NOW()
);

C. Logika Perhitungan Pembiayaan (Loan Calculation Engine)

typescript
// lib/actions/loan-calculator.ts
export function calculateLoanSchedule(
 type: 'conventional' | 'murabahah' | 'musyarakah',
 principal: number,
 ratePercent: number,
 tenorMonths: number,
 isYarnen: boolean
) {
 if (isYarnen) {
 // SKEMA YARNEN: Pokok & Imbal Hasil Ditangguhkan hingga Masa Panen
 const feeAmount = principal * (ratePercent / 100);
 return {
 monthlyPayment: 0,
 bulletPaymentOnHarvest: principal + feeAmount,
 principalPortion: principal,
 profitPortion: feeAmount,
 tenorDays: tenorMonths * 30
 };
 }

 if (type === 'conventional') {
 // KONVENSIONAL: Bunga Flat / Anuitas
 const interestTotal = principal * (ratePercent / 100) * (tenorMonths / 12);
 const monthlyInterest = interestTotal / tenorMonths;
 const monthlyPrincipal = principal / tenorMonths;
 return {
 monthlyPayment: monthlyPrincipal + monthlyInterest,
 totalInterest: interestTotal,
 revenueAccountId: '4-601' // Pendapatan Bunga Pinjaman
 };
 } else {
 // SYARIAH MURABAHAH: Margin Jual-Beli Terikat Akad
 const totalMargin = principal * (ratePercent / 100);
 const monthlyMargin = totalMargin / tenorMonths;
 const monthlyPrincipal = principal / tenorMonths;
 return {
 monthlyPayment: monthlyPrincipal + monthlyMargin,
 totalMargin: totalMargin,
 deferredMarginAccountId: '2-205', // Margin Murabahah Tangguhan
 revenueAccountId: '4-201' // Pendapatan Margin Murabahah (USPPS)
 };
 }
}

D. Logika Pemrograman Modal Tani "Yarnen" (Bayar Panen)

Skema Yarnen mengintegrasikan Simpan Pinjam dengan Sub-Holding Ketapang dalam rantai pasok tertutup (closed-loop):

Memuat diagram alur...

SQL Stored Procedure Auto-Offset Yarnen:

sql
CREATE OR REPLACE FUNCTION auto_offset_yarnen_loan(
 p_loan_id UUID,
 p_harvest_payout NUMERIC(15,2),
 p_operator_id UUID
) RETURNS JSONB AS **DECLARE v_loan RECORD; v_remaining_debt NUMERIC(15,2); v_surplus NUMERIC(15,2); BEGIN SELECT * INTO v_loan FROM usp_loans WHERE id = p_loan_id FOR UPDATE; IF NOT FOUND THEN RAISE EXCEPTION 'Kontrak pinjaman Yarnen tidak ditemukan.'; END IF; v_remaining_debt := v_loan.total_repayment_amount; IF p_harvest_payout >= v_remaining_debt THEN v_surplus := p_harvest_payout - v_remaining_debt; -- 1. Lunasi Pinjaman UPDATE usp_loans SET collectibility_status = 1, status = 'settled', settled_at = NOW() WHERE id = p_loan_id; -- 2. Tambahkan surplus ke Tabungan Anggota UPDATE usp_members SET vol_savings_balance = vol_savings_balance + v_surplus WHERE id = v_loan.member_id; -- 3. Catat Mutasi Tabungan INSERT INTO usp_member_savings (member_id, amount, type, notes) VALUES (v_loan.member_id, v_surplus, 'deposit', 'Sisa lebih panen Yarnen BASTK'); RETURN jsonb_build_object( 'status', 'fully_settled', 'debt_cleared', v_remaining_debt, 'surplus_credited', v_surplus ); ELSE -- Panen di bawah nilai utang -> Restrukturisasi Parsial UPDATE usp_loans SET total_repayment_amount = total_repayment_amount - p_harvest_payout WHERE id = p_loan_id; RETURN jsonb_build_object( 'status', 'partially_settled', 'paid_amount', p_harvest_payout, 'remaining_balance', v_remaining_debt - p_harvest_payout ); END IF; END;** LANGUAGE plpgsql;

E. Penegakan Anti-Commingling Kas & Distribusi SHU Mandiri

  1. Isolasi Rekening Kas:
  • Kasir atau teller simpan pinjam dilarang melakukan transfer langsung (direct fund transfer) antara akun 1-101.01 (USP Konvensional) dan 1-101.13 (USPPS Syariah).
  • Segala bentuk pemindahan dana antar-unit wajib melalui rekening koran timbal balik atau izin persetujuan Super Admin dengan Berita Acara resmi.
  1. Distribusi SHU Mandiri:
  • Anggota Konvensional: Menerima SHU berdasarkan persentase Simpanan Pokok/Wajib dan volume bunga pinjaman yang dibayarkan selama tahun buku berjalan.
  • Anggota Syariah: Menerima bagi hasil tabungan mudharabah dan bonus wadiah sesuai nisbah riil, tanpa pembagian jasa bunga.

4. Mekanisme Konsolidasi & Auto-Eliminasi Level Holding#

Pada saat proses konsolidasi laporan keuangan BUMDes (Level 0 Holding):

Memuat diagram alur...

5. Diagram Alur Data & Interaksi Sistem#

Arsitektur relasional data antar-modul:

text
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ agri_lands (GIS) │ │ business_units (Core) │
│ • id │ │ • id │
│ • polygon_coordinates │ │ • code (AGRO-IND / KTPG) │
│ • owner_resident_nik │ │ • business_type │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
 │ │
 │ 1:N │ 1:N
 ā–¼ ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ usp_loans (Finansial) │◄────────┤ usp_members (Warga) │
│ • is_yarnen: boolean │ │ • nik │
│ • contract_type │ │ • credit_score │
│ • total_repayment_amount │ │ • vol_savings_balance │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
 │
 │ auto-offset on harvest
 ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ feed_production_batches │────────►│ journal_entries │
│ • batch_number (Mix-18) │ │ • unit_id │
│ • corn_intake_kg │ │ • is_eliminated (9-999) │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

6. Panduan Pengembang & Testing Suite#

A. Checklist Pengembang (Developer Rules)

  1. Saat Menambah Unit Bisnis Baru:
  • Tentukan apakah unit tergolong Komersial Holding (Tier 1A) atau Binaan Ketapang (Tier 2A/2B).
  • Daftarkan pasangan akun Rekening Koran pada lib/constants/global-account-mappings.ts.
  1. Saat Menulis Server Action Transaksi Kas:
  • Selalu gunakan safeMoney() integer cents untuk kalkulasi matematis.
  • Pastikan validasi unit-context mencegah mutasi silang akun 1-102.03 (BPD Ketapang).
  1. Saat Menulis Query Simpan Pinjam:
  • Sertakan parameter unit_id secara eksplisit (USP-01 vs USP-SYR).
  • Jangan gunakan perhitungan bunga majemuk (compound interest) pada pembiayaan syariah.

B. Automated Testing Checklist (Jest & Vitest)

Test SuiteTarget ValidasiStatus
test/dual-track-pricing.test.tsValidasi harga transfer internal Ketapang = HPP riil (at-cost).āœ… Passed
test/treasury-isolation.test.tsPencegahan penarikan rekening 1-102.03 oleh unit komersial.āœ… Passed
test/sharia-calculation.test.tsUji formula Murabahah & Musyarakah (0% Riba, margin tetap).āœ… Passed
test/yarnen-offset-rpc.test.tsUji eksekusi RPC auto_offset_yarnen_loan (pelunasan & kredit tabungan).āœ… Passed
test/consolidation-elimination.test.tsKeseimbangan neraca konsolidasi pasca-eliminasi timbal balik 9-999.āœ… Passed

Dokumen ini merupakan bagian dari BUMDes Bolulango Engineering & Architecture Standard. Disahkan oleh Tim Arsitektur Sistem ERP & Dewan Pengawas BUMDes Bolulango.

Apakah panduan ini membantu Anda?

Bacaan Selanjutnya