# Dokumen Kebutuhan & Proses (RPD)
## Platform Iklan Berbasis Credit — Ads OKEWEB


## 1. Latar Belakang

Bisnis periklanan digital berbasis performa (Pay-Per-Click / PPC) memerlukan platform yang mampu mengelola inventaris iklan, menyalurkan tayangan ke berbagai sumber lalu lintas, serta menghitung pemakaian secara akurat berdasarkan klik nyata. Platform **Ads OKEWEB** dibangun untuk menjawab kebutuhan tersebut dengan model **credit-based**: pengiklan (member) membeli credit terlebih dahulu, lalu credit tersebut dipakai setiap kali iklannya diklik oleh pengunjung.

---

---

## 3. Ruang Lingkup

### 3.1 Dalam Lingkup (In-Scope)
- Autentikasi & manajemen sesi pengguna (login, signup, lupa password, ganti password).
- Manajemen pengguna, grup/hak akses, dan menu dinamis berbasis grup.
- Manajemen billing (invoice deposit credit) beserta konfirmasi pembayaran & auto konfirmasi (duitku).
- Manajemen credit pengguna dan riwayat mutasi credit (In/Out).
- Manajemen campaign iklan (buat, ubah, batal, approve, detail).
- Manajemen kategori landing (Landing Page & Redirect) serta placement sumber iklan.
- Manajemen script yang di pasang di web tujuan untuk traking 
- tracking iklan mengarah web dan marketplace, shopee, tiktok, tokopedia
- Mesin penayangan/rotator iklan dengan algoritma *least-clicks* dan jendela jam tayang.
- Pelacakan klik anti-fraud berbasis IP per hari serta kedaluwarsa otomatis.
- Dashboard ringkasan dan ekspor data (Excel/Word/Print).

### 3.2 Luar Lingkup (Out-of-Scope)
- Integrasi gateway pembayaran otomatis (pembayaran saat ini dikonfirmasi manual oleh admin) dan tambahkan duitku.
- Sistem afiliasi/referral pengiklan.
- Iklan format rich-media/video interaktif (format saat ini: link/teks/HTML sederhana).
- Aplikasi mobile native (antarmuka berbasis web responsif).
- Analytics lanjutan pihak ketiga (Google Analytics/Facebook Pixel hanya sebagai sumber placement, bukan integrasi data balik).

---

## 4. Definisi & Istilah

| Istilah | Definisi |
|---|---|
| **Credit** | Mata uang internal sistem. 1 credit = 1 klik iklan yang valid. Diperoleh dari deposit billing. |
| **Campaign** | Satu unit iklan yang dibuat pengiklan; memiliki judul, URL tujuan, jam tayang, dan alokasi credit. |
| **Rotator** | Mesin penayangan yang memilih iklan mana yang ditampilkan berdasarkan algoritma *least-clicks*. |
| **Placement** | Sumber/asal lalu lintas iklan (mis. `fb` = Facebook Ads, `gl` = Google Ads). |
| **Klik valid** | Klik unik dari satu IP pada satu hari untuk satu iklan (anti-click-fraud). |
| **Landing Page** | Jenis kategori yang menampilkan halaman perantara sebelum pengunjung diarahkan ke URL iklan. |
| **Redirect** | Jenis kategori yang langsung mengarahkan pengunjung ke URL iklan tanpa halaman perantara. |
| **Member** | Pengguna grup `members` (pengiklan). |
| **Admin** | Pengguna grup `admin`/`developer` (pengelola sistem). |
| **Ion Auth** | Library autentikasi yang digunakan sistem. |
| **Grocery CRUD** | Library generator CRUD untuk operasi data cepat. |

---

## 5. Deskripsi Umum Sistem

### 5.1 Karakteristik Sistem
Platform ini adalah aplikasi web berarsitektur **MVC** (Model-View-Controller) di atas CodeIgniter 3. Sistem membedakan dua area antarmuka:
- **Area Backend (Admin/Member):** dasbor, manajemen campaign, billing, credit, kategori, placement, user, dan konfigurasi menu. Dilindungi oleh autentikasi dan privilege berbasis grup.
- **Area Landing (Publik):** halaman rotator iklan yang diakses publik melalui URL `landing/{alias}` atau `landing/{alias}/{placement}`. Tidak memerlukan login.

### 5.2 Model Pendapatan
Pendapatan berasal dari penjualan credit. Pengiklan membeli credit melalui invoice (billing), lalu credit terpakai otomatis saat iklan diklik pengunjung. Contoh tarif pada data: **rate Rp 100/credit**, sehingga 1.000 credit = Rp 100.000.

