refactor(conflicts): one ConflictDetail builder for the three row shapes

ListConflicts, GetConflict, and the SSR media-detail active-conflict
lookup each hand-mapped their sqlc row (list-by-user, get-by-id,
list-by-media-item) into ConflictDetailResponse, triplicating the
optional resolution tail — including the silently-swallowed
ResolutionData unmarshal error, three times. NewConflictDetail is the
single mapper; a malformed resolution blob now logs instead of
vanishing.

Also extracts koreaderSyncEndpoints (the KOReader URL map duplicated
verbatim between token rotation and device approval; kobo's two URL
sets stay local because they deliberately differ).

Verified in the test-runner container (host conflict tests fail
environmentally on the container-only uploads path — baseline behavior).
This commit is contained in:
John O'Keefe committed 2026-10-17 16:42:37 -04:00
1 parent 58fbe372e2
commit b47a2b86a7
3 files changed
+62 -55

No files matched your search

+13 -6
View File
@@ -217,6 +217,17 @@ func (h *DeviceHandler) CheckRegistrationStatus(c *echo.Context) error {
})
}
// koreaderSyncEndpoints is the KOReader endpoint map shared by the
// surfaces that publish it (KOReader authenticates by header, so its
// URLs never embed the token).
func koreaderSyncEndpoints(baseURL string) map[string]string {
return map[string]string{
"progress": fmt.Sprintf("%s/api/sync/koreader/progress", baseURL),
"metadata": fmt.Sprintf("%s/api/sync/koreader/metadata", baseURL),
"bookmarks": fmt.Sprintf("%s/api/sync/koreader/bookmarks", baseURL),
}
}
// deviceToInfo is the single Devices->DeviceInfo mapper for every
// device surface. AuthToken rides only on surfaces that deliberately
// expose it (the owner's device lists).
@@ -483,9 +494,7 @@ func (h *DeviceHandler) RegenerateDeviceToken(c *echo.Context) error {
syncURLs["bookmark"] = fmt.Sprintf("%s/api/sync/kobo/%s/bookmark", baseURL, newToken)
syncURLs["init"] = fmt.Sprintf("%s/api/sync/kobo/%s/v1/initialization", baseURL, newToken)
case "koreader":
syncURLs["progress"] = fmt.Sprintf("%s/api/sync/koreader/progress", baseURL)
syncURLs["metadata"] = fmt.Sprintf("%s/api/sync/koreader/metadata", baseURL)
syncURLs["bookmarks"] = fmt.Sprintf("%s/api/sync/koreader/bookmarks", baseURL)
syncURLs = koreaderSyncEndpoints(baseURL)
}
// Handle HTMX requests - return HTML with page reload script
@@ -626,9 +635,7 @@ func (h *DeviceHandler) ApproveDevice(c *echo.Context) error {
syncEndpoints := map[string]string{}
switch registration.DeviceType {
case "koreader":
syncEndpoints["progress"] = fmt.Sprintf("%s/api/sync/koreader/progress", h.cfg.BaseURL)
syncEndpoints["metadata"] = fmt.Sprintf("%s/api/sync/koreader/metadata", h.cfg.BaseURL)
syncEndpoints["bookmarks"] = fmt.Sprintf("%s/api/sync/koreader/bookmarks", h.cfg.BaseURL)
syncEndpoints = koreaderSyncEndpoints(h.cfg.BaseURL)
case "kobo":
syncEndpoints["markup"] = fmt.Sprintf("%s/api/sync/kobo/markup", h.cfg.BaseURL)
syncEndpoints["library"] = fmt.Sprintf("%s/api/sync/kobo/library", h.cfg.BaseURL)