← Portal SIPASI R&D · Dokumentasi Teknis Modul

DOKUMENTASI TEKNIS PEMETAAN MODUL SKEMA JARINGAN IRIGASI (SIPASI)

Kode Menu: `/cms/37/` & `/cms/38/` Model Utama: `App\Models\Sipasi\Mdl_skema_jaringan.php` Dokumen Referensi: Riset Onboarding & Refactoring Arsitektur Sistem Tanggal: 26 Agustus 2026 ---

DAFTAR ISI

---

1. Ringkasan Eksekutif & Ruang Lingkup

Modul Skema Jaringan adalah inti (*core engine*) visual dan kalkulasi spasial-topologis dalam sistem SIPASI (Sistem Informasi Pengelolaan Air dan Skema Irigasi). Modul ini bertanggung jawab atas:

Ruang Lingkup Komponen

+-------------------------------------------------------------------------------+
|                             SISTEM SIPASI                                     |
+------------------------------------+------------------------------------------+
|  CMS AUTHORING & ROUTING           |  CORE SPATIAL & HYDRAULIC ENGINE         |
|  - Cms.php (Controller)            |  - Mdl_skema_jaringan.php (Model/Logic)  |
|  - CmsContent.php (Dynamic Loader) |  - Mdl_musim_tanam.php (Profil Petak/KAS)|
|  - cms_navigation (Table nav id 37)|  - dts_skema_jaringan (Graph Storage)    |
+------------------------------------+------------------------------------------+
|  FRONTEND CANVAS & MODULES         |  DATABASE RELATIONS                      |
|  - Membuat_skema.php (Editor SVG)  |  - dts_bangunan_irigasi                  |
|  - Skema_pelaksanaan.php (Ops View)|  - dts_petak_tersier                     |
|  - assets/js/skema/* (Modular JS)  |  - dts_ruas_saluran                      |
|  - GSAP Draggable + jQuery UI      |  - dd_giliran, dd_debit_ruas_harian      |
+------------------------------------+------------------------------------------+
---

2. Rantai Eksekusi & Mekanisme Routing CMS

Sistem navigasi SIPASI menggunakan arsitektur *Dynamic Database-Driven Content Dispatching*. Ketika user mengakses URL `/cms/37/`, berikut rantai eksekusi lengkapnya:
[User Browser]
       |  GET /cms/37/
       v
[Config/Routes.php] ---> $routes->add('/cms/(:any)', 'Cms::index/');
       |
       v
[Controllers/Cms.php::index()]
       |
       +---> head_navigation()  (Render menu navbar)
       +---> body_content()     (Menentukan isi konten utama)
                |
                |-- urinext('cms') == 'mdl'? TIDAK ('37')
                |-- urinext('cms') == 'sip'? TIDAK ('37')
                v
       [Models/Cms/CmsContent.php::home()]
                |
                |-- Query `cms_navigation` WHERE id = '37'
                |   Row: {
                |     id: 37,
                |     title: 'Skema Jaringan',
                |     view_mode: 'model',
                |     val: 'Sipasi\\Mdl_skema_jaringan(membuat)'
}
v [Parsing cms_navigation.val] |-- explode('(', 'Sipasi\Mdl_skema_jaringan(membuat)') | - $arrMdl[0] = 'Sipasi\Mdl_skema_jaringan' | - $arrMdl[1] = 'membuat)' |-- $mdl = model('App\Models\' . $arrMdl[0]); |-- $fnc = substr($arrMdl[1], 0, -1) ==> 'membuat' v [$mdl->membuat()] (Mengeksekusi Mdl_skema_jaringan::membuat()) | v [Render View: Sipasi/Membuat_skema.php]

Penjelasan Parsing `cms_navigation.val`

Pada file `app_sipasi/Models/Cms/CmsContent.php` baris 165–177, terdapat logika parsing:
php
if ($viewMode == 'model') {
    $data = 'models/'.$proNav['val'];
    $arrMdl = explode('(', $proNav['val']);
    $mdl = model('App\Models\\'.$arrMdl[0]);
    if (!empty($arrMdl[1])) {
        $fnc = substr($arrMdl[1], 0, -1); // memotong karakter ')' terakhir
        $data = $mdl->{$fnc}();          // memanggil method dinamis, misal: membuat()
    } else {
        $data = $mdl->home();
    }
    return $data;
}

Jalur Routing Alternatif (AJAX / Direct Action)

Selain melalui ID menu CMS (`/cms/37/`), seluruh aksi AJAX dari frontend dialihkan melalui rute internal:
php
  else if (urinext('cms') == 'sip') {
      $mdl = model('App\Models\Sipasi\Mdl_'.urinext('sip')); // Mdl_skema_jaringan
      $data = $mdl->home();
  }
  
---

3. Pemetaan Lengkap Method Mdl_skema_jaringan.php

File `app_sipasi/Models/Sipasi/Mdl_skema_jaringan.php` terdiri dari 1376 baris kode dengan total 17 method. Berikut adalah tabel matriks pemetaan lengkap:

Tabel Referensi Method

NoNama MethodVisibilitasTrigger / RouteInput ParameterOutput / ReturnTabel DB yang Disentuh (CRUD)
1`__construct()``public`Instansiasi ModelSesi CI4, Environment `id_di`Instance Object`dd_pt_profil` (R via `polatanam()`)
2`home()``public``/cms/sip/skema_jaringan/``urinext('skema_jaringan')`Hasil delegasi methodTergantung sub-method
3`simpan_giliran()``public`AJAX POST `/cms/sip/skema_jaringan/simpan_giliran``id`, `nama_giliran`, `total_durasi`, `jumlah_giliran`, `faktor_k`, `waktu_mulai`, `data_json`JSON `{valid, id, message/error}``dd_giliran` (C/U)
4`get_list_giliran()``public`AJAX GET/POST `/cms/sip/skema_jaringan/get_list_giliran`Tidak adaJSON `{valid: 1, data: [...]}``dd_giliran` (R)
5`jalankan_giliran()``public`AJAX POST `/cms/sip/skema_jaringan/jalankan_giliran``id` (ID giliran)JSON `{valid, message/error}``dd_giliran` (U), `dts_petak_tersier` (U)
6`get_rotation_status()``public`AJAX GET/POST `/cms/sip/skema_jaringan/get_rotation_status`Tidak adaJSON `{active, nama, current_turn, total_turns, time_remaining, debug}``dd_giliran` (R)
7`_find_active_rotation()``private`Internal helper di `pembagian()` & `get_rotation_status()`Tidak adaArray status rotasi / `null``dd_giliran` (R)
8`polatanam()``public`Dipanggil di `__construct()`Tidak adaString ID Pola Tanam Aktif`dd_pt_profil` (R)
9`membuat()``public`Nav `/cms/37/` atau `/cms/52/` atau `/cms/sip/skema_jaringan/membuat``urinext('name')` (default: `'default'`)HTML string render view `Sipasi/Membuat_skema``dts_pengaturan` (R), `dts_skema_jaringan` (R), `dts_bangunan_irigasi` (R), `dts_petak_tersier` (R)
10`pelaksanaan()``public`Nav `/cms/38/` atau `/cms/53/` atau `/cms/sip/skema_jaringan/pelaksanaan``urinext('name')`HTML string render view `Sipasi/Skema_pelaksanaan``dts_pengaturan` (R), `dts_bangunan_irigasi` (R), `dts_petak_tersier` (R), `dts_saluran_irigasi` (R), `dd_debit_alokasi` (R), `dd_debit_sumber_harian` (R), `dd_debit_real_ruas` (R), `dd_pt_profil` (R via Mdl)
11`skema_publik()``public``/page/skema` via `Controllers/Home.php``urinext('name')` (default: `'sapon'`)HTML string view `Sipasi/Skema_pelaksanaan``dts_bangunan_irigasi` (R), `dts_petak_tersier` (R), `dd_debit_alokasi` (R), `dd_debit_sumber_harian` (R), `dd_debit_real_ruas` (R)
12`pembagian()``public`AJAX GET/POST `/cms/sip/skema_jaringan/pembagian`, Controller `Apk::pembagian()`, `Iopost::recFaktorK()``$_REQUEST['name']`, `$_REQUEST['apk']`, `urinext('faktork')`JSON `{valid, bangunan, textTitle, faktor_k, rotation_debug}``dts_pengaturan` (R), `dts_skema_jaringan` (R), `dts_bangunan_irigasi` (R), `dts_saluran_irigasi` (R), `dts_petak_tersier` (R/U), `dd_giliran` (R), `dts_ruas_saluran` (R), `dd_debit_sumber_harian` (R/U), `dd_debit_alokasi` (R), `dd_debit_sumber_panca` (C/U)
13`kebutuhan_air()``public`Internal helper dipanggil oleh `pembagian()`Instance properties (`$this->bangunan`, `$this->bgOnLevel`, `$this->maxz`)Void (mengupdate `$this->bangunan` secara in-memory)`dts_ruas_saluran` (R), `dd_debit_sumber_harian` (R/U), `dd_debit_alokasi` (R), `dts_petak_tersier` (U), `dd_debit_sumber_panca` (C/U)
14`simpan()``public`AJAX POST `/cms/sip/skema_jaringan/simpan/[nama]``$_POST['nama']`, `$_POST['skema']`, `$_POST['intake']`JSON echoing POST input`dts_skema_jaringan` (C/U)
15`debit_ruas_harian()``public`AJAX `/cms/sip/skema_jaringan/debit_ruas_harian`, Controller `Iopost::recDebitRuas()``$_REQUEST['name']` (default: `'tabotabo'`)JSON `{valid: 1, bangunan}``dts_bangunan_irigasi` (R), `dts_saluran_irigasi` (R), `dts_petak_tersier` (R), `dts_skema_jaringan` (R)
16`posting_kebutuhan_air()``public`Internal helper dipanggil oleh `debit_ruas_harian()`Instance propertiesText / Exit`dts_ruas_saluran` (R), `dd_debit_real_ruas` (R/U), `dd_debit_sumber_harian` (R), `dd_debit_ruas_harian` (C/U)
17`set_routing()``public`AJAX POST `/cms/sip/skema_jaringan/set_routing``$_POST['dataRouting']`, `$_POST['intake']`Text delimited string `cekdata``dts_petak_tersier` (U), `dts_ruas_saluran` (C/U), `dts_bangunan_irigasi` (R)
---

4. Arsitektur View, Canvas SVG & Library Frontend

Struktur antarmuka skema jaringan terbagi menjadi dua view utama:
+------------------------------------------------------------------------------------+
| PANEL EDITOR SKEMA (Membuat_skema.php)                                             |
+----------------------+-------------------------------------------------------------+
| SIDEBAR KIRI (200px) | AREA KANVAS UTAMA (SVG ViewBox: 0 0 9600 9600)              |
| - Tombol [+] Text    |                                                             |
| - Palet Bangunan:    |   [B.Pengambil (bpm)]                                       |
|   * bpm, bin, bsp    |          |                                                  |
|   * bba, bbs, bsa    |          v (saluran line/path)                              |
| - Search & Link DB:  |   [B.Intake (bin)]                                          |
|   * Bangunan (BB)    |          |                                                  |
|   * Petak (PT)       |          v                                                  |
| - Tombol [Simpan]    |   [B.Bagi 1 (bba)] ------> [Petak Tersier 1 (ter)]          |
| - Tombol [Set Intake]|          |                                                  |
|                      |          v                                                  |
|                      |   [B.Bagi 2 (bba)] ------> [Petak Tersier 2 (ter)]          |
+----------------------+-------------------------------------------------------------+
| TOOL FLOATING BOXES:                                                               |
| #opsibox (Pilih tipe) | #actionbox (Link, Hapus, Add Petak) | #actionboxSaluran    |
+------------------------------------------------------------------------------------+

A. Library Frontend & Peranannya

B. Struktur Simbol Bangunan Irigasi (SVG)

Kode Tipe (`bb`)Nama BangunanElemen SVG RepresentasiKeterangan & Karakteristik
`bpm`Bangunan Pengambil / Bendung``Titik awal sumber air (warna biru muda `#66ccff`)
`bin`Bangunan Intake / Pengambilan``Titik awal pengukuran debit sistem (putih belah ketupat)
`bsp`Bangunan Suplesi``Intake tambahan dari suplesi luar
`bba`Bangunan Bagi``Lingkaran konsentris tanpa isi solid
`bbs`Bangunan Bagi-Sadap``Lingkaran konsentris dengan titik tengah berongga
`bsa`Bangunan Sadap``Lingkaran konsentris dengan titik tengah solid (`#334455`)
`ter`Petak Tersier``Kotak persegi panjang warna hijau pastel (`#bbffee`)

C. Arsitektur Modular JavaScript (`assets/js/skema/` & `Xskema_modules/`)

Pada versi `Skema_pelaksanaan.php` yang telah direfaktor, kode JavaScript dipisahkan menjadi 8 modul fungsional: ---

5. Skema Data, Topologi Graf & Relasi Database

A. Entity-Relationship Diagram (ERD) Topologi Jaringan

 +------------------------+             +------------------------+
 |   dts_skema_jaringan   |             |   dts_saluran_irigasi  |
 +------------------------+             +------------------------+
 | PK  id                 |             | PK  id                 |
 |     kode_di            |             |     nama_saluran       |
 |     nama               |             |     jenis_saluran      |
 |     data_skema [TEXT]  |             |     total_kehilangan   |
 |     intake             |             +-----------+------------+
 +------------------------+                         |
1
N
+------------------------+ 1 N +-----------v------------+ | dts_bangunan_irigasi +-------------+ dts_ruas_saluran | +------------------------+ (dari/menuju+------------------------+ | PK id | | PK id | | kode_di | | id_ruas (b1xb2) | | nomenklature | | FK dari (id_bg) | | nama_saluran | | FK menuju (id_bg/pt) | | jenis_saluran | | bg_tujuan | | tipe_bangunan | | losses (persen) | | skema_x, skema_y | | listing | +-----------+------------+ +-----------+------------+ | |
1 (sumber)1:1
N v
+-----------v------------+ +------------------------+ | dts_petak_tersier | | dd_debit_ruas_harian | +------------------------+ +------------------------+ | PK id | | PK id | | nama_sadap | | id_data(b1xb2_Wed) | | bangunan_sumber | | FK id_ruas | | luas | | debit_kebutuhan | | kebutuhan_air | | faktor_k | | faktor_k | | debit_perintah | | debit_perintah | | debit_real | | giliran (int) | +------------------------+ | pos_x, pos_y | +-----------+------------+ | | N | (data_petak JSON) v +------------------------+ | dd_giliran | +------------------------+ | PK id | | nama | | periode (hari) | | jumlah (giliran) | | waktu_mulai | | status (active/dis)| +------------------------+

B. Format Data Penyimpanan Skema (`dts_skema_jaringan.data_skema`)

Terdapat dua format yang didukung oleh Hybrid Parser pada sistem:

1. Format Modern (Standard JSON)

json
{
  "bangunan": [
    {
      "id": 0,
      "bb": "bpm",
      "name": "bpengambil_0",
      "x": 1120,
      "y": 620,
      "sumber": [],
      "goto": [1],
      "link": 1,
      "nomen": "BD.OR",
      "z": 1
    },
    {
      "id": 1,
      "bb": "bba",
      "name": "bangunan_1",
      "x": 1260,
      "y": 620,
      "sumber": [0],
      "goto": [2, 104],
      "link": 2,
      "nomen": "B.Or.1",
      "tx": 1190,
      "ty": 610,
      "z": 2
    },
    {
      "id": 104,
      "bb": "ter",
      "name": "petak_104",
      "x": 1840,
      "y": 660,
      "sumber": [1],
      "goto": [],
      "link": 1,
      "nomen": "B.Or.1 Ki",
      "z": 3
    }
  ],
  "textTitle": [
    {
      "id": 1,
      "x": 1100,
      "y": 580,
      "r": 0,
      "fz": 27,
      "text": "Saluran Induk Oransbari"
    }
  ]
}

2. Format Legacy (Custom JavaScript String Serialized)

Format ini disimpan langsung sebagai representasi assignment objek JS:
javascript
"bangunan[0]={id:'0',bb:'bpm',name:'bpengambil_0',x:'1120',y:'620',sumber:[],goto:[1]}; bangunan[1]={id:'1',bb:'bba',name:'bangunan_1',x:'1260',y:'620',sumber:[0],goto:[2,104],tx:'1190',ty:'610',z:'2',link:'2',nomen:'B.Or.1'}; bangunan[104]={sumber:[1],id:'104',bb:'ter',name:'petak_104',x:'1840',y:'660',link:'1',nomen:'B.Or.1 Ki',z:'3'}; textTitle[0]={id:'0',x:'1100',y:'580',r:'0',fz:'27'};"

C. Kolom Penting Spasial, Topologi & Nomenklatur

---

6. Alur Kerja Pengguna End-to-End (User Workflows)

Skenario A: Membuat Skema Jaringan Baru (Authoring Workflow)

[1. User Buka /cms/37/]
       |
       v
[2. Drop Objek Intake & Bangunan Bagi]
       |-- Klik palet kiri (bpm, bin, bba, bsa, dll.)
       |-- Drag ke posisi kanvas SVG (GSAP LiveSnap Grid 20px)
       v
[3. Hubungkan Saluran Antar Node]
       |-- Klik tombol Link [fa-link-simple] pada Bangunan Hulu
       |-- Tarik garis merah (#garis) dan klik Bangunan Hilir
       |-- Array `sumber` dan `goto` otomatis terisi di kedua objek
       v
[4. Koneksikan Node ke Database Master (Linking)]
       |-- Klik node bangunan di kanvas
       |-- Ketik nama di input "Bangunan Irigasi:" -> Pilih dari #palet_nomen
       |-- Property `link` = ID master dan label `nomen` otomatis terpasang
       v
[5. Hubungkan Petak Tersier]
       |-- Klik tombol Petak [fa-square] pada Bangunan Sadap/Bagi
       |-- Muncul kotak hijau pastel petak tersier
       |-- Ketik nama di "Petak Tersier:" -> Pilih dari #palet_petak
       v
[6. Generate Routing Topologi]
       |-- Klik node Intake -> Klik tombol "Set Intake"
       |-- JS menjalankan fungsi rekursif `rooting(id, level)`
       |-- Menghitung depth level `z` dari hulu ke hilir
       |-- AJAX POST `/cms/sip/skema_jaringan/set_routing`
       |-- Backend membuat/mengupdate record di tabel `dts_ruas_saluran`
       v
[7. Simpan Skema Jaringan]
       |-- Klik tombol "Simpan"
       |-- JS men-serialize objek `bangunan` & `textTitle`
       |-- AJAX POST `/cms/sip/skema_jaringan/simpan`
       |-- Tersimpan ke tabel `dts_skema_jaringan`

Skenario B: Eksekusi Alokasi Air & Perhitungan Real-Time (Operational Workflow)

[1. User Buka /cms/38/ (Skema Pelaksanaan)]
       |
       v
[2. Client-Side Init]
       |-- Load data dasar (BB, PT, RPT, Debit Real, Alokasi)
       |-- Panggil `SkemaDataService.fetchSkemaData()`
       v
[3. AJAX Request: GET /cms/sip/skema_jaringan/pembagian]
       |
       v
[4. Backend (Mdl_skema_jaringan::pembagian)]
       |-- Load `data_skema` dari `dts_skema_jaringan`
       |-- Parse JSON / Regex Archaic
       |-- Cek Rotasi Giliran Aktif via `_find_active_rotation()`
       |-- Ambil kebutuhan air petak (ttl_KAS) dari `Mdl_musim_tanam`
       |-- Kelompokkan node berdasarkan level z ($bgOnLevel[$z])
       |-- Jalankan `kebutuhan_air()`:
       |     * Iterasi mundur dari $maxz s/d 1 (Bottom-Up)
       |     * Akumulasi kebutuhan air + faktor kehilangan saluran (losses)
       |     * Akumulasi luas komoditas (padi, palawija, tebu, luas total)
       |-- Hitung rekomendasi Faktor K
       |-- Return JSON lengkap
       v
[5. Frontend SvgRenderer]
       |-- Render ulang seluruh node, garis saluran, dan label angka debit
       |-- Tampilkan nilai debit kebutuhan di setiap titik bagi
       |-- Update panel info DSS saat bangunan diklik
---

7. Logika Komputasi Hidrolika (Kebutuhan Air, Faktor K, & Giliran)

A. Algoritma Perambatan Kebutuhan Air *Bottom-Up*

Perhitungan kebutuhan air dilakukan dari petak tersier paling hilir merambat naik ke bangunan utama (Bendung/Intake) dengan memperhitungkan kehilangan air di setiap ruas saluran (*conveyance losses*).
Level Max (Z = 4) [Petak Tersier A] (KAS = 100 lt/dt)
                  [Petak Tersier B] (KAS = 150 lt/dt)
                         |
                         |  Losses Ruas Saluran = 5%
                         v
Level 3 (Z = 3)   [Bangunan Sadap 2]
                  Kebutuhan = (100 + 150) + Loss = 250 + (250 / (100 - 5) * 5) = 263.15 lt/dt
                         |
                         |  Losses Ruas Saluran = 2.5%
                         v
Level 2 (Z = 2)   [Bangunan Bagi 1]
                  Kebutuhan = Kebutuhan B.Sadap 2 + Cabang Lain + Loss
                         |
                         v
Level 1 (Z = 1)   [Bangunan Intake / Pengambil]
                  Total Kebutuhan Sistem = Σ Kebutuhan Seluruh Jaringan

Rumus Hidrolika di `kebutuhan_air()`:

Untuk setiap cabang tujuan ($idbg \in goto$): $$\text{Losses} = lossesSaluran[idRuas]$$ $$Q_{bangunan} = Q_{tujuan} + \left( \frac{Q_{tujuan}}{100 - \text{Losses}} \times \text{Losses} \right)$$ $$Q_{total\_level} = \sum Q_{bangunan}$$

B. Rumus Perhitungan Faktor K

Faktor K adalah rasio antara ketersediaan debit air di intake dengan total kebutuhan air seluruh daerah irigasi: $$K = \frac{Q_{\text{intake}}}{Q_{\text{kebutuhan}}}$$ Aturan penentuan debit intake ($Q_{\text{intake}}$): $$Q_{\text{perintah}} = Q_{\text{kebutuhan\_petak}} \times K$$

C. Mesin Rotasi Air (Giliran Intermiten)

Logika giliran pada `_find_active_rotation()` bekerja secara deterministik berbasis selisih waktu (*timestamp modulo*): $$T_{\text{periode}} = \text{periode (hari)} \times 86400$$ $$T_{\text{turn}} = \frac{T_{\text{periode}}}{\text{jumlah\_giliran}}$$ $$\Delta t = t_{\text{sekarang}} - t_{\text{mulai}}$$ $$\text{Current Turn} = \left\lfloor \frac{\Delta t \pmod{T_{\text{periode}}}}{T_{\text{turn}}} \right\rfloor + 1$$ $$\text{Time Remaining} = T_{\text{turn}} - \left( \Delta t \pmod{T_{\text{periode}}} \pmod{T_{\text{turn}}} \right)$$ ---

8. Temuan Menarik, Kerentanan Keamanan & Quirk Implementasi

Berdasarkan audit mendalam terhadap basis kode, berikut adalah daftar temuan teknis penting untuk bahan riset dan refaktorisasi:

1. Eksekusi Kode Berbahaya via `eval()` pada `debit_ruas_harian()`

php
  $data_argbn = str_replace(':', '=>', $argbn[1]);
  eval('$'.trim($argbn[0]).'= array'.$data_argbn.';');
  

2. Injeksi Kode Mentah via Tag `