### 5.3 Karakteristik Penayangan
Sistem menampilkan iklan secara **round-robin berbasis klik terkecil** (`ORDER BY klik ASC LIMIT 1`) dengan dua batasan: iklan harus berada dalam jendela jam tayang (`jam_tayang_mulai`–`jam_tayang_selesai`) dan jumlah klik belum melampaui credit (`klik < credit`).

---

## 6. Aktor & Peran

| Aktor | Grup (id) | Deskripsi Peran |
|---|---|---|
| **Admin** | `admin` (1) | Mengelola seluruh data: user, billing, kategori, placement, campaign (termasuk approve), menu, bank. Melihat semua data lintas pengguna. |
| **Developer** | `developer` (3) | Akses konfigurasi/CRUD builder dan pengembangan; hak akses luas untuk pemeliharaan sistem. |
| **Member (Pengiklan)** | `members` (2) | Membeli credit (billing), melihat riwayat credit, membuat & mengelola campaign miliknya, membatalkan campaign pending. Hanya melihat data miliknya sendiri. |
| **Visitor (Pengunjung)** | — (publik) | Mengakses landing/rotator iklan. Kliknya tercatat sebagai konsumsi credit (jika unik per IP/hari). Tidak melakukan login. |
| **Sistem** | — (otomatis) | Menjalankan proses otomatis: pemilihan iklan rotator, pencatatan klik, kedaluwarsa otomatis, pembaruan counter tayang. |

---

## 7. Use Case

### 7.1 Diagram Use Case (Ringkas)

```
                        ┌──────────────────────────────────────────┐
                        │            PLATFORM IKLAN OKEWEB          │
                        │                                          │
   ┌─────────┐   login  │  ┌──────────┐                            │
   │  Admin  │─────────►│  │  Auth    │◄───────── login   ┌────────┐
   │         │          │  └──────────┘                   │ Member │
   └────┬────┘          │        │                        └───┬────┘
        │               │   kelola│                            │
        ├──────────────►│  ┌──────────┐  deposit credit ───────►│
        │  kelola user  │  │ Billing  │◄──── confirm ───────────┤
        │  kelola bank  │  └──────────┘                         │
        │  kelola kategori ┌──────────┐  buat campaign ─────────►│
        ├──────────────►│  │ Campaign │◄── approve/batal ────────┤
        │  kelola place  │  └──────────┘                         │
        │  kelola menu   │  ┌──────────┐                         │
        │               │  │ Credit   │  lihat riwayat ─────────►│
        │               │  └──────────┘                         │
        └──────────────►│  ┌──────────┐                         │
                        │  │ Rotator  │◄──── akses ────── ┌──────┴────┐
                        │  └──────────┘                   │  Visitor  │
                        └─────────────────────────────────┴───────────┘
```

### 7.2 Daftar Use Case

| Kode | Use Case | Aktor Utama | Prioritas |
|---|---|---|---|
| UC-01 | Login / Logout | Admin, Member, Developer | Tinggi |
| UC-02 | Registrasi (Signup) | Member (calon) | Tinggi |
| UC-03 | Lupa & Reset Password | Admin, Member | Sedang |
| UC-04 | Manajemen User | Admin | Tinggi |
| UC-05 | Manajemen Grup & Hak Akses Menu | Admin | Tinggi |
| UC-06 | Manajemen Menu Dinamis | Admin/Developer | Sedang |
| UC-07 | Buat Invoice Billing (Deposit) | Member/Admin | Tinggi |
| UC-08 | Konfirmasi Pembayaran Billing | Admin | Tinggi |
| UC-09 | Lihat Riwayat Credit | Member, Admin | Tinggi |
| UC-10 | Buat Campaign | Member/Admin | Tinggi |
| UC-11 | Ubah Campaign | Member (pending), Admin | Tinggi |
| UC-12 | Approve Campaign | Admin | Tinggi |
| UC-13 | Batalkan Campaign (Refund) | Member (pending), Admin | Tinggi |
| UC-14 | Lihat Detail Campaign | Member, Admin | Sedang |
| UC-15 | Manajemen Kategori Landing | Admin | Sedang |
| UC-16 | Manajemen Ads Placement | Admin | Sedang |
| UC-17 | Akses Rotator Iklan | Visitor | Tinggi |
| UC-18 | Klik Iklan (konsumsi credit) | Visitor, Sistem | Tinggi |
| UC-19 | Lihat Dashboard & Ringkasan | Admin, Member | Sedang |
| UC-20 | Ekspor Data (Excel/Word/Print) | Admin, Member | Rendah |

