All four progress write paths now delegate to ProgressService.SaveProgress:
- MediaHandler: UpdateMediaReadingProgress uses ProgressService for web
saves with richer request body (reading_mode, zoom_level, scroll). GET
now uses GetUniversalProgress query that JOINs media_items for
format_group, total_characters, chapter_count.
- KOReaderHandler: updateProgressForBook delegates to ProgressService.
Fixed device ID bug (was using userID, now uses deviceID). Removed
duplicate UpdateDeviceLastSync with zero UUID. Added pgtype helper
functions (textPtrToPgText, intPtrToPgInt4, int64PtrToPgInt8).
- KoboHandler: all four progress write points (Markup ReadingSync, Markup
last-read-place, AnalyticsGettests, SyncFromServer) delegate to
ProgressService. Fixed empty epubcfi string now correctly set to
Valid: false. SyncFromServer preserves last_sync_source=bookhoard
and Broadcast: false.
- QueueProcessor: syncProgress delegates to ProgressService.
- main.go: creates ProgressService after ConnectionManager, injects via
SetProgressService() on all handlers and queue processor.
Handler tests cover pgtype conversion helpers (textPtrToPgText, etc.)
and device icon mapping.