feat(api): capture contextual_likes on like during open play_event
Two new helpers in internal/playevents (CaptureContextualLikeIfPlaying, SoftDeleteContextualLikes) called by both api and subsonic surfaces. Like inserts a new contextual_likes row when LikeTrack actually inserted (rows=1) AND there's an open play_event with a vector. Unlike soft-deletes via deleted_at. Idempotent in both directions. Subsonic wiring lands in the next commit.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
package playevents
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
|
||||
)
|
||||
|
||||
// CaptureContextualLikeIfPlaying snapshots the user's currently-playing
|
||||
// session context into a new contextual_likes row. No-op if no open
|
||||
// play_event exists or its session_vector is NULL. Failures are logged
|
||||
// but never returned to the caller — contextual capture is best-effort
|
||||
// and must not break the like response.
|
||||
func CaptureContextualLikeIfPlaying(
|
||||
ctx context.Context,
|
||||
q *dbq.Queries,
|
||||
userID, trackID pgtype.UUID,
|
||||
logger *slog.Logger,
|
||||
) error {
|
||||
event, err := q.GetOpenPlayEventForUser(ctx, userID)
|
||||
if err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil // no play in progress; nothing to capture
|
||||
}
|
||||
logger.Error("playevents: get open play_event", "err", err)
|
||||
return nil // best-effort
|
||||
}
|
||||
if event.SessionVectorAtPlay == nil {
|
||||
return nil // event predates this slice; no vector to snapshot
|
||||
}
|
||||
if err := q.InsertContextualLike(ctx, dbq.InsertContextualLikeParams{
|
||||
UserID: userID,
|
||||
TrackID: trackID,
|
||||
SessionVector: event.SessionVectorAtPlay,
|
||||
SessionID: event.SessionID,
|
||||
}); err != nil {
|
||||
logger.Error("playevents: insert contextual_like", "err", err)
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SoftDeleteContextualLikes marks all currently-active contextual_likes
|
||||
// rows for (user, track) as deleted. Idempotent.
|
||||
func SoftDeleteContextualLikes(
|
||||
ctx context.Context,
|
||||
q *dbq.Queries,
|
||||
userID, trackID pgtype.UUID,
|
||||
) error {
|
||||
return q.SoftDeleteContextualLikesForUserTrack(ctx, dbq.SoftDeleteContextualLikesForUserTrackParams{
|
||||
UserID: userID,
|
||||
TrackID: trackID,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user