### 7.3 Skenario Use Case Kunci — UC-10 (Buat Campaign)
- **Aktor:** Member
- **Prakondisi:** Member sudah login; memiliki saldo credit.
- **Alur Utama:**
  1. Member membuka form *Create Campaign*.
  2. Mengisi judul, URL tujuan, jam tayang mulai/selesai, dan jumlah credit.
  3. Sistem memvalidasi input dan mengecek saldo credit member.
  4. Jika saldo cukup, sistem menyimpan campaign (status=0 Pending), **mengurangi saldo credit** member, dan mencatat mutasi credit `Out`.
  5. Sistem menampilkan pesan sukses.
- **Alur Alternatif:** Saldo tidak mencukupi → sistem menolak dan menampilkan pesan "Saldo Credit tidak mencukupi".
- **Pascakondisi:** Campaign berstatus pending menunggu approve admin; saldo credit member berkurang.

---

## 8. Proses Bisnis

### 8.1 Alur Siklus Credit & Campaign

```mermaid
flowchart TD
    A([Member]) -->|1. Deposit credit| B[Buat Invoice Billing\nstatus = Pending]
    B --> C{2. Admin konfirmasi?}
    C -->|Tidak| E[Status tetap Pending / Batal]
    C -->|Ya| D[Status = Lunas\nsaldo credit member +N]
    D --> F[3. Member buat Campaign]
    F --> G{4. Saldo credit cukup?}
    G -->|Tidak| H[Ditolak:\nSaldo tidak mencukupi]
    G -->|Cukup| I[saldo credit -N\nstatus = 0 Pending]
    I --> J{5. Admin approve?}
    J -->|Batal oleh member/admin| L[status = 2\nsaldo credit +N refund]
    J -->|Disetujui| K[status = 1 Aktif\ntgl_aktif diisi]
    K --> M[6. Iklan tayang via Rotator]
    M --> N[7. Visitor klik iklan]
    N --> O{8. IP sama\nhari ini?}
    O -->|Ya| P[Klik tidak dihitung\nanti-fraud]
    O -->|Tidak| Q[klik +1\ncatat ip_history]
    Q --> R{9. klik >= credit?}
    R -->|Ya| S[status = 3 Selesai\nauto-expire]
    R -->|Tidak| M
    S --> T([Campaign berakhir])
    L --> T
```

### 8.2 Alur Penayangan Rotator (Detail Mesin)
1. Visitor mengakses `landing/{alias_kategori}` (opsional `{placement}`).
2. Sistem mencari kategori berdasarkan `alias`; menaikkan counter `viewed` kategori.
3. Jika tidak ada kategori/iklan cocok → redirect ke URL default (`https://okeweb-id.com`).
4. Sistem memilih 1 iklan dengan kriteria:
   - `status = 1` (Aktif)
   - waktu sekarang berada dalam `jam_tayang_mulai`–`jam_tayang_selesai`
   - `klik < credit`
   - `kategori = id_kategori`
   - urutkan `klik ASC`, ambil 1 (`LIMIT 1`) → **algoritma least-clicks**.
5. Menaikkan counter `muncul` (tayang) iklan.
6. Mencatat/memperbarui `ads_history` per placement.
7. **Berdasarkan jenis kategori:**
   - **Landing Page:** tampilkan halaman perantara berisi judul + deskripsi + tombol "Klik untuk melanjutkan" → mengarah ke `landing/go/{id}`.
   - **Redirect:** langsung menuju `landing/go/{id}`.
8. Pada `landing/go/{id}`:
   - Cek apakah IP visitor sudah tercatat untuk iklan ini hari ini (`ip_history`).
   - Jika **belum** → catat IP + browser, naikkan `klik` iklan (+1).
   - Jika `klik >= credit` → ubah `status = 3` (Selesai/kedaluwarsa otomatis).
   - Redirect ke `url` iklan.

### 8.3 Alur Mutasi Credit
- **Credit In (bertambah):** deposit billing dikonfirmasi Lunas; campaign dibatalkan (refund).
- **Credit Out (berkurang):** pembuatan campaign baru.
- Setiap mutasi dicatat di tabel `credit_history` dengan nomor invoice/referensi, tanggal, keterangan (HTML), jumlah credit, jenis (`In`/`Out`), dan `iduser`.

---

## 9. Kebutuhan Fungsional

