Sync controller sekarang pake ViolationService::recordViolation()
biar notifikasi realtime (AppNotification + broadcast event)
dan pengecekan SP threshold tetap jalan untuk data dari E-Jurnal.
ViolationService: recordViolation() & generateSpLetter()
diubah jadi nullable userId supaya bisa dipanggil tanpa user
(0 = system-generated dari sync)