# DOKUMENTASI DATABASE SISTEM PERPUSTAKAAN SMA N 1 PANGURURAN

## 📋 Daftar Isi
1. [Gambaran Umum Sistem](#1-gambaran-umum-sistem)
2. [Stored Procedures](#2-stored-procedures)
3. [Functions](#3-functions)
4. [Views](#4-views)
5. [Triggers](#5-triggers)
6. [Struktur Tabel](#6-struktur-tabel)

---

## 1. Gambaran Umum Sistem

### Informasi Database
- **Nama Database**: `db_perpustakaan_sma1pangururan`
- **Server**: MariaDB 10.4.32
- **PHP Version**: 8.0.30
- **Character Set**: UTF8MB4
- **Waktu Export**: 27 Desember 2025

### Komponen Database
- **Stored Procedures**: 6 procedures
- **Functions**: 5 functions
- **Views**: 13 views
- **Triggers**: 13 triggers
- **Tables**: 18+ tabel

---

## 2. Stored Procedures

Database memiliki **6 Stored Procedures** untuk berbagai kebutuhan operasional.

### 2.1 `sp_buku_populer()`
**Fungsi**: Menampilkan 10 buku paling populer berdasarkan jumlah peminjaman

**Parameter**: Tidak ada

**Output Columns**:
- `kode_buku` - Kode unik buku
- `judul` - Judul buku
- `nama_pengarang` - Nama penulis
- `penerbit` - Penerbit
- `stok_tersedia` - Stok tersedia saat ini
- `total_dipinjam` - Total kali dipinjam
- `rating_rata` - Rating rata-rata (dari `fn_rating_buku`)
- `jumlah_ulasan` - Jumlah ulasan
- `status_stok` - Status ketersediaan (dari `fn_cek_ketersediaan`)

**Contoh Penggunaan**:
```sql
CALL sp_buku_populer();
```

**Kegunaan**:
- Dashboard analitik perpustakaan
- Rekomendasi buku populer untuk pengunjung
- Laporan statistik koleksi

---

### 2.2 `sp_dashboard_statistik()`
**Fungsi**: Menampilkan statistik global perpustakaan

**Parameter**: Tidak ada

**Output Columns**:
- `total_buku` - Total judul buku dalam sistem
- `total_stok_tersedia` - Total stok buku tersedia
- `total_member_aktif` - Total member dengan status aktif
- `total_sedang_dipinjam` - Buku yang sedang dipinjam saat ini
- `total_terlambat` - Peminjaman yang terlambat
- `total_denda_terkumpul` - Total denda terkumpul (Rupiah)
- `total_ulasan` - Total ulasan yang diberikan
- `rating_rata_keseluruhan` - Rating rata-rata semua buku

**Contoh Penggunaan**:
```sql
CALL sp_dashboard_statistik();
```

**Sample Output**:
| total_buku | total_stok_tersedia | total_member_aktif | total_sedang_dipinjam | total_terlambat | total_denda_terkumpul | total_ulasan | rating_rata_keseluruhan |
|------------|---------------------|--------------------|-----------------------|-----------------|----------------------|--------------|------------------------|
| 55 | 687 | 30 | 2 | 1 | 15000 | 45 | 4.25 |

**Kegunaan**:
- Dashboard admin/petugas
- Monitoring kinerja perpustakaan
- Laporan bulanan/tahunan

---

### 2.3 `sp_laporan_peminjaman(p_tanggal_awal, p_tanggal_akhir)`
**Fungsi**: Menampilkan laporan peminjaman dalam periode tertentu

**Parameter**:
- `p_tanggal_awal` (DATE) - Tanggal mulai periode
- `p_tanggal_akhir` (DATE) - Tanggal akhir periode

**Output Columns**:
- `id_peminjaman` - ID transaksi peminjaman
- `nomor_identitas` - NIS/NIP/ID pengunjung
- `nama_peminjam` - Nama lengkap peminjam
- `judul_buku` - Judul buku yang dipinjam
- `tanggal_pinjam` - Tanggal mulai pinjam
- `tanggal_jatuh_tempo` - Deadline pengembalian
- `tanggal_kembali` - Tanggal aktual dikembalikan
- `status_peminjaman` - Status (Dipinjam/Dikembalikan/Terlambat)
- `denda` - Denda tercatat (Rupiah)
- `denda_seharusnya` - Denda hasil kalkulasi `fn_hitung_denda`

**Contoh Penggunaan**:
```sql
-- Laporan Desember 2025
CALL sp_laporan_peminjaman('2025-12-01', '2025-12-31');

-- Laporan tahun 2025
CALL sp_laporan_peminjaman('2025-01-01', '2025-12-31');
```

**Kegunaan**:
- Laporan periodik (harian/bulanan/tahunan)
- Export data ke Excel
- Audit trail transaksi

---

### 2.4 `sp_peminjaman_terlambat()`
**Fungsi**: Menampilkan semua peminjaman yang terlambat saat ini

**Parameter**: Tidak ada

**Output Columns**:
- `id_peminjaman` - ID transaksi
- `nomor_identitas` - NIS/NIP pengunjung
- `nama_peminjam` - Nama peminjam
- `no_hp` - Nomor HP (untuk reminder/notifikasi)
- `judul_buku` - Buku yang dipinjam
- `tanggal_pinjam` - Tanggal pinjam
- `tanggal_jatuh_tempo` - Deadline
- `hari_terlambat` - Jumlah hari terlambat (real-time)
- `denda_berjalan` - Denda yang terus bertambah (dari `fn_hitung_denda`)
- `status_peminjaman` - Status saat ini

**Contoh Penggunaan**:
```sql
CALL sp_peminjaman_terlambat();
```

**Sample Output**:
| id_peminjaman | nama_peminjam | no_hp | judul_buku | hari_terlambat | denda_berjalan |
|---------------|---------------|--------|------------|----------------|----------------|
| 17 | Siswa 5 | 08123456789 | FUGIAT TEMPORE... | 14 | 7000.00 |

**Kegunaan**:
- Alert/reminder untuk petugas
- SMS/WhatsApp notification ke pengunjung
- Monitoring keterlambatan real-time

---

### 2.5 `sp_statistik_pengunjung(p_nomor_identitas)`
**Fungsi**: Menampilkan profil dan statistik individual pengunjung

**Parameter**:
- `p_nomor_identitas` (VARCHAR) - NIS/NIP/ID unik pengunjung

**Output Columns**:
- `nomor_identitas` - ID pengunjung
- `nama` - Nama lengkap
- `email` - Email
- `tipe_anggota` - Siswa/Guru/Staf/Umum
- `status_keanggotaan` - Aktif/Tidak Aktif/Dibekukan
- `total_peminjaman` - Total riwayat peminjaman (dari `fn_total_peminjaman`)
- `status_pinjam` - BOLEH/TIDAK BOLEH (dari `fn_boleh_pinjam`)
- `sedang_dipinjam` - Jumlah buku sedang dipinjam saat ini
- `total_denda` - Total denda yang pernah/sedang ada

**Contoh Penggunaan**:
```sql
CALL sp_statistik_pengunjung('SIS0005');
```

**Kegunaan**:
- Profil pengunjung di dashboard user
- Validasi sebelum peminjaman
- Customer service lookup

---

### 2.6 `sp_update_status_terlambat()`
**Fungsi**: Update otomatis status peminjaman yang lewat jatuh tempo menjadi "Terlambat"

**Parameter**: Tidak ada

**Return**: Pesan berapa peminjaman yang di-update

**Logika**:
```sql
UPDATE peminjaman
SET status_peminjaman = 'Terlambat',
    denda = fn_hitung_denda(tanggal_jatuh_tempo, NULL)
WHERE status_peminjaman = 'Dipinjam'
  AND tanggal_jatuh_tempo < CURDATE();
```

**Contoh Penggunaan**:
```sql
CALL sp_update_status_terlambat();
-- Output: "Berhasil update 3 peminjaman menjadi status Terlambat"
```

**Kegunaan**:
- Cron job harian (dijalankan setiap hari jam 00:01)
- Manual cleanup oleh admin
- Maintenance rutin database

---

## 3. Functions

Database memiliki **5 Functions** untuk kalkulasi dan validasi.

### 3.1 `fn_boleh_pinjam(p_nomor_identitas)`
**Fungsi**: Cek apakah pengunjung boleh pinjam buku (validasi batas maksimal)

**Parameter**:
- `p_nomor_identitas` (VARCHAR) - ID pengunjung

**Return Type**: `VARCHAR(20)`

**Return Value**:
- `'BOLEH'` - Jumlah pinjaman aktif < 2
- `'TIDAK BOLEH'` - Sudah mencapai batas maksimal (2 buku)

**Logika**:
```sql
DECLARE v_jumlah_dipinjam INT;
DECLARE v_max_pinjam INT DEFAULT 2;

SELECT COUNT(*) INTO v_jumlah_dipinjam
FROM peminjaman
WHERE nomor_identitas = p_nomor_identitas
  AND status_peminjaman = 'Dipinjam';

IF v_jumlah_dipinjam < v_max_pinjam THEN
    RETURN 'BOLEH';
ELSE
    RETURN 'TIDAK BOLEH';
END IF;
```

**Contoh Penggunaan**:
```sql
SELECT fn_boleh_pinjam('SIS0005');  -- Output: 'BOLEH'
SELECT fn_boleh_pinjam('SIS0010');  -- Output: 'TIDAK BOLEH'
```

**Kegunaan**:
- Validasi sebelum peminjaman
- Tampilan status di UI pengunjung
- Digunakan oleh `sp_statistik_pengunjung`

---

### 3.2 `fn_cek_ketersediaan(p_kode_buku)`
**Fungsi**: Cek status ketersediaan buku berdasarkan stok

**Parameter**:
- `p_kode_buku` (VARCHAR) - Kode unik buku

**Return Type**: `VARCHAR(20)`

**Return Value**:
- `'BANYAK'` - Stok > 5
- `'TERBATAS'` - Stok 1-5
- `'HABIS'` - Stok = 0

**Logika**:
```sql
DECLARE v_stok INT;

SELECT stok_tersedia INTO v_stok
FROM buku
WHERE kode_buku = p_kode_buku;

IF v_stok > 5 THEN
    RETURN 'BANYAK';
ELSEIF v_stok > 0 THEN
    RETURN 'TERBATAS';
ELSE
    RETURN 'HABIS';
END IF;
```

**Contoh Penggunaan**:
```sql
SELECT judul, stok_tersedia, fn_cek_ketersediaan(kode_buku) AS status
FROM buku
WHERE kode_buku = 'BK003';
```

**Kegunaan**:
- Badge status di katalog buku
- Alert stok menipis
- Digunakan oleh `sp_buku_populer`

---

### 3.3 `fn_hitung_denda(p_tanggal_jatuh_tempo, p_tanggal_kembali)`
**Fungsi**: Hitung denda keterlambatan berdasarkan hari terlambat

**Parameter**:
- `p_tanggal_jatuh_tempo` (DATE) - Deadline pengembalian
- `p_tanggal_kembali` (DATE) - Tanggal aktual dikembalikan (NULL = belum dikembalikan)

**Return Type**: `DECIMAL(10,2)`

**Tarif Denda**: Rp 500/hari

**Logika**:
```sql
DECLARE v_hari_terlambat INT;
DECLARE v_tarif_denda DECIMAL(10,2) DEFAULT 500.00;
DECLARE v_total_denda DECIMAL(10,2);

-- Jika belum dikembalikan, hitung dari hari ini
IF p_tanggal_kembali IS NULL THEN
    SET v_hari_terlambat = DATEDIFF(CURDATE(), p_tanggal_jatuh_tempo);
ELSE
    SET v_hari_terlambat = DATEDIFF(p_tanggal_kembali, p_tanggal_jatuh_tempo);
END IF;

-- Kalkulasi denda
IF v_hari_terlambat <= 0 THEN
    SET v_total_denda = 0;
ELSE
    SET v_total_denda = v_hari_terlambat * v_tarif_denda;
END IF;

RETURN v_total_denda;
```

**Contoh Penggunaan**:
```sql
-- Buku dikembalikan terlambat 7 hari
SELECT fn_hitung_denda('2025-12-10', '2025-12-17');  -- Output: 3500.00

-- Buku belum dikembalikan, jatuh tempo 2025-12-01 (hari ini 2025-12-27)
SELECT fn_hitung_denda('2025-12-01', NULL);  -- Output: 13000.00
```

**Kegunaan**:
- Kalkulasi real-time denda berjalan
- Validasi saat pengembalian
- Digunakan oleh `sp_update_status_terlambat`, `sp_peminjaman_terlambat`, `sp_laporan_peminjaman`

---

### 3.4 `fn_rating_buku(p_kode_buku)`
**Fungsi**: Hitung rating rata-rata buku dari semua ulasan

**Parameter**:
- `p_kode_buku` (VARCHAR) - Kode unik buku

**Return Type**: `DECIMAL(3,2)`

**Return Value**: Rating 0.00 - 5.00 (2 desimal)

**Logika**:
```sql
DECLARE v_avg_rating DECIMAL(3,2);

SELECT COALESCE(AVG(rating), 0) INTO v_avg_rating
FROM ulasan_buku
WHERE kode_buku = p_kode_buku;

RETURN ROUND(v_avg_rating, 2);
```

**Contoh Penggunaan**:
```sql
SELECT judul, fn_rating_buku(kode_buku) AS rating_rata
FROM buku
WHERE kode_buku = 'BK055';  -- Output: 4.75
```

**Kegunaan**:
- Display rating bintang di katalog
- Sorting buku berdasarkan rating
- Digunakan oleh `sp_buku_populer`

---

### 3.5 `fn_total_peminjaman(p_nomor_identitas)`
**Fungsi**: Hitung total riwayat peminjaman pengunjung (lifetime)

**Parameter**:
- `p_nomor_identitas` (VARCHAR) - ID pengunjung

**Return Type**: `INT`

**Logika**:
```sql
DECLARE v_total INT;

SELECT COUNT(*) INTO v_total
FROM peminjaman
WHERE nomor_identitas = p_nomor_identitas;

RETURN v_total;
```

**Contoh Penggunaan**:
```sql
SELECT nama, fn_total_peminjaman(nomor_identitas) AS total_peminjaman
FROM pengunjung
WHERE nomor_identitas = 'SIS0005';  -- Output: 15
```

**Kegunaan**:
- Badge "Active Reader" untuk member
- Loyalty/gamification system
- Digunakan oleh `sp_statistik_pengunjung`

---

## 4. Views

Database memiliki **13 Views** untuk kemudahan query. (Detail lengkap bisa dilihat di dokumentasi terpisah)

**Daftar Views**:
1. `view_katalog_buku` - Katalog buku dengan genre
2. `view_buku_populer` - Buku paling banyak dipinjam
3. `view_aset_lengkap` - Daftar aset buku fisik
4. `view_peminjaman_buku` - Detail peminjaman lengkap
5. `view_peminjaman_terlambat` - Peminjaman yang terlambat
6. `view_detail_peminjaman` - Detail peminjaman
7. `view_profil_peminjam` - Profil user dengan statistik
8. `view_login_hari_ini` - Login harian
9. `view_total_login_hari_ini` - Total login hari ini
10. `view_laporan_denda` - Laporan denda
11. `v_summary_pembayaran_denda` - Summary pembayaran denda
12. `view_detail_ulasan` - Detail ulasan buku
13. `view_statistik_global` - Statistik global

---

## 5. Triggers

Database memiliki **13 Triggers** untuk automasi. (Detail lengkap ada di dokumentasi terpisah)

**Kategori Triggers**:

### Triggers Tabel `buku`:
- `trg_after_buku_update_log` - Logging perubahan
- `trg_before_buku_delete_check_active_loans` - Cegah hapus buku yang dipinjam
- `trg_before_buku_update_prevent_negative` - Cegah stok negatif

### Triggers Tabel `aset_buku`:
- `trg_before_aset_buku_insert_generate_number` - Auto-generate nomor inventaris

### Triggers Tabel `peminjaman`:
- `trg_before_peminjaman_insert_check_account_status` - Validasi akun aktif
- `trg_before_peminjaman_insert_check_max_borrow` - Validasi max 2 buku
- `trg_before_peminjaman_insert_check_unpaid_fine` - Validasi denda unpaid
- `trg_before_peminjaman_update_calculate_fine` - Auto hitung denda
- `trg_after_peminjaman_insert_decrease_stock` - Kurangi stok
- `trg_after_peminjaman_update_increase_stock` - Tambah stok

### Triggers Lainnya:
- `trg_before_request_peminjaman_update_set_date` - Auto set tanggal diproses
- `trg_before_request_perpanjangan_insert_check_limit` - Cek batas perpanjangan
- `trg_after_request_perpanjangan_update_sync_date` - Sync tanggal
- `trg_before_users_insert_format_username` - Format uppercase username
- `trg_before_users_delete_log` - Log penghapusan user

---

## 6. Struktur Tabel

### Tabel Utama

#### 📚 `buku`
Master data buku (judul buku)
```sql
- id_buku INT PK
- judul VARCHAR(255)
- nama_pengarang VARCHAR(100)
- penerbit VARCHAR(100)
- tahun_terbit INT
- jumlah_halaman INT
- gambar VARCHAR(255)
- stok_tersedia INT (auto-update by trigger)
```

#### 📦 `aset_buku`
Aset fisik buku individual
```sql
- id_aset INT PK
- id_buku INT FK
- nomor_inventaris VARCHAR(50) UNIQUE (format: BK-003-001)
- kondisi_buku ENUM('Baik','Rusak Ringan','Rusak Berat')
- catatan TEXT
```

#### 👥 `users`
Data pengguna sistem
```sql
- id_user INT PK
- username VARCHAR(50) UNIQUE
- password VARCHAR(255) (bcrypt hash)
- nama VARCHAR(100)
- tipe_anggota ENUM('Siswa','Guru','Kepala Sekolah','Staf','Umum')
- kelas VARCHAR(20)
- status_keanggotaan ENUM('Aktif','Tidak Aktif','Dibekukan')
- role ENUM('admin','petugas','pengunjung','non aktif')
- foto_profil VARCHAR(255)
```

#### 📖 `peminjaman`
Transaksi peminjaman
```sql
- id_peminjaman INT PK
- id_user INT FK
- id_aset_buku INT FK
- tanggal_pinjam DATE
- tanggal_kembali DATE (nullable)
- tanggal_jatuh_tempo DATE
- denda INT (Rupiah)
- status_peminjaman ENUM('Dipinjam','Dikembalikan','Terlambat')
```

#### 🏷️ `genre`
Master genre buku
```sql
- id_genre INT PK
- nama_genre VARCHAR(50) UNIQUE
```

#### 🔗 `buku_genre`
Junction table buku-genre (many-to-many)
```sql
- id_buku INT FK
- id_genre INT FK
```

#### ⭐ `ulasan_buku`
Review dan rating buku
```sql
- id_ulasan INT PK
- id_buku INT FK
- id_user INT FK
- rating INT (1-5)
- komentar TEXT
```

#### 💰 `pembayaran_denda`
Tracking pembayaran denda (support cicilan)
```sql
- id_pembayaran INT PK
- id_peminjaman INT FK
- nominal_bayar INT
- tanggal_bayar DATETIME
- nomor_kwitansi VARCHAR(50) UNIQUE
- metode_bayar ENUM('Cash')
- diterima_oleh INT FK (petugas)
- keterangan TEXT
```

#### 📝 `request_peminjaman`
Request peminjaman (perlu approval)
```sql
- id_request INT PK
- id_user INT FK
- id_buku INT FK
- status ENUM('pending','disetujui','ditolak')
- tanggal_request DATETIME
- diproses_oleh INT FK
- tanggal_diproses DATETIME
- catatan_admin TEXT
```

#### 🔄 `request_perpanjangan`
Request perpanjangan waktu pinjam
```sql
- id_request INT PK
- id_peminjaman INT FK
- tanggal_request DATETIME
- status ENUM('pending','disetujui','ditolak')
- tanggal_perpanjangan_baru DATE
- diproses_oleh INT FK
- catatan TEXT
```

#### ⚙️ `aturan_perpustakaan`
Konfigurasi rules (key-value)
```sql
- nama_aturan VARCHAR(50) PK
- isi_aturan VARCHAR(255)
- deskripsi VARCHAR(255)
```

**Aturan yang Ada**:
- `maks_buku_dipinjam` = 2
- `maks_lama_pinjam` = 7 hari
- `maks_perpanjangan` = 1 kali
- `hari_perpanjangan` = 7 hari
- `denda_per_hari` = Rp 500
- `nama_perpustakaan` = "Perpustakaan Digital SMA N 1 Pangururan"

#### 📊 `log_aktivitas`
Audit trail/logging
```sql
- id_log INT PK
- id_user INT
- username VARCHAR(50)
- nama_tabel VARCHAR(100)
- operasi ENUM('insert','update','delete')
- deskripsi TEXT
- id_terkait VARCHAR(50)
- data_lama TEXT
- data_baru TEXT
- timestamp TIMESTAMP
```

#### 🔐 `login_event`
Tracking login/logout
```sql
- id_login INT PK
- id_user INT FK
- waktu_login DATETIME
- waktu_logout DATETIME (nullable)
- sumber VARCHAR(50) (web/mobile)
```

---

## 📊 Diagram Alur Peminjaman

```
┌─────────────────────────────────────────────────┐
│ 1. User Request Peminjaman                      │
│    INSERT INTO request_peminjaman                │
└──────────────┬──────────────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────────────┐
│ 2. Petugas Approve                               │
│    - fn_boleh_pinjam() → validasi max 2 buku    │
│    - Cek denda unpaid (trigger)                  │
│    - Cek status akun aktif (trigger)             │
└──────────────┬──────────────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────────────┐
│ 3. INSERT INTO peminjaman                        │
│    Triggers:                                     │
│    - Auto kurangi stok buku                      │
│    - Set tanggal_jatuh_tempo = +7 hari          │
└──────────────┬──────────────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────────────┐
│ 4. Jika Terlambat                                │
│    - sp_update_status_terlambat()                │
│    - fn_hitung_denda() → kalkulasi denda         │
└──────────────┬──────────────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────────────┐
│ 5. Pengembalian Buku                             │
│    UPDATE peminjaman SET tanggal_kembali         │
│    Triggers:                                     │
│    - Auto hitung denda (fn_hitung_denda)         │
│    - Auto tambah stok buku                       │
│    - Log aktivitas                               │
└──────────────┬──────────────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────────────┐
│ 6. Bayar Denda (jika ada)                        │
│    INSERT INTO pembayaran_denda                  │
│    - Support cicilan                             │
│    - v_summary_pembayaran_denda → cek status     │
└─────────────────────────────────────────────────┘
```

---

## 🎯 Best Practices Penggunaan

### 1. Daily Cron Jobs
Jalankan setiap hari jam 00:01:
```sql
CALL sp_update_status_terlambat();
```

### 2. Dashboard Admin
Query statistik lengkap:
```sql
CALL sp_dashboard_statistik();
```

### 3. Reminder Keterlambatan
Ambil daftar untuk kirim notifikasi:
```sql
CALL sp_peminjaman_terlambat();
```

### 4. Laporan Bulanan
Export data peminjaman:
```sql
CALL sp_laporan_peminjaman('2025-12-01', '2025-12-31');
```

### 5. Cek Status User Sebelum Pinjam
```sql
SELECT 
    fn_boleh_pinjam('SIS0005') AS boleh_pinjam,
    * 
FROM pengunjung 
WHERE nomor_identitas = 'SIS0005';
```

### 6. Display Buku Populer
```sql
CALL sp_buku_populer();
```

---

## 📈 Keunggulan Sistem

### ✅ Automated
- Auto-generate nomor inventaris
- Auto-update stok saat pinjam/kembali
- Auto-hitung denda keterlambatan
- Auto-log semua aktivitas penting

### ✅ Data Integrity
- Foreign Key constraints
- Triggers untuk validasi business rules
- Unique constraints (username, nomor_inventaris, nomor_kwitansi)
- ENUM untuk nilai terbatas

### ✅ Business Logic Enforcement
- Max 2 buku per user (configurable)
- Tidak bisa pinjam jika ada denda unpaid
- Tidak bisa hapus buku yang sedang dipinjam
- Max 1x perpanjangan per buku

### ✅ Flexible & Configurable
- Tarif denda bisa diubah di `aturan_perpustakaan`
- Max peminjaman configurable
- Support berbagai tipe anggota

### ✅ Auditable
- Semua aktivitas ter-log
- Tracking login/logout
- History pembayaran denda

### ✅ Performance Optimized
- Views untuk query kompleks
- Functions untuk kalkulasi berulang
- Stored Procedures untuk laporan

---

## 🔐 Security Features

1. **Password Hashing**: Bcrypt
2. **Role-Based Access**: admin/petugas/pengunjung/non aktif
3. **Audit Trail**: Log semua aktivitas
4. **Data Validation**: Triggers & Functions
5. **Referential Integrity**: Foreign Keys

---

## 📞 Support & Maintenance

### Maintenance Rutin
- **Harian**: Jalankan `sp_update_status_terlambat()`
- **Mingguan**: Review `log_aktivitas`
- **Bulanan**: Backup database
- **Tahunan**: Cleanup data lama

### Monitoring
- Monitor dari `sp_dashboard_statistik()`
- Alert jika stok < 5 (dari `fn_cek_ketersediaan`)
- Track keterlambatan dari `sp_peminjaman_terlambat()`

---

**Dokumentasi dibuat untuk**: Presentasi Tugas Sistem Basis Data  
**Tim**: Perpustakaan SMA N 1 Pangururan  
**Tanggal**: 27 Desember 2025  
**Database Version**: db_perpustakaan_sma1pangururan (12).sql