### 9.1 Modul Autentikasi & Otorisasi (AUT)
| Kode | Kebutuhan |
|---|---|
| FR-AUT-01 | Sistem wajib menyediakan login berbasis *identity* (username/email) dan password menggunakan Ion Auth. |
| FR-AUT-02 | Sistem wajib menyediakan fitur "Remember Me" pada login. |
| FR-AUT-03 | Sistem wajib menyediakan registrasi (signup) pengguna baru dengan data: nama depan, nama belakang, perusahaan, telepon, email, password. |
| FR-AUT-04 | Sistem wajib menyediakan mekanisme lupa password (kirim kode reset) dan reset password. |
| FR-AUT-05 | Sistem wajib menyediakan ganti password bagi pengguna yang sudah login. |
| FR-AUT-06 | Sistem wajib membatasi akses halaman backend hanya untuk pengguna ter-login; pengguna belum login dialihkan ke halaman login. |
| FR-AUT-07 | Sistem wajib menerapkan privilege berbasis grup (`groups_menu`): pengguna hanya bisa mengakses menu/controller yang diberikan ke grupnya. |
| FR-AUT-08 | Sistem wajib mencatat percobaan login gagal pada `login_attempts`. |

### 9.2 Modul Manajemen User & Grup (USR)
| Kode | Kebutuhan |
|---|---|
| FR-USR-01 | Admin wajib dapat melihat, menambah, mengubah, dan menghapus (CRUD) pengguna. |
| FR-USR-02 | Admin wajib dapat menetapkan/merubah keanggotaan grup seorang pengguna. |
| FR-USR-03 | Sistem wajib menyimpan saldo `credit` per pengguna. |
| FR-USR-04 | Admin wajib dapat mengelola grup (`admin`, `members`, `developer`). |
| FR-USR-05 | Admin/Developer wajib dapat mengelola menu dinamis (label, link, ikon, urutan, hierarki parent-child) dan tipe menu. |
| FR-USR-06 | Admin/Developer wajib dapat mengatur hak akses menu per grup melalui `groups_menu`. |

### 9.3 Modul Billing & Deposit (BILL)
| Kode | Kebutuhan |
|---|---|
| FR-BILL-01 | Member/Admin wajib dapat membuat invoice billing (deposit credit) berisi: jumlah credit, rate, total, bank tujuan, pengguna. |
| FR-BILL-02 | Sistem wajib menghasilkan nomor invoice otomatis dengan format `DDMMYYYY` + 4 digit urut harian (mis. `2001210001`). |
| FR-BILL-03 | Invoice baru berstatus `Pending`. |
| FR-BILL-04 | Admin wajib dapat mengkonfirmasi pembayaran → status `Lunas`; saat Lunas, saldo credit pengguna **bertambah** sebesar `jumlah_credit` dan mutasi `In` dicatat. |
| FR-BILL-05 | Admin wajib dapat mengubah/menghapus invoice hanya selama berstatus `Pending`. |
| FR-BILL-06 | Member hanya dapat melihat invoice miliknya; tidak dapat membuat/mengubah/menghapus (hanya admin). |
| FR-BILL-07 | Sistem wajib mendukung penghapusan massal (bulk delete) invoice. |
| FR-BILL-08 | Admin wajib dapat mengelola master bank (kode, keterangan rekening). |

### 9.4 Modul Credit & Riwayat (CRED)
| Kode | Kebutuhan |
|---|---|
| FR-CRED-01 | Sistem wajib mencatat setiap mutasi credit di `credit_history`: invoice/referensi, tanggal, keterangan, jumlah, jenis (`In`/`Out`), iduser. |
| FR-CRED-02 | Member wajib dapat melihat riwayat credit miliknya; Admin melihat seluruh riwayat. |
| FR-CRED-03 | Mutasi `In` wajib dicatat saat: konfirmasi billing Lunas; pembatalan campaign (refund). |
| FR-CRED-04 | Mutasi `Out` wajib dicatat saat: pembuatan campaign. |

### 9.5 Modul Campaign Iklan (CAMP)
| Kode | Kebutuhan |
|---|---|
| FR-CAMP-01 | Member/Admin wajib dapat membuat campaign: judul, URL tujuan, jam tayang mulai/selesai, jumlah credit, (admin: kategori, pemilik user). |
| FR-CAMP-02 | Sistem wajib memvalidasi saldo credit sebelum campaign dibuat; menolak jika saldo kurang. |
| FR-CAMP-03 | Saat campaign dibuat: saldo credit pengguna berkurang, status=`0` (Pending), mutasi `Out` dicatat. |
| FR-CAMP-04 | Member hanya dapat mengubah campaign miliknya yang berstatus `0` (Pending). |
| FR-CAMP-05 | Admin wajib dapat menyetujui (approve) campaign pending → status=`1` (Aktif), `tgl_aktif` terisi. |
| FR-CAMP-06 | Member/Admin wajib dapat membatalkan campaign pending → status=`2` (Batal); saldo credit **dikembalikan** (refund) dan mutasi `In` dicatat. |
| FR-CAMP-07 | Member hanya dapat melihat/mengelola campaign miliknya; Admin melihat semua. |
| FR-CAMP-08 | Sistem wajib menampilkan sisa credit campaign (`credit - klik`) pada daftar. |
| FR-CAMP-09 | Sistem wajib mendukung ekspor daftar campaign ke Excel, Word, dan Print. |

