๐๏ธ Struktur Database
Tabel SQLite via migration Laravel 10 (framework/database/migrations), driver sqlite default โ bisa switch ke mysql lewat .env. Kunci target notifikasi: tabel notification_nups. Login memakai auth_sessions (multi-login per akun).
Diagram Relasi
erDiagram
EMPLOYEES ||--o{ AUTH_SESSIONS : "employee_id"
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 username "user_id server auth"
string unit_kerja
string jabatan
string status_pegawai
string device_uuid "legacy"
string token "legacy auth per-pegawai"
}
AUTH_SESSIONS {
int id PK
int employee_id FK
string nup "NUP pemilik sesi"
string username "user_id"
string access_token "SHA-256 token"
string auth_payload "output JSON server auth"
string auth_hash "SHA-256 payload"
string revoked_at "null = aktif"
}
NOTIFICATIONS {
int id PK
string title
string body
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
datetime last_seen
}
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) |
username | string|null | User ID dari server auth (user_id), unik โ tanpa email |
unit_kerja | string | Unit kerja |
jabatan | string | Jabatan |
status_pegawai | string | Dari data_pegawai_sisdm.STATUS_PEGAWAI (menggantikan level_id) |
device_uuid | string|null | Legacy, tidak dipakai untuk membatasi login |
token | string | Legacy auth per-pegawai (akses utama kini access token di auth_sessions) |
notifications โ Pesan
| Kolom | Tipe | Keterangan |
id | int auto | Primary key |
title / body | string | Judul & isi (wajib) |
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 saat broadcast via Eloquent firstOrCreate per NUP (NotificationController::attachNups). Fetch bangun peta id_notification โ [target_nup] 1x per request (NotifHelper::buildNupMap), sekaligus memindahkan kolom legacy target_nups bila masih ada.
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)).
auth_sessions โ Sesi login mobile
| Kolom | Tipe | Keterangan |
employee_id / nup / username | int/string | Pemilik sesi (satu akun boleh punya banyak baris) |
access_token | string(64) unik | SHA-256 Bearer token server auth; token asli (format id|secret) dikirim ke client saat login dan disimpan di localStorage |
auth_code | string | Kode login_result (informasi saja, bukan acuan sukses) |
auth_payload | text | Output JSON server auth apa adanya |
auth_hash | string(64) | SHA-256(auth_payload) |
device_uuid, ip_address, user_agent | string|null | Info perangkat/login |
last_used_at / revoked_at | datetime|null | Terakhir dipakai; revoked_at terisi saat logout |
Multi-login: setiap login membuat baris baru. Logout hanya mengisi revoked_at pada token yang dipakai, token lain tetap aktif.
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 punya
created_at/updated_at (timestamp Laravel), kecuali notification_nups hanya created_at.
- Auth utama mobile =
auth_sessions.access_token (hash Bearer token server auth); token pegawai/device hanya fallback legacy.
- Absensi hari ini tidak disimpan ke database (tabel
attendances sudah dihapus); nilainya dibaca langsung dari objek absensi_sikap di server auth.
- 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 tidak ada di skema notifications (diganti tabel notification_nups). Data legacy dari JSON yang masih membawanya dipindah malas ke tabel saat pertama dibaca (buildNupMap).
- 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 (
target_nups_count, target_summary, targets_count) dihitung saat response, tidak disimpan sebagai kolom. Kolom acknowledged tetap tersimpan di device_notifications.