# Arsitektur dan Struktur Kode

## Gambaran sistem

```text
Browser admin/wali/santri/pengelola/pengasuh/dev
                 | Livewire + session auth
                 v
Routes -> middleware role -> komponen Livewire -> service domain
                                                   |
Mobile wali -> REST API -> Sanctum -> controller --+
Kiosk fisik -> REST API -> token Device -----------+
                                                   v
                               model + transaksi database
                                                   |
                         ledger, audit, notifikasi, dokumen
```

UI tidak menjadi batas keamanan. Route, lifecycle komponen, ownership query,
dan service tetap harus menolak akses yang tidak sah.

## Struktur direktori

| Lokasi | Tanggung jawab |
| --- | --- |
| `app/Livewire` | State dan aksi halaman web; jangan menaruh algoritma ledger di sini |
| `app/Http/Controllers/Api` | Adapter HTTP API, validasi request, dan response resource |
| `app/Services` | Aturan bisnis, transaksi atomik, idempotensi, dan integrasi |
| `app/Models` | Relasi, cast, scope, konstanta status, dan invariant model |
| `app/Policies`, middleware | Otorisasi server-side dan batas role/ownership |
| `resources/views` | Presentasi Blade; seluruh layout harus mobile-first |
| `routes` | Peta endpoint web, API, dan console |
| `database/migrations` | Evolusi skema yang tidak boleh diedit setelah produksi |
| `database/seeders` | Data awal dan role; seeder wajib aman dijalankan ulang |
| `tests/Feature` | Kontrak perilaku antarlapisan dan regresi finansial |
| `docs` | Flow, kontrak, deployment, keamanan, dan runbook |

## Batas lapisan

```text
Komponen/controller
  -> validasi format dan otorisasi awal
  -> panggil service domain

Service domain
  -> DB::transaction
  -> lock baris yang akan berubah
  -> validasi invariant dan periode
  -> cek idempotensi
  -> tulis semua sisi ledger
  -> simpan audit/referensi

Komponen/controller
  -> tampilkan resource, bukti, atau pesan aman
```

Komponen Livewire dan controller API boleh memakai service yang sama. Jangan
menduplikasi perhitungan saldo atau aturan tagihan di kedua kanal.

## Sumber kebenaran keuangan

| Domain | Sumber kebenaran | Catatan |
| --- | --- | --- |
| Saldo santri | Ledger/transaksi saldo | Nilai cache harus dapat direkonsiliasi |
| Tabungan | Rekening dan transaksi tabungan | Terpisah dari saldo belanja |
| Kas petugas | Sesi kas dan mutasi kas | Selisih fisik tidak mengubah histori |
| Tagihan | Tagihan dan pembayaran | Periode tagihan berbeda dari waktu pembayaran |
| Kantin | Ledger unit usaha | Kredit pembayaran dan debit pencairan |
| Midtrans | Transaksi lokal + callback tervalidasi | Callback berulang wajib idempoten |
| Tutup buku | Snapshot dan status periode | Histori terkunci, transaksi periode baru tetap berjalan |

## Kontrol periode dan koreksi

```text
Rekonsiliasi -> temuan?
  | tidak -> periode siap ditutup
  + ya -> tetapkan penanggung jawab -> unggah bukti
          -> ajukan penyesuaian -> pemeriksa berbeda menyetujui/menolak
          -> transaksi koreksi baru -> rekonsiliasi ulang
          -> tutup buku -> snapshot permanen + audit
```

Tagihan Agustus yang dibayar September tetap mengurangi tagihan Agustus, tetapi
kas/pembayaran tercatat pada waktu aktual di September. Penutupan Agustus tidak
menghapus kewajiban dan tidak memindahkan tanggal pembayaran.

## Event sensitif

- Restore: superadmin, 2FA/kode pemulihan, kata sandi, maintenance aktif, audit.
- Midtrans: perubahan kredensial diajukan superadmin dan disetujui pengasuh.
- Penyesuaian: pembuat dan penyetuju harus berbeda.
- Tutup buku: hanya setelah rekonsiliasi dan sesi kas selesai.
- Selisih kas: bukti, alasan, keputusan, dan transaksi koreksi harus tertaut.

## Konvensi responsif

- Mulai dari lebar ponsel; breakpoint hanya menambah kolom.
- Semua container memakai `min-width: 0` agar isi dapat menyusut.
- Tabel berada dalam pembungkus `overflow-x-auto`, dengan teks panjang dapat membungkus.
- Blok kode memakai overflow horizontal dan tidak memperlebar halaman.
- Tombol aksi utama menjadi lebar penuh di ponsel bila ruang tidak cukup.
- Informasi tidak boleh bergantung pada warna saja; selalu sertakan label/status.

## Definition of done

1. Otorisasi server-side dan validasi ownership tersedia.
2. Perubahan finansial atomik, idempoten, dan memiliki audit.
3. Empty, loading, error, sukses, serta layar kecil telah diperiksa.
4. Bukti transaksi dan export memakai sumber data yang sama dengan layar.
5. Tes regresi relevan lulus dan aset produksi berhasil dibangun.
6. Flow, matriks role, API, atau runbook diperbarui bila kontraknya berubah.
