fe1cc46752
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.
60 lines
1.7 KiB
Go
60 lines
1.7 KiB
Go
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,
|
|
})
|
|
}
|