When a Kobo device pushes a last-read-place bookmark, the server now
converts the KEPUB CFI (with koboSpan wrappers) to a standard EPUB CFI
and extracts surrounding text as context_text for use by other devices
(KOReader, web reader) during their pull-side CFI conversions.
Previously the raw KEPUB CFI was stored verbatim as epubcfi, which
meant foliate and CREngine couldn't resolve it (wrong child indices
due to koboSpan wrappers), and no context_text was available for the
text-search fallback in ConvertStandardToCRE.
Changes:
- kepub_cfi_converter.go: Add ExtractedContext field to
KEPUBConversionResult, populated from the already-computed
searchText in both ConvertKEPUBCFIToStandard and
ConvertStandardCFIToKEPUB (exact-match and percentage-fallback
paths).
- kobo.go: Add libraryService field and SetLibraryService setter
(mirrors KOReaderHandler pattern). Add convertKoboCFIToStandard
helper that resolves EPUB+KEPUB paths, instantiates the converter,
and returns the converted CFI + extracted context. The last-read-place
branch in Markup now calls this helper for reflowable formats,
skipping fixed-layout/comic archives (page-index only).
- router.go: Add LibraryService to router Config.
- sync.go: Wire LibraryService to KoboHandler via SetLibraryService.
- main.go: Pass libraryService through router config.
The conversion is purely additive — if no KEPUB file exists on disk
(e.g. side-loaded EPUB without kepubify conversion), the handler
gracefully skips conversion and stores the raw CFI as before.
- Remove GET /progress/:id and POST /progress/:id from progress routes.
These were superseded by the media-item progress routes. Only
GET /progress/:id/history remains.
- Add ProgressService to router.Config so sync.go can inject it into
KoboHandler via SetProgressService().
- Inject ProgressService into KoboHandler at route registration time
rather than requiring a separate setup step.
- Update comment from 'Legacy progress routes' to 'Progress routes'.
Update all router files to use Echo v5 APIs and type signatures.
Changes in router.go:
- Replace echomiddleware.Logger() with RequestLogger() (line 144)
- Update import from echo/v4 to echo/v5
Changes in frontend.go:
- Update frontend handler signatures to use *echo.Context
- Fix middleware registration for v5 compatibility
Changes in auth.go, library.go, scanner.go, sync.go, helpers.go:
- Update handler function signatures to *echo.Context
- Ensure consistent type usage across all route handlers
All routes now properly implement Echo v5's middleware and handler patterns.
- Implement event queue with 3-second debouncing for file system events
- Add configurable polling fallback (default 3 min) via SCAN_POLL_INTERVAL_MINUTES
- Add SyncFilesystemWithDatabase to detect orphaned DB entries and new files
- Integrate utils.ResolveMediaURL for consistent media file path resolution
- Add COOKIE_SECURE env var with SameSite=LaxMode for session cookies
- Update media handler to properly decode URL paths for file serving
- Refactor scanner initialization to accept poll interval configuration
Critical fixes to prevent goroutine leaks during application shutdown:
1. Sync Queue Processor:
- Changed StartCleanupTask() to return context.CancelFunc
- Modified to accept and watch cancellable context
- Added queue context/cancel to Handler struct
- Created StartBackgroundTasks() method for main handler instance
- Cancel queue processor during shutdown in StopScheduler()
2. Connection Manager:
- Modified StartCleanupTask() to use cancellable context
- Returns cancel function that can be called during shutdown
- Goroutine now properly exits when context is cancelled
3. Handler Lifecycle:
- Added StartBackgroundTasks() to Handler
- Only main handler instance starts background goroutines
- Temporary handler instances (library/sync routes) don't start tasks
- StopScheduler() now properly shuts down all background goroutines
4. Router Integration:
- Updated SetupRoutes to accept queueProcessor parameter
- Main scanner handler starts background tasks after creation
- Library and sync route handlers don't start duplicate tasks
Impact:
- Fixes 2 major goroutine leaks (queue processor + connection cleanup)
- Application now properly shuts down all goroutines on exit
- No more resource leaks from long-running goroutines
- Test added to detect future goroutine regressions
Test: TestGoroutineCleanup verifies background services can be stopped.
Add createJWTMiddleware helper that sets database.Users object in context,
matching the original main.go JWT middleware behavior. This fixes
'authentication context error' panics in handlers that call
MustGetAuthenticatedUser.
Changes:
- Add createJWTMiddleware() in router.go
- Update all route files to use the helper
- Set user claims AND database.Users object in context