# ERD inti RIETS

```mermaid
erDiagram
    roles ||--o{ users : assigns
    roles ||--o{ role_permissions : grants
    permissions ||--o{ role_permissions : contains
    users ||--o| employees : owns
    divisions ||--o{ employees : groups
    positions ||--o{ employees : assigns
    buildings ||--o{ floors : contains
    floors ||--o{ rooms : contains
    floors ||--o{ beacons : installs
    floors ||--o{ uwb_anchors : installs
    buildings ||--o{ qr_areas : anchors
    rooms ||--o{ qr_areas : anchors
    employees ||--o{ tracking_sessions : starts
    qr_areas ||--o{ tracking_sessions : validates
    employees ||--|| current_locations : latest
    tracking_sessions ||--o{ location_history : records
    employees ||--o{ location_history : owns
    location_history ||--o| gps_logs : gps_payload
    beacons ||--o{ raw_beacon_scans : observes
    employees ||--o{ room_visits : visits
    rooms ||--o{ room_visits : receives
    employees ||--o{ notifications : receives
    users ||--o{ audit_logs : performs
```

## Kontrak posisi terpadu

Semua location engine menghasilkan struktur yang sama:

- `source`: `gps`, `ble`, `uwb`, `rfid`, atau adapter berikutnya.
- `latitude/longitude/altitude`: posisi geografis bila tersedia.
- `floor_id/x/y`: posisi denah indoor bila tersedia.
- `accuracy_m`, `speed_mps`, `heading_deg`, waktu observasi, baterai, dan jaringan.
- `client_event_id`: idempotency key dari perangkat agar retry offline tidak menggandakan data.

`current_locations` hanya menyimpan posisi terbaru. `location_history` menyimpan perjalanan. Tabel sumber seperti `gps_logs` menyimpan atribut khusus engine tanpa mengubah kontrak utama.