### 9.6 Modul Kategori Landing (KAT)
| Kode | Kebutuhan |
|---|---|
| FR-KAT-01 | Admin wajib dapat mengelola kategori: nama, judul, deskripsi (HTML), alias, jenis (`Landing Page`/`Redirect`), status. |
| FR-KAT-02 | Sistem wajib menghasilkan alias kategori (identitas URL publik). |
| FR-KAT-03 | Sistem wajib mencatat jumlah dilihat (`viewed`) per kategori. |
| FR-KAT-04 | Kategori jenis `Landing Page` menampilkan halaman perantara; jenis `Redirect` langsung mengarahkan ke URL iklan. |

### 9.7 Modul Ads Placement (PLACE)
| Kode | Kebutuhan |
|---|---|
| FR-PLACE-01 | Admin wajib dapat mengelola placement sumber iklan: kode (mis. `fb`, `gl`), keterangan, URL. |
| FR-PLACE-02 | Sistem wajib mencatat statistik tayang per placement di `ads_history`. |
| FR-PLACE-03 | Jika placement tidak dikenali, sistem menggunakan placement default `UNKNOWN` (id=1). |

### 9.8 Modul Rotator / Penayangan (ROT)
| Kode | Kebutuhan |
|---|---|
| FR-ROT-01 | Sistem wajib menyediakan endpoint publik `landing/{alias}` dan `landing/{alias}/{placement}` tanpa login. |
| FR-ROT-02 | Sistem wajib memilih iklan aktif dengan algoritma least-clicks (`ORDER BY klik ASC LIMIT 1`) dalam jendela jam tayang dan `klik < credit`. |
| FR-ROT-03 | Sistem wajib menaikkan counter tayang (`muncul`) iklan dan `viewed` kategori. |
| FR-ROT-04 | Sistem wajib menyediakan endpoint `landing/go/{id}` untuk mencatat klik dan mengarahkan ke URL iklan. |
| FR-ROT-05 | Sistem wajib menerapkan anti-click-fraud: 1 IP hanya boleh menghasilkan 1 klik per iklan per hari (`ip_history`). |
| FR-ROT-06 | Sistem wajib mengubah status iklan menjadi `3` (Selesai) otomatis ketika `klik >= credit`. |
| FR-ROT-07 | Jika tidak ada iklan cocok, sistem redirect ke URL default. |

### 9.9 Modul Dashboard & Laporan (DASH)
| Kode | Kebutuhan |
|---|---|
| FR-DASH-01 | Sistem wajib menampilkan dashboard ringkasan: campaign terbaru, billing/credit terbaru. |
| FR-DASH-02 | Sistem wajib menampilkan grafik performa campaign (judul vs jumlah klik) untuk iklan berstatus aktif/selesai. |
| FR-DASH-03 | Member hanya melihat datanya sendiri; Admin melihat seluruh data. |

---

## 10. Kebutuhan Non-Fungsional

| Kode | Kategori | Kebutuhan |
|---|---|---|
| NFR-01 | Performa | Halaman daftar (Datatables) wajib memuat ≤ 3 detik pada data ≤ 10.000 baris; query rotator wajib direspons < 1 detik. |
| NFR-02 | Keamanan | Autentikasi menggunakan password hash (bcrypt); sesi terlindungi; mencegah akses tidak sah antar pengguna (member tidak bisa membaca data member lain). |
| NFR-03 | Keamanan | *Catatan risiko*: beberapa query masih menggunakan interpolasi string (lihat §15) — perlu mitigasi. |
| NFR-04 | Keandalan | Sistem wajib menjaga konsistensi saldo credit (operasi pengurangan/pengembalian bersifat atomik terhadap data terkait). |
| NFR-05 | Keamanan Data | Klik hanya dihitung dari IP unik per hari untuk mencegah inflasi klik (fraud). |
| NFR-06 | Usability | Antarmuka admin berbasis AdminLTE, konsisten, dengan navigasi sidebar dinamis sesuai hak akses. |
| NFR-07 | Kompatibilitas | Berjalan pada PHP ≥ 5.6 (disarankan ≥ 7.2), MariaDB/MySQL, server Apache/Nginx. |
| NFR-08 | Maintainability | Kode mengikuti pola MVC CodeIgniter; CRUD ter-generate via Grocery CRUD/Harviacode untuk konsistensi. |
| NFR-29 | Skalabilitas | Skema dapat melayani banyak pengiklan & campaign; indeks primer pada semua tabel kunci. |
| NFR-10 | Interoperabilitas | Mendukung ekspor data ke format Excel (.xls) dan Word (.doc). |

