Files
minstrel/internal/db/dbq/requests.sql.go
T
bvandeusenandClaude Opus 5.5 1d4ef1a23f docs: query comments say what each query selects and why, not how it came to be (#6277)
Rewrites the internal/db/queries comments to rule 32 and regenerates
dbq, whose doc comments and embedded SQL carry them. The bugs behind the
tiered mixes, the md5 order seed, the score bands and the round-robin
arms are restated as the constraint each one enforces; counts from one
library and stale cross-references are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 12:31:13 -04:00

529 lines
14 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: requests.sql
package dbq
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const approveRequest = `-- name: ApproveRequest :one
UPDATE requests
SET status = 'approved',
decided_at = now(),
decided_by = $2,
updated_at = now()
WHERE id = $1 AND status = 'pending'
RETURNING id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at
`
type ApproveRequestParams struct {
ID pgtype.UUID
DecidedBy pgtype.UUID
}
func (q *Queries) ApproveRequest(ctx context.Context, arg ApproveRequestParams) (Request, error) {
row := q.db.QueryRow(ctx, approveRequest, arg.ID, arg.DecidedBy)
var i Request
err := row.Scan(
&i.ID,
&i.UserID,
&i.Status,
&i.Kind,
&i.ArtistMbid,
&i.AlbumMbid,
&i.TrackMbid,
&i.ArtistName,
&i.AlbumTitle,
&i.TrackTitle,
&i.DecidedAt,
&i.DecidedBy,
&i.Notes,
&i.CompletedAt,
&i.MatchedTrackID,
&i.MatchedAlbumID,
&i.MatchedArtistID,
&i.RequestedAt,
&i.UpdatedAt,
)
return i, err
}
const cancelRequest = `-- name: CancelRequest :one
UPDATE requests
SET status = 'rejected',
notes = 'cancelled by user',
decided_at = now(),
decided_by = $2,
updated_at = now()
WHERE id = $1 AND user_id = $2 AND status = 'pending'
RETURNING id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at
`
type CancelRequestParams struct {
ID pgtype.UUID
DecidedBy pgtype.UUID
}
// $2 serves as both the ownership guard (user_id = $2) and the
// decided_by audit field. The generated parameter struct names it
// DecidedBy — callers must pass the cancelling user's UUID, and
// a wrong UUID will silently no-op (zero rows updated) rather than
// erroring at the SQL layer.
func (q *Queries) CancelRequest(ctx context.Context, arg CancelRequestParams) (Request, error) {
row := q.db.QueryRow(ctx, cancelRequest, arg.ID, arg.DecidedBy)
var i Request
err := row.Scan(
&i.ID,
&i.UserID,
&i.Status,
&i.Kind,
&i.ArtistMbid,
&i.AlbumMbid,
&i.TrackMbid,
&i.ArtistName,
&i.AlbumTitle,
&i.TrackTitle,
&i.DecidedAt,
&i.DecidedBy,
&i.Notes,
&i.CompletedAt,
&i.MatchedTrackID,
&i.MatchedAlbumID,
&i.MatchedArtistID,
&i.RequestedAt,
&i.UpdatedAt,
)
return i, err
}
const completeRequest = `-- name: CompleteRequest :one
UPDATE requests
SET status = 'completed',
matched_track_id = $2,
matched_album_id = $3,
matched_artist_id = $4,
completed_at = now(),
updated_at = now()
WHERE id = $1 AND status = 'approved'
RETURNING id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at
`
type CompleteRequestParams struct {
ID pgtype.UUID
MatchedTrackID pgtype.UUID
MatchedAlbumID pgtype.UUID
MatchedArtistID pgtype.UUID
}
// Reconciler transitions an approved request to completed when its
// target track/album/artist has appeared in the library. Callers
// should set ONLY the matched_*_id corresponding to the request's
// kind and pass pgtype.UUID{} (Valid: false) for the others —
// per-kind one-of-three is the contract, NULL for the others
// preserves auditability if the matched row is later evicted.
func (q *Queries) CompleteRequest(ctx context.Context, arg CompleteRequestParams) (Request, error) {
row := q.db.QueryRow(ctx, completeRequest,
arg.ID,
arg.MatchedTrackID,
arg.MatchedAlbumID,
arg.MatchedArtistID,
)
var i Request
err := row.Scan(
&i.ID,
&i.UserID,
&i.Status,
&i.Kind,
&i.ArtistMbid,
&i.AlbumMbid,
&i.TrackMbid,
&i.ArtistName,
&i.AlbumTitle,
&i.TrackTitle,
&i.DecidedAt,
&i.DecidedBy,
&i.Notes,
&i.CompletedAt,
&i.MatchedTrackID,
&i.MatchedAlbumID,
&i.MatchedArtistID,
&i.RequestedAt,
&i.UpdatedAt,
)
return i, err
}
const createRequest = `-- name: CreateRequest :one
INSERT INTO requests (
user_id, kind,
artist_mbid, album_mbid, track_mbid,
artist_name, album_title, track_title
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
RETURNING id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at
`
type CreateRequestParams struct {
UserID pgtype.UUID
Kind RequestKind
ArtistMbid string
AlbumMbid *string
TrackMbid *string
ArtistName string
AlbumTitle *string
TrackTitle *string
}
func (q *Queries) CreateRequest(ctx context.Context, arg CreateRequestParams) (Request, error) {
row := q.db.QueryRow(ctx, createRequest,
arg.UserID,
arg.Kind,
arg.ArtistMbid,
arg.AlbumMbid,
arg.TrackMbid,
arg.ArtistName,
arg.AlbumTitle,
arg.TrackTitle,
)
var i Request
err := row.Scan(
&i.ID,
&i.UserID,
&i.Status,
&i.Kind,
&i.ArtistMbid,
&i.AlbumMbid,
&i.TrackMbid,
&i.ArtistName,
&i.AlbumTitle,
&i.TrackTitle,
&i.DecidedAt,
&i.DecidedBy,
&i.Notes,
&i.CompletedAt,
&i.MatchedTrackID,
&i.MatchedAlbumID,
&i.MatchedArtistID,
&i.RequestedAt,
&i.UpdatedAt,
)
return i, err
}
const getNonTerminalRequestForMBID = `-- name: GetNonTerminalRequestForMBID :one
SELECT id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at FROM requests
WHERE status IN ('pending', 'approved', 'completed')
AND ((kind = 'artist' AND artist_mbid = $1)
OR (kind = 'album' AND album_mbid = $1)
OR (kind = 'track' AND track_mbid = $1))
ORDER BY requested_at ASC
LIMIT 1
`
// Returns the oldest non-terminal (pending/approved/completed) request
// whose own-kind MBID matches @mbid, or pgx.ErrNoRows when none. Create()
// uses this to dedupe: a re-request for something already in flight
// returns the existing row instead of inserting a duplicate.
func (q *Queries) GetNonTerminalRequestForMBID(ctx context.Context, mbid string) (Request, error) {
row := q.db.QueryRow(ctx, getNonTerminalRequestForMBID, mbid)
var i Request
err := row.Scan(
&i.ID,
&i.UserID,
&i.Status,
&i.Kind,
&i.ArtistMbid,
&i.AlbumMbid,
&i.TrackMbid,
&i.ArtistName,
&i.AlbumTitle,
&i.TrackTitle,
&i.DecidedAt,
&i.DecidedBy,
&i.Notes,
&i.CompletedAt,
&i.MatchedTrackID,
&i.MatchedAlbumID,
&i.MatchedArtistID,
&i.RequestedAt,
&i.UpdatedAt,
)
return i, err
}
const getRequestByID = `-- name: GetRequestByID :one
SELECT id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at FROM requests WHERE id = $1
`
func (q *Queries) GetRequestByID(ctx context.Context, id pgtype.UUID) (Request, error) {
row := q.db.QueryRow(ctx, getRequestByID, id)
var i Request
err := row.Scan(
&i.ID,
&i.UserID,
&i.Status,
&i.Kind,
&i.ArtistMbid,
&i.AlbumMbid,
&i.TrackMbid,
&i.ArtistName,
&i.AlbumTitle,
&i.TrackTitle,
&i.DecidedAt,
&i.DecidedBy,
&i.Notes,
&i.CompletedAt,
&i.MatchedTrackID,
&i.MatchedAlbumID,
&i.MatchedArtistID,
&i.RequestedAt,
&i.UpdatedAt,
)
return i, err
}
const hasNonTerminalRequestForMBID = `-- name: HasNonTerminalRequestForMBID :one
SELECT (EXISTS (
SELECT 1 FROM requests r
WHERE r.status IN ('pending', 'approved', 'completed')
AND ((r.kind = 'artist' AND r.artist_mbid = $1)
OR (r.kind = 'album' AND r.album_mbid = $1)
OR (r.kind = 'track' AND r.track_mbid = $1))
) OR EXISTS (
SELECT 1 FROM wants w WHERE w.release_group_mbid = $1 AND w.fulfilled_at IS NULL
) OR EXISTS (
SELECT 1 FROM follows f WHERE f.artist_mbid = $1
))::bool AS requested
`
// Whether something is already on its way: a pending, approved or completed
// request at the given level, an open want for the release group, or a
// follow of the artist. Sets the `requested` flag on catalogue search.
// Terminal-status (rejected, failed) requests do not count. MBIDs are unique
// per entity type, so checking one id against every column cannot
// false-match.
func (q *Queries) HasNonTerminalRequestForMBID(ctx context.Context, mbid string) (bool, error) {
row := q.db.QueryRow(ctx, hasNonTerminalRequestForMBID, mbid)
var requested bool
err := row.Scan(&requested)
return requested, err
}
const listApprovedRequestsForReconcile = `-- name: ListApprovedRequestsForReconcile :many
SELECT id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at FROM requests
WHERE status = 'approved'
ORDER BY decided_at ASC
LIMIT $1
`
func (q *Queries) ListApprovedRequestsForReconcile(ctx context.Context, limit int32) ([]Request, error) {
rows, err := q.db.Query(ctx, listApprovedRequestsForReconcile, limit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Request
for rows.Next() {
var i Request
if err := rows.Scan(
&i.ID,
&i.UserID,
&i.Status,
&i.Kind,
&i.ArtistMbid,
&i.AlbumMbid,
&i.TrackMbid,
&i.ArtistName,
&i.AlbumTitle,
&i.TrackTitle,
&i.DecidedAt,
&i.DecidedBy,
&i.Notes,
&i.CompletedAt,
&i.MatchedTrackID,
&i.MatchedAlbumID,
&i.MatchedArtistID,
&i.RequestedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listRequestsByStatus = `-- name: ListRequestsByStatus :many
SELECT id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at FROM requests
WHERE status = $1
ORDER BY requested_at DESC
LIMIT $2
`
type ListRequestsByStatusParams struct {
Status RequestStatus
Limit int32
}
func (q *Queries) ListRequestsByStatus(ctx context.Context, arg ListRequestsByStatusParams) ([]Request, error) {
rows, err := q.db.Query(ctx, listRequestsByStatus, arg.Status, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Request
for rows.Next() {
var i Request
if err := rows.Scan(
&i.ID,
&i.UserID,
&i.Status,
&i.Kind,
&i.ArtistMbid,
&i.AlbumMbid,
&i.TrackMbid,
&i.ArtistName,
&i.AlbumTitle,
&i.TrackTitle,
&i.DecidedAt,
&i.DecidedBy,
&i.Notes,
&i.CompletedAt,
&i.MatchedTrackID,
&i.MatchedAlbumID,
&i.MatchedArtistID,
&i.RequestedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listRequestsForUser = `-- name: ListRequestsForUser :many
SELECT id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at FROM requests
WHERE user_id = $1
ORDER BY requested_at DESC
LIMIT $2
`
type ListRequestsForUserParams struct {
UserID pgtype.UUID
Limit int32
}
func (q *Queries) ListRequestsForUser(ctx context.Context, arg ListRequestsForUserParams) ([]Request, error) {
rows, err := q.db.Query(ctx, listRequestsForUser, arg.UserID, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Request
for rows.Next() {
var i Request
if err := rows.Scan(
&i.ID,
&i.UserID,
&i.Status,
&i.Kind,
&i.ArtistMbid,
&i.AlbumMbid,
&i.TrackMbid,
&i.ArtistName,
&i.AlbumTitle,
&i.TrackTitle,
&i.DecidedAt,
&i.DecidedBy,
&i.Notes,
&i.CompletedAt,
&i.MatchedTrackID,
&i.MatchedAlbumID,
&i.MatchedArtistID,
&i.RequestedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const rejectRequest = `-- name: RejectRequest :one
UPDATE requests
SET status = 'rejected',
notes = $2,
decided_at = now(),
decided_by = $3,
updated_at = now()
WHERE id = $1 AND status = 'pending'
RETURNING id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at
`
type RejectRequestParams struct {
ID pgtype.UUID
Notes *string
DecidedBy pgtype.UUID
}
func (q *Queries) RejectRequest(ctx context.Context, arg RejectRequestParams) (Request, error) {
row := q.db.QueryRow(ctx, rejectRequest, arg.ID, arg.Notes, arg.DecidedBy)
var i Request
err := row.Scan(
&i.ID,
&i.UserID,
&i.Status,
&i.Kind,
&i.ArtistMbid,
&i.AlbumMbid,
&i.TrackMbid,
&i.ArtistName,
&i.AlbumTitle,
&i.TrackTitle,
&i.DecidedAt,
&i.DecidedBy,
&i.Notes,
&i.CompletedAt,
&i.MatchedTrackID,
&i.MatchedAlbumID,
&i.MatchedArtistID,
&i.RequestedAt,
&i.UpdatedAt,
)
return i, err
}
const repointRequestsAlbumMbid = `-- name: RepointRequestsAlbumMbid :exec
UPDATE requests
SET album_mbid = $1,
updated_at = now()
WHERE album_mbid = $2
`
type RepointRequestsAlbumMbidParams struct {
NewMbid *string
OldMbid *string
}
// A want moved from a release id to its group takes the requests
// that name it along, so the reconciler finds it.
func (q *Queries) RepointRequestsAlbumMbid(ctx context.Context, arg RepointRequestsAlbumMbidParams) error {
_, err := q.db.Exec(ctx, repointRequestsAlbumMbid, arg.NewMbid, arg.OldMbid)
return err
}