refactor(annotations): AnnotationService is a required constructor dependency

H1's doctrine applied to the annotation service, which had been left on
setters: NewMediaHandler/NewKoboHandler/NewKOReaderHandler/
NewSyncQueueProcessor(WithConfig) now take it as a parameter; the four
SetAnnotationService setters are deleted; wiring updated (main.go,
router/sync.go, test harness).

With the service unskippable, the 18 nil-guards and their plain-query
fallbacks die:
- media.go: the create fallbacks for notes/highlights/bookmarks (the
  bookmark one was the H3 census's Bug #1 — it dropped
  percentage/chapter_reference the sync path carries), the highlight
  PUT fallback, and the three delete-path plain deletes (tombstone is
  now the only delete semantics).
- kobo.go: both markup-ingest annotation loops (the bookmark fallback
  wrote the text into media_notes — a category error the fallback
  never should have had).
- koreader.go: all three push-stack guards.
- queue.go: the three "annotation service not available" errors in
  syncNote/syncHighlight/syncBookmark.

Behavior note: the deleted highlight create/PUT fallbacks were the only
paths passing note_id to the plain query — the sync service has no
NoteID field, so the web's highlight→note link was already being
dropped on the live path; this commit makes that pre-existing
limitation explicit rather than papering it over (surfacing note_id on
SaveHighlightRequest is left for a behavior commit that needs it).

Pins (now 20 incl. the 3 annotation CRUD suites) + H1 tests + both
unit suites green.
This commit is contained in:
John O'Keefe committed 2026-10-17 15:47:57 -04:00
1 parent ff029f1ad5
commit c579179fee
9 files changed
+290 -564

No files matched your search

+3 -6
View File
@@ -130,8 +130,7 @@ func main() {
maintenanceCancel := annotationService.StartDailyMaintenance()
defer maintenanceCancel()
queueProcessor := sync.NewSyncQueueProcessorWithConfig(queries, progressService, registry.SyncQueueConfig().Interval, registry.SyncQueueConfig().BatchSize)
queueProcessor.SetAnnotationService(annotationService)
queueProcessor := sync.NewSyncQueueProcessorWithConfig(queries, progressService, annotationService, registry.SyncQueueConfig().Interval, registry.SyncQueueConfig().BatchSize)
// Create library service
libraryService := services.NewLibraryService(queries)
@@ -147,8 +146,7 @@ func main() {
worker := services.NewWorkerWithConfig(workerCfg.Size, workerCfg.QueueCap, connManager)
services.WorkerInstance = worker
koreaderHandler := handlers.NewKOReaderHandler(queries, connManager, queueProcessor, progressService)
koreaderHandler.SetAnnotationService(annotationService)
koreaderHandler := handlers.NewKOReaderHandler(queries, connManager, queueProcessor, progressService, annotationService)
koreaderHandler.SetLibraryService(libraryService)
wsHandler := handlers.NewWSHandler(queries, connManager, cfg.JWTSecret, deviceAuthMiddleware)
conflictHandler := handlers.NewConflictHandler(queries, connManager, progressService)
@@ -167,8 +165,7 @@ func main() {
dashboardHandler := handlers.NewDashboardHandler(queries)
seriesHandler := handlers.NewSeriesHandler(queries)
filtersHandler := handlers.NewFiltersHandler(queries)
mediaHandler := handlers.NewMediaHandler(queries, libraryService, progressService)
mediaHandler.SetAnnotationService(annotationService)
mediaHandler := handlers.NewMediaHandler(queries, libraryService, progressService, annotationService)
matchingHandler := handlers.NewMatchingHandler(queries, connManager)
jobsHandler := handlers.NewJobsHandler(queries, worker)
+3 -5
View File
@@ -483,12 +483,11 @@ func setupTestServer(t *testing.T) *TestServerSetup {
progressService := wsync.NewProgressService(queries, connManager)
annotationService := wsync.NewAnnotationService(queries, connManager)
queueProcessor := wsync.NewSyncQueueProcessor(queries, progressService)
queueProcessor := wsync.NewSyncQueueProcessor(queries, progressService, annotationService)
queueCtx, queueCancel := context.WithCancel(context.Background())
go queueProcessor.Start(queueCtx)
koreaderHandler := handlers.NewKOReaderHandler(queries, connManager, queueProcessor, progressService)
koreaderHandler.SetAnnotationService(annotationService)
koreaderHandler := handlers.NewKOReaderHandler(queries, connManager, queueProcessor, progressService, annotationService)
wsHandler := handlers.NewWSHandler(queries, connManager, cfg.JWTSecret, deviceAuthMiddleware)
conflictHandler := handlers.NewConflictHandler(queries, connManager, progressService)
analyticsHandler := handlers.NewAnalyticsHandler(queries)
@@ -508,8 +507,7 @@ func setupTestServer(t *testing.T) *TestServerSetup {
statisticsService := services.NewStatisticsService(queries)
statsHandler := handlers.NewStatsHandler(statisticsService)
seriesHandler := handlers.NewSeriesHandler(queries)
mediaHandler := handlers.NewMediaHandler(queries, libraryService, progressService, worker)
mediaHandler.SetAnnotationService(annotationService)
mediaHandler := handlers.NewMediaHandler(queries, libraryService, progressService, annotationService, worker)
matchingHandler := handlers.NewMatchingHandler(queries, connManager)
// Create conversion service for OPDS