# Master Data Schema

## Core

```sql
users (id, name, email, password_hash, is_superadmin, is_active, deleted_at)
user_spbu_assignments (user_id, spbu_id, role_id)
roles (id, spbu_id [null=global], nama, deskripsi, is_system, can_be_scheduled, can_login_web)
role_permissions (role_id, modul, aksi)
```

## SPBU Config

```sql
master_spbu (id, name, nomor_pertamina, alamat, rekening_bank,
             teller_discrepancy_threshold_pct,  -- default 0.300
             is_active, deleted_at)
master_spbu_shift (id, spbu_id, nama, jam_mulai, jam_selesai, is_active, deleted_at)
master_spbu_island (id, spbu_id, nama, urutan, is_active, deleted_at)
master_spbu_nozzle (id, island_id, nama, produk_id, tangki_id,
                    teller_terakhir_manual, teller_terakhir_digital,
                    primary_teller,  -- 'manual' (default) | 'digital'
                    is_active, deleted_at)
  -- TIDAK ada no_meter/nomor seri
master_spbu_tangki (id, spbu_id, nama, kapasitas_liter, produk_id, is_active, deleted_at)
master_spbu_kalibrasi (id, tangki_id, tinggi_cm, volume_liter)
```

## Products

```sql
master_produk (id, nama, kode, jenis[gasoline/diesel], is_subsidi, kuota_config jsonb,
               losses_threshold_penerimaan_pct,  -- default 0.150
               losses_threshold_penjualan_pct,   -- default 0.500
               deleted_at)
produk_harga (id, produk_id, harga, berlaku_mulai, berlaku_sampai)
spbu_produk (spbu_id, produk_id, is_active)
```

## Contracts

```sql
master_spbu_tenant (id, spbu_id, nama, jenis_usaha, luas_m2, kontak, deleted_at)
master_spbu_kontrak (id, tenant_id, nilai_bulanan, tanggal_mulai, tanggal_akhir, status, dokumen_url)
-- status: Active | Expiring Soon | Expired. Alert < 90 hari dari jatuh tempo.
```

## Penyetoran

```sql
penyetoran (id, laporan_shift_id, spbu_id, tanggal, shift_id,
            jumlah_kas, jumlah_non_kas, total_penjualan, catatan, bukti_url,
            batch_id, status,  -- draft | submitted | approved
            created_by_id, created_at, updated_at)
-- UniqueConstraint: (laporan_shift_id)

penyetoran_batch (id, spbu_id, tanggal_from, tanggal_to, total_amount, catatan,
                  status,  -- draft | submitted | approved
                  submitted_by_id, submitted_at,
                  reviewed_by_id, reviewed_at, catatan_review,
                  unlocked_by_id, unlocked_at, unlock_reason,
                  created_at, updated_at)
```

## General Affairs

```sql
absensi (id, spbu_id, shift_id, tanggal, foto_url, foto_eksif_waktu, status,
         uploaded_by_id, uploaded_at, reviewed_by_id, reviewed_at)
-- status: pending | approved
-- UniqueConstraint: (spbu_id, shift_id, tanggal)

housekeeping (id, spbu_id, shift_id, tanggal, status,
              uploaded_by_id, uploaded_at, reviewed_by_id, reviewed_at)
housekeeping_item (id, housekeeping_id, deskripsi, urutan)
housekeeping_foto (id, housekeeping_id, tipe['before'|'after'], foto_url, urutan)
-- UniqueConstraint: (spbu_id, shift_id, tanggal)
```

## System

```sql
system_config (id, key, value, updated_at)
-- Keys: maintenance_mode ('true'/'false'), environment_mode ('development'/'production')
```

## Belum diimplementasikan

```sql
pemindahan_produk (...)     -- ❌
rekonsiliasi_harian (...)   -- ❌
anomali_records (...)       -- ❌
audit_log (...)             -- ❌
tangki_produk_history (...) -- ❌
```
