11 — Konsep Navigasi ERP Mobile/Tablet¶
1. Latar Belakang¶
Sistem lama menggunakan tiga tabel Delphi untuk navigasi:
| Tabel | Baris | Masalah |
|---|---|---|
menu |
125 | Terikat imageindex DevExpress, actionname form Delphi |
menutemplate |
608 | Template per tipe operator Delphi |
aksesmenu |
— | Hak akses per namauser (username Delphi, bukan Firebase UID) |
Semua kolom Delphi-spesifik (imageindex, helpkeyword, helpcontext, actionname) tidak relevan
untuk Flutter atau Web. Ketiga tabel ini diklasifikasikan SKIP_ARSIP — tidak dimigrasi.
2. Desain Baru¶
2.1 Prinsip¶
- API-driven: klien Flutter/Web memanggil
GET /modul/sayasetiap login, bukan hardcode - Metadata-driven: ubah 1 baris di
pusat.modul→ semua klien ikut - 3 lapis hak akses: peran default → override tenant → override pengguna individual
2.2 Hierarki Navigasi (3 Level)¶
Grup (level 1) → Modul (level 2) → Detail/Form (level 3, klien)
──────────────────────────────────────────────────────────────────────────
DASHBOARD → Ringkasan & Dashboard
TRANSAKSI → Pembelian (PB)
→ Penjualan (PJ)
→ Retur Pembelian (RB)
→ Retur Penjualan (RJ)
→ Transfer Stok (PL)
→ Opname Stok (OS)
KEUANGAN → Kas Keluar (KK)
→ Kas Masuk (KM)
→ Pelunasan Piutang (PP)
→ Pelunasan Hutang (PH)
→ Aset & Penyusutan (DA)
→ Jurnal Umum (JU)
MASTER → Master Barang
→ Master Kontak
→ Bagan Akun (CoA)
→ Lokasi & Cabang
→ Daftar Harga
LAPORAN → Laporan Stok & Persediaan
→ Laporan Penjualan
→ Laporan Keuangan
→ Laporan Piutang & Hutang
→ Buku Besar & Jurnal
PENGATURAN → Pengguna & Peran
→ Pengaturan Tenant
2.3 Skema Database¶
Semua tabel berada di schema pusat (global, tidak per-tenant):
-- Katalog modul ERP
pusat.modul (id, kode, nama, grup, urut, ikon, jenis_transaksi_kode, is_aktif)
-- Hak akses default per peran
pusat.peran_modul (peran, modul_id)
-- Override per tenant: nonaktifkan modul tertentu
pusat.tenant_modul (tenant_kode, modul_id, is_aktif)
-- Override per pengguna individual: GRANT atau REVOKE
pusat.pengguna_modul (pengguna_id, tenant_kode, modul_id, izin)
Kolom ikon berisi nama Material Icons Flutter (mis. shopping_cart, point_of_sale) — bukan
indeks DevExpress.
Kolom jenis_transaksi_kode adalah FK logis ke jenis_transaksi di schema tenant. Tidak
dideklarasikan FK database karena lintas schema.
2.4 Peran Standar & Hak Akses Default¶
| Peran | Modul |
|---|---|
admin |
Semua 25 modul |
kasir |
Transaksi + Kas + Master Barang/Kontak/Harga + Laporan Stok & Penjualan (16 modul) |
akunting |
Keuangan + Jurnal + Master Akun/Kontak + Semua Laporan (14 modul) |
viewer |
Dashboard + Semua Laporan (6 modul) |
3. API Endpoint¶
GET /modul/saya¶
Prasyarat: JWT dengan tenant_kode dan peran (token setelah POST /tenants/:kode/pilih).
Logika resolusi (3 lapis):
1. Ambil modul default berdasarkan peran dari pusat.peran_modul
2. Kurangi modul yang dinonaktifkan di pusat.tenant_modul untuk tenant ini
3. Terapkan override individu dari pusat.pengguna_modul: GRANT tambah, REVOKE kurangi
Response:
[
{
"grup": "TRANSAKSI",
"modul": [
{ "kode": "PEMBELIAN", "nama": "Pembelian", "ikon": "shopping_bag", "jenis_transaksi_kode": "PB" },
{ "kode": "PENJUALAN", "nama": "Penjualan", "ikon": "point_of_sale", "jenis_transaksi_kode": "PJ" }
]
},
...
]
4. Panduan Integrasi Flutter¶
// Panggil setelah pilih tenant, simpan di state/provider
final response = await api.get('/modul/saya');
final List<ModulGrup> menu = (response.data as List)
.map((g) => ModulGrup.fromJson(g))
.toList();
// Render bottom nav atau drawer berdasarkan grup
// Tiap item modul memiliki kode untuk routing ke screen yang sesuai
Klien tidak perlu hardcode daftar menu. Jika modul ditambah di pusat.modul, klien otomatis
menampilkannya saat API dipanggil ulang.
5. Mengelola Hak Akses¶
Override per tenant (nonaktifkan modul)¶
-- Tenant 'leontech' tidak menggunakan modul Aset
INSERT INTO pusat.tenant_modul (tenant_kode, modul_id, is_aktif)
SELECT 'leontech', id, false FROM pusat.modul WHERE kode = 'ASET_PENYUSUTAN';
Override per pengguna individual¶
-- Berikan akses Laporan Keuangan ke kasir tertentu
INSERT INTO pusat.pengguna_modul (pengguna_id, tenant_kode, modul_id, izin)
SELECT 5, 'sparepart', id, 'GRANT' FROM pusat.modul WHERE kode = 'LAPORAN_KEUANGAN';
-- Cabut akses Transfer Stok dari kasir tertentu
INSERT INTO pusat.pengguna_modul (pengguna_id, tenant_kode, modul_id, izin)
SELECT 7, 'sparepart', id, 'REVOKE' FROM pusat.modul WHERE kode = 'TRANSFER_STOK';
6. File Terkait¶
| File | Keterangan |
|---|---|
database/ddl/05_schema_modul.sql |
DDL 4 tabel + COMMENT ON + GRANT |
database/seeds/01_seed_modul.sql |
25 modul + 61 mapping peran-modul |
backend/src/modul/modul.module.ts |
NestJS module |
backend/src/modul/modul.controller.ts |
GET /modul/saya |
backend/src/modul/modul.service.ts |
Query 3-lapis hak akses |
backend/src/modul/dto/modul.dto.ts |
DTO Swagger |
frontend/flutter/erp/NAVIGASI.md |
Implementasi navigasi Flutter: shell structure, named routes, state |