chore(server): delete dead unrouted UpdateUniversalProgress handler
Handler.UpdateUniversalProgress (handlers/progress.go) had no route registration anywhere (router/progress.go only wires the history route to the scanner handler) and no callers — a legacy progress-write path that bypassed the verify/heal pipeline entirely. Deleting it removes the last bypass-shaped writer that could poison progress rows without verification; conflict-resolution apply remains the only deliberate direct write (user-approved winner rows). Pure deletion: 115 lines, no route, no callers, no behavior change.
This commit is contained in:
1 parent
69516ae165
commit
4f05a232fe
1 file changed
-115
@@ -97,121 +97,6 @@ func (h *Handler) GetUniversalProgress(c *echo.Context) error {
|
||||
}
|
||||
|
||||
// UpdateUniversalProgress updates progress with automatic conversion
|
||||
func (h *Handler) UpdateUniversalProgress(c *echo.Context) error {
|
||||
user := MustGetAuthenticatedUser(c)
|
||||
|
||||
mediaItemID, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "invalid media item ID")
|
||||
}
|
||||
|
||||
var req struct {
|
||||
Source string `json:"source"`
|
||||
Location struct {
|
||||
Percentage *float64 `json:"percentage"`
|
||||
Page *int `json:"page"`
|
||||
TotalPages *int `json:"total_pages"`
|
||||
Epubcfi *string `json:"epubcfi"`
|
||||
Character *int64 `json:"character"`
|
||||
Chapter *int `json:"chapter"`
|
||||
ViewportY *float64 `json:"viewport_y"`
|
||||
} `json:"location"`
|
||||
DeviceMetadata struct {
|
||||
DeviceType string `json:"device_type"`
|
||||
UserAgent string `json:"user_agent"`
|
||||
} `json:"device_metadata"`
|
||||
}
|
||||
|
||||
if err := c.Bind(&req); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "invalid request body")
|
||||
}
|
||||
|
||||
mediaItem, err := h.db.GetMediaItem(context.Background(), pgtype.UUID{Bytes: mediaItemID, Valid: true})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusNotFound, "media item not found")
|
||||
}
|
||||
|
||||
percentage := 0.0
|
||||
if req.Location.Percentage != nil {
|
||||
percentage = *req.Location.Percentage
|
||||
} else if req.Location.Page != nil && req.Location.TotalPages != nil {
|
||||
percentage = wsync.PageToPercentage(*req.Location.Page, *req.Location.TotalPages)
|
||||
}
|
||||
|
||||
currentPage := 0
|
||||
totalPages := 0
|
||||
if req.Location.Page != nil {
|
||||
currentPage = *req.Location.Page
|
||||
}
|
||||
if req.Location.TotalPages != nil {
|
||||
totalPages = *req.Location.TotalPages
|
||||
}
|
||||
if mediaItem.PageCount.Valid && mediaItem.PageCount.Int32 > 0 {
|
||||
totalPages = int(mediaItem.PageCount.Int32)
|
||||
}
|
||||
|
||||
var epubcfi pgtype.Text
|
||||
if req.Location.Epubcfi != nil {
|
||||
epubcfi = pgtype.Text{String: *req.Location.Epubcfi, Valid: true}
|
||||
}
|
||||
|
||||
var chapter pgtype.Int4
|
||||
if req.Location.Chapter != nil {
|
||||
chapter = pgtype.Int4{Int32: int32(*req.Location.Chapter), Valid: true}
|
||||
}
|
||||
|
||||
var viewportY pgtype.Float8
|
||||
if req.Location.ViewportY != nil {
|
||||
viewportY = pgtype.Float8{Float64: *req.Location.ViewportY, Valid: true}
|
||||
}
|
||||
|
||||
var lastSyncDevice, lastSyncSource pgtype.Text
|
||||
if req.DeviceMetadata.DeviceType != "" {
|
||||
lastSyncDevice = pgtype.Text{String: req.DeviceMetadata.DeviceType, Valid: true}
|
||||
lastSyncSource = pgtype.Text{String: req.Source, Valid: true}
|
||||
}
|
||||
|
||||
updated, err := h.db.UpdateUniversalProgress(context.Background(), database.UpdateUniversalProgressParams{
|
||||
MediaItemID: pgtype.UUID{Bytes: mediaItemID, Valid: true},
|
||||
UserID: pgtype.UUID{Bytes: user.ID.Bytes, Valid: true},
|
||||
Percentage: pgtype.Float8{Float64: percentage, Valid: true},
|
||||
Epubcfi: epubcfi,
|
||||
Chapter: chapter,
|
||||
ChapterProgress: pgtype.Float8{Float64: percentage, Valid: true},
|
||||
ViewportY: viewportY,
|
||||
LastSyncDevice: lastSyncDevice,
|
||||
LastSyncSource: lastSyncSource,
|
||||
CurrentPage: pgtype.Int4{Int32: int32(currentPage), Valid: true},
|
||||
TotalPages: pgtype.Int4{Int32: int32(totalPages), Valid: true},
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "failed to update progress")
|
||||
}
|
||||
|
||||
// Broadcast progress update to all connected WebSocket clients
|
||||
deviceName := "Web"
|
||||
deviceType := "web"
|
||||
if req.DeviceMetadata.DeviceType != "" {
|
||||
deviceType = req.DeviceMetadata.DeviceType
|
||||
deviceName = req.DeviceMetadata.DeviceType
|
||||
}
|
||||
|
||||
h.connManager.BroadcastProgressUpdate(mediaItemID, percentage, wsync.SourceDevice{
|
||||
ID: uuid.UUID(user.ID.Bytes).String(),
|
||||
Name: deviceName,
|
||||
Type: deviceType,
|
||||
})
|
||||
|
||||
return c.JSON(http.StatusOK, map[string]interface{}{
|
||||
"sync_status": "success",
|
||||
"progress_updated": true,
|
||||
"percentage": percentage,
|
||||
"current_page": currentPage,
|
||||
"total_pages": totalPages,
|
||||
"last_read_at": updated.LastReadAt.Time,
|
||||
})
|
||||
}
|
||||
|
||||
// GetProgressHistory retrieves reading session history
|
||||
func (h *Handler) GetProgressHistory(c *echo.Context) error {
|
||||
user := MustGetAuthenticatedUser(c)
|
||||
|
||||
Reference in new issue
Block a user