---

## 11. Aturan Bisnis

| Kode | Aturan |
|---|---|
| BR-01 | **Credit sebagai mata uang**: 1 credit = 1 klik valid. Credit diperoleh dari deposit billing. |
| BR-02 | **Penomoran invoice**: format `DDMMYYYY` + urutan 4 digit harian, direset setiap hari (`SELECT MAX(RIGHT(no_invoice,4)) ... WHERE DATE(tanggal)=CURDATE()`). |
| BR-03 | **Status Campaign**: `0`=Menunggu Approve, `1`=Aktif, `2`=Batal, `3`=Selesai/Tidak Aktif (kedaluwarsa). |
| BR-04 | **Status Billing**: `Pending`, `Lunas`, (dapat `Batal`). Hanya `Pending` yang dapat diubah/dihapus. |
| BR-05 | **Pengurangan credit**: dilakukan saat campaign dibuat (bukan saat diklik). |
| BR-06 | **Pengembalian credit (refund)**: dilakukan saat campaign dibatalkan (status→2). |
| BR-07 | **Algoritma rotator**: iklan dipilih dengan `status=1`, dalam jendela jam tayang, `klik < credit`, urut `klik ASC LIMIT 1`. |
| BR-08 | **Anti-click-fraud**: 1 IP = maks 1 klik per iklan per hari (dicek via `ip_history`). |
| BR-09 | **Kedaluwarsa otomatis**: saat `klik >= credit`, status iklan otomatis menjadi `3`. |
| BR-10 | **Privilege menu**: akses controller ditentukan oleh `groups_menu`; pengguna tanpa akses diarahkan ke Dashboard. |
| BR-11 | **Dua jenis kategori**: `Landing Page` (halaman perantara) dan `Redirect` (langsung redirect). |
| BR-12 | **Member terbatas**: member (grup 2) tidak dapat memilih kategori/pemilik saat membuat campaign; tidak dapat membuat/mengubah billing; hanya melihat data sendiri. |
| BR-13 | **Mutasi credit**: setiap perubahan saldo wajib dicatat di `credit_history` dengan jenis `In`/`Out`. |

---

## 12. Struktur Data

### 12.1 Entity Relationship Diagram (ERD)

```mermaid
erDiagram
    users ||--o{ users_groups : "tergabung"
    groups ||--o{ users_groups : "beranggotakan"
    groups ||--o{ groups_menu : "berhak"
    menu ||--o{ groups_menu : "diakses"
    menu }o--|| menu_type : "berjenis"
    users ||--o{ ads : "membuat"
    users ||--o{ billing : "memiliki"
    users ||--o{ credit_history : "bermutasi"
    kategori ||--o{ ads : "mengkategorikan"
    bank ||--o{ billing : "tujuan-bayar"
    ads ||--o{ ads_history : "dicatat"
    ads_placement ||--o{ ads_history : "dari-sumber"

    users {
        int id PK
        varchar username
        varchar email
        varchar password
        int credit
        int active
    }
    ads {
        int id PK
        varchar judul
        text url
        varchar jam_tayang_mulai
        varchar jam_tayang_selesai
        int credit
        int kategori FK
        int klik
        int muncul
        int iduser FK
        int status
    }
    billing {
        int id PK
        varchar no_invoice
        int jumlah_credit
        int rate
        int total
        int bank FK
        varchar status
        int iduser FK
    }
    credit_history {
        int id PK
        varchar invoice
        varchar tanggal
        varchar keterangan
        int credit
        varchar jenis
        int iduser FK
    }
```

### 12.2 Kamus Data (Data Dictionary)

