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
|
// 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
|
// GetProgressHistory retrieves reading session history
|
||||||
func (h *Handler) GetProgressHistory(c *echo.Context) error {
|
func (h *Handler) GetProgressHistory(c *echo.Context) error {
|
||||||
user := MustGetAuthenticatedUser(c)
|
user := MustGetAuthenticatedUser(c)
|
||||||
|
|||||||
Reference in new issue
Block a user