๐๏ธ Struktur Database
JSON file per tabel di API/database/*.json (driver json, bisa switch sqlite/mysql/pgsql via API/config/database.php). Kunci target notifikasi: tabel notification_nups (NUP-locked, JOIN saat fetch).
Diagram Relasi
erDiagram
EMPLOYEES ||--o{ ATTENDANCES : "nup"
EMPLOYEES ||--o{ DEVICE_NOTIFICATIONS : "token = device_id"
NOTIFICATIONS ||--o{ DEVICE_NOTIFICATIONS : "notification_id"
NOTIFICATIONS ||--o{ NOTIFICATION_NUPS : "id_notification"
NOTIFICATION_NUPS }o--o{ EMPLOYEES : "target_nup = nup"
DEVICES ||--o{ DEVICE_NOTIFICATIONS : "device_id"
EMPLOYEES {
int id PK
string nama
string nup "unik, kunci target"
string email
string unit_kerja
string jabatan
string status_pegawai
string device_uuid "sesi device aktif"
string token "auth per-pegawai"
}
ATTENDANCES {
int id PK
string nup FK
string tanggal "YYYY-MM-DD, unik per nup"
string jam_masuk "HH:MM"
string jam_pulang "HH:MM nullable"
}
NOTIFICATIONS {
int id PK
string title
string body
string priority "low/normal/high"
string link "lampiran nullable"
string data "JSON opsional nullable"
int is_broadcast "1 = semua device"
string deleted_at "soft delete nullable"
}
NOTIFICATION_NUPS {
int id PK
int id_notification FK
string target_nup "NUP tujuan, kunci"
}
DEVICE_NOTIFICATIONS {
int id PK
string device_id "token pegawai / device"
int notification_id FK
int acknowledged "0/1"
string acknowledged_at "nullable"
}
DEVICES {
int id PK
string device_id
string device_name
string platform
}
employees โ Data Pegawai
| Kolom | Tipe | Keterangan |
id | int auto | Primary key |
nama | string | Nama lengkap (wajib) |
nup | string | NUP/NIP, unik โ kunci target notifikasi & absensi (wajib) |
email | string | Fallback cocokkan akun Keycloak |
unit_kerja | string | Unit kerja |
jabatan | string | Jabatan |
status_pegawai | string | Aktif/TETAP/PKWT/P2K/KONTRAK/Nonaktif |
device_uuid | string | Device sesi aktif (binding 1 akun = 1 HP) |
token | string | Auth per-pegawai, auto bin2hex(random_bytes(16)), bisa regenerate |
notifications โ Pesan
| Kolom | Tipe | Keterangan |
id | int auto | Primary key |
title / body | string | Judul & isi (wajib) |
priority | string | low/normal/high |
link | string|null | Link lampiran dokumen |
data | JSON string|null | Payload opsional bebas |
is_broadcast | 0/1 | 1 = semua device (tanpa target) |
deleted_at | datetime|null | Soft delete โ tersembunyi dari device, tampil di admin + bisa restore |
notification_nups โ Ikatan NOTIFICATIONS โ NUP
| Kolom | Tipe | Keterangan |
id | int auto | Primary key |
id_notification | int | FK ke notifications โ kunci target |
target_nup | string | NUP/NIP tujuan, unik per notifikasi |
Ditulis bulk 1x (insertMany) saat broadcast โ 501 baris 0,008 dtk. Fetch bangun peta id_notification โ [target_nup] 1x per request + gabung fallback JSON legacy.
device_notifications โ Pengiriman & status baca
| Kolom | Tipe | Keterangan |
device_id | string | Token pegawai / ID device |
notification_id | int | FK ke notifications |
acknowledged | 0/1 | 1 = sudah dibaca |
acknowledged_at | datetime|null | Waktu dibaca |
Baris hanya dibuat untuk target device eksplisit, broadcast semua, dan ack on-demand โ target NUP tak dibuatkan baris di sini melainkan di notification_nups (fetch cocokkan langsung, tulis O(1)).
attendances โ Absensi view-only
| Kolom | Tipe | Keterangan |
nup + tanggal | string | Unik per pasangan (upsert) |
jam_masuk / jam_pulang | HH:MM | Pulang boleh null (belum absen pulang) |
devices โ Perangkat terdaftar
| Kolom | Tipe | Keterangan |
device_id | string | ID unik perangkat |
device_name / platform / last_seen | string | Info perangkat & terakhir terlihat |
Catatan
- Semua tabel otomatis punya
created_at (Y-m-d H:i:s), tabel employees/attendances juga updated_at.
- Rotate token pegawai tak memutus pengiriman: fetch cocokkan
NUP dulu via target_nups.
- Retensi: pesan > 6 bulan tak tampil di device (admin log tetap full).
- Kapasitas teruji: 150 rb NUP โ tulis bulk 501 baris 0,008 dtk, fetch via JOIN 1x per request. Device hanya terima
target_nups_count, bukan daftarnya; admin terima max 200 (tooltip) + total.
- Kolom
target_nups dihapus dari notifications (diganti JOIN tabel). Baris lama yang masih membawanya dimigrasi malas ke tabel + kolom dihapus saat pertama dibaca.
- Soft delete:
DELETE /notifications/{id} isi deleted_at (admin only), POST /notifications/{id}/restore pulihkan. Device tak lihat yang terhapus; admin tampil badge + tombol pulihkan.
- Field hitungan (
acknowledged, target_nups_count, target_summary, targets_count) dihitung saat response, tak tersimpan di file.