| Tabel | Fungsi | Kolom Kunci |
|---|---|---|
| `users` | Data pengguna + saldo credit | `id`, `username`, `email`, `password`, `credit`, `active` |
| `groups` | Grup pengguna | `id`, `name` (admin/members/developer), `description` |
| `users_groups` | Relasi user–grup | `user_id`, `group_id` |
| `menu` | Menu dinamis (label/link/ikon/hierarki) | `id_menu`, `label`, `link`, `parent_id`, `id_menu_type` |
| `menu_type` | Tipe menu | `id_menu_type`, `type` (mis. `Side menu`) |
| `groups_menu` | Hak akses menu per grup | `id_groups`, `id_menu` |
| `ads` | Data campaign/iklan | `id`, `judul`, `url`, `jam_tayang_mulai/selesai`, `credit`, `kategori`, `klik`, `muncul`, `iduser`, `status` |
| `kategori` | Kategori landing | `id`, `nama_kategori`, `judul`, `deskripsi`, `alias`, `jenis`, `viewed`, `status` |
| `ads_placement` | Sumber lalu lintas | `id`, `kode` (`fb`/`gl`), `keterangan`, `url` |
| `ads_history` | Statistik tayang per placement | `idads`, `idplacement`, `klik`, `tgl_update` |
| `billing` | Invoice deposit credit | `id`, `no_invoice`, `jumlah_credit`, `rate`, `total`, `bank`, `status`, `iduser` |
| `bank` | Master bank/rekening | `id`, `kode`, `keterangan` |
| `credit_history` | Mutasi credit | `id`, `invoice`, `tanggal`, `keterangan`, `credit`, `jenis`, `iduser` |
| `login_attempts` | Percobaan login gagal | `id`, `ip_address`, `login`, `time` |
| `ip_history` * | Riwayat IP per klik (anti-fraud) | `idads`, `ip`, `browser`, `tanggal` — **lihat §15** |

> *\* Tabel `ip_history` dirujuk dalam kode (`Landing.php`, `views/Landing/Index.php`) namun **tidak terdapat** dalam dump `adsbase.sql` — wajib dibuat manual (lihat Temuan Teknis).*

---

## 13. Antarmuka Sistem

### 13.1 Antarmuka Pengguna (UI)
| Area | Halaman | Akses |
|---|---|---|
| Publik | Login, Signup, Lupa Password | Semua |
| Publik | Landing/Rotator (`landing/{alias}`) | Visitor |
| Backend | Dashboard | Admin, Member, Developer |
| Backend | Campaign (list/form/read) | Admin, Member |
| Backend | Billing (list/form/read) | Admin (Member: lihat) |
| Backend | Credit History | Admin, Member |
| Backend | Bank, Ads Placement, Kategori | Admin |
| Backend | Users, Groups, Menu, Menu Type | Admin/Developer |
| Backend | CRUD Builder | Developer |

Template: **AdminLTE** (skin-blue) dengan sidebar dinamis, Bootstrap, DataTables, Select2, Bootstrap Datepicker, Alertify, TinyMCE (editor HTML), dan Nestable (urut menu).

### 13.2 Antarmuka Program (Endpoint Kunci)
| Rute / Controller | Metode | Fungsi |
|---|---|---|
| `auth/login` | GET/POST | Login |
| `auth/signup` | GET/POST | Registrasi |
| `auth/forgot_password` | GET/POST | Lupa password |
| `dashboard` | GET | Ringkasan |
| `campaign` | GET | Daftar campaign (Datatables via `campaign/json`) |
| `campaign/create` | GET/POST | Buat campaign |
| `campaign/proses/{id}` | GET | Approve campaign |
| `campaign/batal/{id}` | GET | Batalkan + refund |
| `billing` / `billing/proses/{id}` | GET | Invoice / konfirmasi Lunas |
| `landing/{alias}` / `landing/{alias}/{place}` | GET | Rotator iklan |
| `landing/go/{id}` | GET | Catat klik + redirect |
| `kategori`, `ads_placement`, `bank` | CRUD | Master data |

---

## 14. Asumsi & Ketergantungan

### 14.1 Asumsi
- Konfirmasi pembayaran billing dilakukan **manual** oleh admin setelah memverifikasi transfer ke rekening bank terdaftar.
- Tarif (rate) per credit ditentukan per invoice oleh admin (tidak otomatis dari master tarif).
- Server memiliki timezone yang konsisten (`Asia/Jakarta` dipakai saat pembuatan invoice).
- Pengunjung dianggap unik berdasarkan kombinasi IP + tanggal + iklan.

### 14.2 Ketergantungan
- PHP ≥ 5.6 (data eksisting: 7.2.33), ekstensi `mysqli`.
- MariaDB/MySQL (data eksisting: MariaDB 10.4.14).
- Library pihak ketiga: Ion Auth, Grocery CRUD, DataTables, AdminLTE, TinyMCE, Image_moo, Bcrypt.
- Konfigurasi `base_url`, `encryption_key`, dan session yang benar agar autentikasi berfungsi.

---

## 15. Temuan & Catatan Teknis

Bagian ini berisi temuan dari analisis kode sumber yang penting untuk diperhatikan saat pengembangan/pengujian.

### 15.1 Tabel `ip_history` Belum Didefinisikan di Skema
Kode di `application/controllers/Landing.php` (baris 46–50) dan `application/views/Landing/Index.php` (baris 67–71) melakukan `select`/`insert` ke tabel `ip_history`, namun tabel ini **tidak ada** dalam `adsbase.sql`. Tanpa tabel ini, fitur anti-click-fraud akan gagal (error query).

