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)