**Usulan definisi tabel:**
```sql
CREATE TABLE `ip_history` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ip` varchar(45) NOT NULL,
  `idads` int(10) NOT NULL,
  `browser` varchar(255) DEFAULT NULL,
  `tanggal` date NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idads` (`idads`,`ip`,`tanggal`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```

### 15.2 Risiko SQL Injection
Beberapa query menggunakan interpolasi string langsung, contoh:
- `Layout.php` → `auth_privilege()`: `... where substring_index(menu.link, '/', 1) = '$current_url'`
- `Landing.php` → `go()` dan `views/Landing/Index.php`: query dengan `$id`, `$ipclient` langsung disisipkan.

**Rekomendasi:** migrasi ke *query builder* CodeIgniter (`$this->db->where()` dengan binding) atau *prepared statements*, serta validasi tipe data (id harus integer).

### 15.3 Konsistensi Transaksi Credit
Operasi pengurangan/pengembalian credit melibatkan beberapa tabel (`ads`, `users`, `credit_history`). Saat ini tidak terlihat dibungkus transaksi database. Kegagalan sebagian dapat menyebabkan saldo tidak konsisten.

**Rekomendasi:** bungkus operasi multi-tabel dengan `$this->db->trans_start()` / `trans_complete()`.

### 15.4 Kredensial Default pada Data Seed
Dump `adsbase.sql` berisi pengguna `administrator` / `member` / `admin@gmail.com` dengan password ter-hash. Pastikan diubah pada lingkungan produksi.

### 15.5 Penamaan "Laravel" pada Folder
Folder proyek bernama `Laravel/ads`, namun framework yang dipakai adalah **CodeIgniter 3** (lihat `composer.json`: `codeigniter/framework`). Ini hanya penamaan direktori, bukan indikasi framework.

### 15.6 Fallback Redirect Hardcoded
Saat tidak ada iklan cocok, sistem redirect ke `https://okeweb-id.com` (hardcoded di `views/Landing/Index.php` baris 24). Sebaiknya dijadikan konfigurasi (`tamaconfig.php`).

---

## 16. Lampiran: Teknologi & Struktur Folder

### 16.1 Teknologi
| Komponen | Teknologi |
|---|---|
| Bahasa | PHP (≥ 5.6, data 7.2.33) |
| Framework | CodeIgniter 3 |
| Basis Data | MariaDB 10.4 / MySQL (mysqli) |
| Template UI | AdminLTE (skin-blue) + Bootstrap |
| Autentikasi | Ion Auth (bcrypt) |
| CRUD | Grocery CRUD + Harviacode CRUD Generator |
| Komponen UI | DataTables, Select2, Bootstrap Datepicker, Alertify, TinyMCE, Nestable |
| Server | Apache/Nginx + PHP |

### 16.2 Struktur Folder Inti
```
ads/
├── application/
│   ├── config/        # konfigurasi (database, routes, autoload, ion_auth, tamaconfig)
│   ├── controllers/   # Auth, Dashboard, Campaign, Billing, Kategori, Users, Groups, Menu, ...
│   ├── models/        # *_model.php (Campaign_model, Billing_model, Ion_auth_model, ...)
│   ├── views/         # template/ (backend, landing), campaign/, billing/, auth/, ...
│   ├── libraries/     # Layout, Ion_auth, Grocery_CRUD, Datatables, Bcrypt, Image_moo
│   └── helpers/       # exportexcel_helper.php (get_ip, get_browser_client)
├── assets/            # AdminLTE, bower_components, plugins, dist, uploads
├── system/            # inti CodeIgniter
├── landings/          # aset landing publik
├── crud/              # generator CRUD
├── adsbase.sql        # dump basis data
└── index.php          # entry point
```

### 16.3 Konfigurasi Penting
- `application/config/routes.php` — `default_controller = auth`, rute `login`, `signup`, `landing/*`.
- `application/config/autoload.php` — library: `database, email, session, ion_auth, Layout`; helper: `url, file, form, language`; config: `tamaconfig`.
- `application/config/database.php` — koneksi mysqli ke `adsbase`.
- `application/config/tamaconfig.php` — `sitename` = "Ads okeweb.id".
- `application/config/ion_auth.php` — `default_group = members`, `admin_group = admin`.

---

*Dokumen ini disusun dari analisis langsung kode sumber dan skema basis data proyek Ads OKEWEB. Versi 1.0 — siap digunakan sebagai acuan kebutuhan, pengembangan, dan pengujian.*
