0d0a8f46b1
The recommendation scoring knobs move out of YAML (radio profile) and out of the systemMixWeights hard-code (daily_mix profile) into DB-backed settings with live effect (#1250) — the defaults-discovery lab per decision #1247: the operator turns knobs to find good values, which then get baked back into shipped defaults; end users and other operators should never need the card. - Migration 0040: recommendation_weight_profiles (radio / daily_mix, 8 weight columns), taste_tuning singleton (engagement half-life + completion-curve points), recommendation_tuning_audit (one row per change with a {field, old, new} diff — the trend view's markers, #1251). - internal/recsettings: boot reconcile seeds shipped defaults without clobbering tuned rows (coverart SettingsService pattern), validates patches (bounds, curve ordering), writes audit rows, and pushes daily_mix weights + taste config into package playlists. No-op patches write no audit row. - playlists gains SetSystemMixWeights / SetTasteConfig swap points under a RWMutex — no signature threading through the producers; the scheduler's taste rebuild reads the pushed config. - Radio reads its weight profile from the service per request; the 8 weight fields leave config.RecommendationConfig (YAML keeps only RecentlyPlayedHours / RadioSize / RadioSizeMax). - Admin API: GET/PATCH/reset under /api/admin/recommendation-tuning, echoing current + shipped values. - Web: new admin Tuning tab — two weight profiles side by side, taste card, per-scope save (changed fields only) + reset, deviation dots against shipped defaults. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TsF3cNoKrqCYsU78cXC8U6
625 lines
14 KiB
Go
625 lines
14 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.31.1
|
|
|
|
package dbq
|
|
|
|
import (
|
|
"database/sql/driver"
|
|
"fmt"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
type LidarrQuarantineActionKind string
|
|
|
|
const (
|
|
LidarrQuarantineActionKindResolved LidarrQuarantineActionKind = "resolved"
|
|
LidarrQuarantineActionKindDeletedFile LidarrQuarantineActionKind = "deleted_file"
|
|
LidarrQuarantineActionKindDeletedViaLidarr LidarrQuarantineActionKind = "deleted_via_lidarr"
|
|
)
|
|
|
|
func (e *LidarrQuarantineActionKind) Scan(src interface{}) error {
|
|
switch s := src.(type) {
|
|
case []byte:
|
|
*e = LidarrQuarantineActionKind(s)
|
|
case string:
|
|
*e = LidarrQuarantineActionKind(s)
|
|
default:
|
|
return fmt.Errorf("unsupported scan type for LidarrQuarantineActionKind: %T", src)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type NullLidarrQuarantineActionKind struct {
|
|
LidarrQuarantineActionKind LidarrQuarantineActionKind
|
|
Valid bool // Valid is true if LidarrQuarantineActionKind is not NULL
|
|
}
|
|
|
|
// Scan implements the Scanner interface.
|
|
func (ns *NullLidarrQuarantineActionKind) Scan(value interface{}) error {
|
|
if value == nil {
|
|
ns.LidarrQuarantineActionKind, ns.Valid = "", false
|
|
return nil
|
|
}
|
|
ns.Valid = true
|
|
return ns.LidarrQuarantineActionKind.Scan(value)
|
|
}
|
|
|
|
// Value implements the driver Valuer interface.
|
|
func (ns NullLidarrQuarantineActionKind) Value() (driver.Value, error) {
|
|
if !ns.Valid {
|
|
return nil, nil
|
|
}
|
|
return string(ns.LidarrQuarantineActionKind), nil
|
|
}
|
|
|
|
type LidarrQuarantineReason string
|
|
|
|
const (
|
|
LidarrQuarantineReasonBadRip LidarrQuarantineReason = "bad_rip"
|
|
LidarrQuarantineReasonWrongFile LidarrQuarantineReason = "wrong_file"
|
|
LidarrQuarantineReasonWrongTags LidarrQuarantineReason = "wrong_tags"
|
|
LidarrQuarantineReasonDuplicate LidarrQuarantineReason = "duplicate"
|
|
LidarrQuarantineReasonOther LidarrQuarantineReason = "other"
|
|
)
|
|
|
|
func (e *LidarrQuarantineReason) Scan(src interface{}) error {
|
|
switch s := src.(type) {
|
|
case []byte:
|
|
*e = LidarrQuarantineReason(s)
|
|
case string:
|
|
*e = LidarrQuarantineReason(s)
|
|
default:
|
|
return fmt.Errorf("unsupported scan type for LidarrQuarantineReason: %T", src)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type NullLidarrQuarantineReason struct {
|
|
LidarrQuarantineReason LidarrQuarantineReason
|
|
Valid bool // Valid is true if LidarrQuarantineReason is not NULL
|
|
}
|
|
|
|
// Scan implements the Scanner interface.
|
|
func (ns *NullLidarrQuarantineReason) Scan(value interface{}) error {
|
|
if value == nil {
|
|
ns.LidarrQuarantineReason, ns.Valid = "", false
|
|
return nil
|
|
}
|
|
ns.Valid = true
|
|
return ns.LidarrQuarantineReason.Scan(value)
|
|
}
|
|
|
|
// Value implements the driver Valuer interface.
|
|
func (ns NullLidarrQuarantineReason) Value() (driver.Value, error) {
|
|
if !ns.Valid {
|
|
return nil, nil
|
|
}
|
|
return string(ns.LidarrQuarantineReason), nil
|
|
}
|
|
|
|
type LidarrRequestKind string
|
|
|
|
const (
|
|
LidarrRequestKindArtist LidarrRequestKind = "artist"
|
|
LidarrRequestKindAlbum LidarrRequestKind = "album"
|
|
LidarrRequestKindTrack LidarrRequestKind = "track"
|
|
)
|
|
|
|
func (e *LidarrRequestKind) Scan(src interface{}) error {
|
|
switch s := src.(type) {
|
|
case []byte:
|
|
*e = LidarrRequestKind(s)
|
|
case string:
|
|
*e = LidarrRequestKind(s)
|
|
default:
|
|
return fmt.Errorf("unsupported scan type for LidarrRequestKind: %T", src)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type NullLidarrRequestKind struct {
|
|
LidarrRequestKind LidarrRequestKind
|
|
Valid bool // Valid is true if LidarrRequestKind is not NULL
|
|
}
|
|
|
|
// Scan implements the Scanner interface.
|
|
func (ns *NullLidarrRequestKind) Scan(value interface{}) error {
|
|
if value == nil {
|
|
ns.LidarrRequestKind, ns.Valid = "", false
|
|
return nil
|
|
}
|
|
ns.Valid = true
|
|
return ns.LidarrRequestKind.Scan(value)
|
|
}
|
|
|
|
// Value implements the driver Valuer interface.
|
|
func (ns NullLidarrRequestKind) Value() (driver.Value, error) {
|
|
if !ns.Valid {
|
|
return nil, nil
|
|
}
|
|
return string(ns.LidarrRequestKind), nil
|
|
}
|
|
|
|
type LidarrRequestStatus string
|
|
|
|
const (
|
|
LidarrRequestStatusPending LidarrRequestStatus = "pending"
|
|
LidarrRequestStatusApproved LidarrRequestStatus = "approved"
|
|
LidarrRequestStatusRejected LidarrRequestStatus = "rejected"
|
|
LidarrRequestStatusCompleted LidarrRequestStatus = "completed"
|
|
LidarrRequestStatusFailed LidarrRequestStatus = "failed"
|
|
)
|
|
|
|
func (e *LidarrRequestStatus) Scan(src interface{}) error {
|
|
switch s := src.(type) {
|
|
case []byte:
|
|
*e = LidarrRequestStatus(s)
|
|
case string:
|
|
*e = LidarrRequestStatus(s)
|
|
default:
|
|
return fmt.Errorf("unsupported scan type for LidarrRequestStatus: %T", src)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type NullLidarrRequestStatus struct {
|
|
LidarrRequestStatus LidarrRequestStatus
|
|
Valid bool // Valid is true if LidarrRequestStatus is not NULL
|
|
}
|
|
|
|
// Scan implements the Scanner interface.
|
|
func (ns *NullLidarrRequestStatus) Scan(value interface{}) error {
|
|
if value == nil {
|
|
ns.LidarrRequestStatus, ns.Valid = "", false
|
|
return nil
|
|
}
|
|
ns.Valid = true
|
|
return ns.LidarrRequestStatus.Scan(value)
|
|
}
|
|
|
|
// Value implements the driver Valuer interface.
|
|
func (ns NullLidarrRequestStatus) Value() (driver.Value, error) {
|
|
if !ns.Valid {
|
|
return nil, nil
|
|
}
|
|
return string(ns.LidarrRequestStatus), nil
|
|
}
|
|
|
|
type Album struct {
|
|
ID pgtype.UUID
|
|
Title string
|
|
SortTitle string
|
|
ArtistID pgtype.UUID
|
|
ReleaseDate pgtype.Date
|
|
Mbid *string
|
|
CoverArtPath *string
|
|
CreatedAt pgtype.Timestamptz
|
|
UpdatedAt pgtype.Timestamptz
|
|
CoverArtSource *string
|
|
CoverArtSourcesVersion int32
|
|
}
|
|
|
|
type Artist struct {
|
|
ID pgtype.UUID
|
|
Name string
|
|
SortName string
|
|
Mbid *string
|
|
CreatedAt pgtype.Timestamptz
|
|
UpdatedAt pgtype.Timestamptz
|
|
ArtistThumbPath *string
|
|
ArtistFanartPath *string
|
|
ArtistArtSource *string
|
|
ArtistArtSourcesVersion int32
|
|
}
|
|
|
|
type ArtistSimilarity struct {
|
|
ArtistAID pgtype.UUID
|
|
ArtistBID pgtype.UUID
|
|
Score float64
|
|
Source string
|
|
FetchedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type ArtistSimilarityUnmatched struct {
|
|
SeedArtistID pgtype.UUID
|
|
CandidateMbid string
|
|
CandidateName string
|
|
Score float64
|
|
Source string
|
|
FetchedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type AuditLog struct {
|
|
ID pgtype.UUID
|
|
ActorID pgtype.UUID
|
|
TargetID pgtype.UUID
|
|
Action string
|
|
Metadata []byte
|
|
CreatedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type ContextualLike struct {
|
|
ID pgtype.UUID
|
|
UserID pgtype.UUID
|
|
TrackID pgtype.UUID
|
|
LikedAt pgtype.Timestamptz
|
|
DeletedAt pgtype.Timestamptz
|
|
SessionVector []byte
|
|
SessionID pgtype.UUID
|
|
}
|
|
|
|
type CoverArtProviderSetting struct {
|
|
ProviderID string
|
|
Enabled bool
|
|
ApiKey *string
|
|
DisplayOrder int32
|
|
CreatedAt pgtype.Timestamptz
|
|
UpdatedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type CoverArtSourcesMetum struct {
|
|
ID bool
|
|
CurrentVersion int32
|
|
LastRegisteredProvidersHash string
|
|
}
|
|
|
|
type DiagnosticEvent struct {
|
|
ID pgtype.UUID
|
|
UserID pgtype.UUID
|
|
ClientID string
|
|
AppVersion *string
|
|
OsVersion *string
|
|
Kind string
|
|
Payload []byte
|
|
OccurredAt pgtype.Timestamptz
|
|
ReceivedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type GeneralLike struct {
|
|
UserID pgtype.UUID
|
|
TrackID pgtype.UUID
|
|
LikedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type GeneralLikesAlbum struct {
|
|
UserID pgtype.UUID
|
|
AlbumID pgtype.UUID
|
|
LikedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type GeneralLikesArtist struct {
|
|
UserID pgtype.UUID
|
|
ArtistID pgtype.UUID
|
|
LikedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type LibraryChange struct {
|
|
ID int64
|
|
EntityType string
|
|
EntityID string
|
|
Op string
|
|
ChangedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type LidarrConfig struct {
|
|
ID int16
|
|
Enabled bool
|
|
BaseUrl *string
|
|
ApiKey *string
|
|
DefaultQualityProfileID *int32
|
|
DefaultRootFolderPath *string
|
|
CreatedAt pgtype.Timestamptz
|
|
UpdatedAt pgtype.Timestamptz
|
|
DefaultMetadataProfileID *int32
|
|
}
|
|
|
|
type LidarrQuarantine struct {
|
|
UserID pgtype.UUID
|
|
TrackID pgtype.UUID
|
|
Reason LidarrQuarantineReason
|
|
Notes *string
|
|
CreatedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type LidarrQuarantineAction struct {
|
|
ID pgtype.UUID
|
|
TrackID pgtype.UUID
|
|
TrackTitle string
|
|
ArtistName string
|
|
AlbumTitle *string
|
|
Action LidarrQuarantineActionKind
|
|
AdminID pgtype.UUID
|
|
LidarrAlbumMbid *string
|
|
AffectedUsers int32
|
|
CreatedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type LidarrRequest struct {
|
|
ID pgtype.UUID
|
|
UserID pgtype.UUID
|
|
Status LidarrRequestStatus
|
|
Kind LidarrRequestKind
|
|
LidarrArtistMbid string
|
|
LidarrAlbumMbid *string
|
|
LidarrTrackMbid *string
|
|
ArtistName string
|
|
AlbumTitle *string
|
|
TrackTitle *string
|
|
QualityProfileID *int32
|
|
RootFolderPath *string
|
|
DecidedAt pgtype.Timestamptz
|
|
DecidedBy pgtype.UUID
|
|
Notes *string
|
|
CompletedAt pgtype.Timestamptz
|
|
MatchedTrackID pgtype.UUID
|
|
MatchedAlbumID pgtype.UUID
|
|
MatchedArtistID pgtype.UUID
|
|
RequestedAt pgtype.Timestamptz
|
|
UpdatedAt pgtype.Timestamptz
|
|
LidarrAddConfirmedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type PasswordReset struct {
|
|
Token string
|
|
UserID pgtype.UUID
|
|
CreatedAt pgtype.Timestamptz
|
|
ExpiresAt pgtype.Timestamptz
|
|
UsedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type PlayEvent struct {
|
|
ID pgtype.UUID
|
|
UserID pgtype.UUID
|
|
TrackID pgtype.UUID
|
|
SessionID pgtype.UUID
|
|
StartedAt pgtype.Timestamptz
|
|
EndedAt pgtype.Timestamptz
|
|
DurationPlayedMs *int32
|
|
CompletionRatio *float64
|
|
WasSkipped bool
|
|
ClientID *string
|
|
SessionVectorAtPlay []byte
|
|
ScrobbledAt pgtype.Timestamptz
|
|
Source *string
|
|
PickKind *string
|
|
}
|
|
|
|
type PlaySession struct {
|
|
ID pgtype.UUID
|
|
UserID pgtype.UUID
|
|
StartedAt pgtype.Timestamptz
|
|
EndedAt pgtype.Timestamptz
|
|
LastEventAt pgtype.Timestamptz
|
|
TrackCount int32
|
|
ClientID *string
|
|
}
|
|
|
|
type PlaybackError struct {
|
|
ID pgtype.UUID
|
|
TrackID pgtype.UUID
|
|
UserID pgtype.UUID
|
|
ClientID string
|
|
Kind string
|
|
Detail *string
|
|
OccurredAt pgtype.Timestamptz
|
|
ResolvedAt pgtype.Timestamptz
|
|
ResolvedBy pgtype.UUID
|
|
Resolution *string
|
|
}
|
|
|
|
type Playlist struct {
|
|
ID pgtype.UUID
|
|
UserID pgtype.UUID
|
|
Name string
|
|
Description string
|
|
IsPublic bool
|
|
CoverPath *string
|
|
TrackCount int32
|
|
DurationSec int32
|
|
CreatedAt pgtype.Timestamptz
|
|
UpdatedAt pgtype.Timestamptz
|
|
Kind string
|
|
SystemVariant *string
|
|
SeedArtistID pgtype.UUID
|
|
}
|
|
|
|
type PlaylistTrack struct {
|
|
PlaylistID pgtype.UUID
|
|
Position int32
|
|
TrackID pgtype.UUID
|
|
Title string
|
|
ArtistName string
|
|
AlbumTitle string
|
|
DurationSec int32
|
|
AddedAt pgtype.Timestamptz
|
|
PickKind *string
|
|
}
|
|
|
|
type RecommendationTuningAudit struct {
|
|
ID int64
|
|
ChangedAt pgtype.Timestamptz
|
|
Scope string
|
|
Action string
|
|
Changes []byte
|
|
}
|
|
|
|
type RecommendationWeightProfile struct {
|
|
Profile string
|
|
BaseWeight float64
|
|
LikeBoost float64
|
|
RecencyWeight float64
|
|
SkipPenalty float64
|
|
JitterMagnitude float64
|
|
ContextWeight float64
|
|
SimilarityWeight float64
|
|
TasteWeight float64
|
|
UpdatedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type RegistrationSetting struct {
|
|
ID bool
|
|
Mode string
|
|
}
|
|
|
|
type ScanRun struct {
|
|
ID pgtype.UUID
|
|
StartedAt pgtype.Timestamptz
|
|
FinishedAt pgtype.Timestamptz
|
|
Library []byte
|
|
MbidBackfill []byte
|
|
CoverEnrich []byte
|
|
ErrorMessage *string
|
|
ArtistArtEnrich []byte
|
|
}
|
|
|
|
type ScrobbleQueue struct {
|
|
ID pgtype.UUID
|
|
UserID pgtype.UUID
|
|
PlayEventID pgtype.UUID
|
|
Status string
|
|
Attempts int32
|
|
NextAttemptAt pgtype.Timestamptz
|
|
LastError *string
|
|
EnqueuedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type Session struct {
|
|
ID pgtype.UUID
|
|
UserID pgtype.UUID
|
|
TokenHash []byte
|
|
UserAgent string
|
|
CreatedAt pgtype.Timestamptz
|
|
LastSeenAt pgtype.Timestamptz
|
|
}
|
|
|
|
type SkipEvent struct {
|
|
ID pgtype.UUID
|
|
UserID pgtype.UUID
|
|
TrackID pgtype.UUID
|
|
SessionID pgtype.UUID
|
|
SkippedAt pgtype.Timestamptz
|
|
PositionMs int32
|
|
}
|
|
|
|
type SmtpConfig struct {
|
|
ID bool
|
|
Enabled bool
|
|
Host string
|
|
Port int32
|
|
Username string
|
|
Password string
|
|
FromAddress string
|
|
FromName string
|
|
UseTls bool
|
|
UpdatedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type SystemPlaylistRotationState struct {
|
|
UserID pgtype.UUID
|
|
PlaylistKind string
|
|
PlayedTrackIds []pgtype.UUID
|
|
RotationStartedAt pgtype.Timestamptz
|
|
UpdatedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type SystemPlaylistRun struct {
|
|
UserID pgtype.UUID
|
|
LastRunAt pgtype.Timestamptz
|
|
LastRunDate pgtype.Date
|
|
InFlight bool
|
|
LastError *string
|
|
}
|
|
|
|
type TasteProfileArtist struct {
|
|
UserID pgtype.UUID
|
|
ArtistID pgtype.UUID
|
|
Weight float64
|
|
UpdatedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type TasteProfileTag struct {
|
|
UserID pgtype.UUID
|
|
Tag string
|
|
Weight float64
|
|
UpdatedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type TasteTuning struct {
|
|
Singleton bool
|
|
HalfLifeDays float64
|
|
EngagementHardSkip float64
|
|
EngagementNeutral float64
|
|
EngagementFull float64
|
|
UpdatedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type Track struct {
|
|
ID pgtype.UUID
|
|
Title string
|
|
AlbumID pgtype.UUID
|
|
ArtistID pgtype.UUID
|
|
TrackNumber *int32
|
|
DiscNumber *int32
|
|
DurationMs int32
|
|
FilePath string
|
|
FileSize int64
|
|
FileFormat string
|
|
Bitrate *int32
|
|
Mbid *string
|
|
Genre *string
|
|
AddedAt pgtype.Timestamptz
|
|
UpdatedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type TrackSimilarity struct {
|
|
TrackAID pgtype.UUID
|
|
TrackBID pgtype.UUID
|
|
Score float64
|
|
Source string
|
|
FetchedAt pgtype.Timestamptz
|
|
}
|
|
|
|
type User struct {
|
|
ID pgtype.UUID
|
|
Username string
|
|
PasswordHash string
|
|
ApiToken string
|
|
IsAdmin bool
|
|
CreatedAt pgtype.Timestamptz
|
|
SubsonicPassword *string
|
|
ListenbrainzToken *string
|
|
ListenbrainzEnabled bool
|
|
DisplayName *string
|
|
AutoApproveRequests bool
|
|
Email *string
|
|
Timezone string
|
|
TimezoneUpdatedAt pgtype.Timestamptz
|
|
DebugModeEnabled bool
|
|
}
|
|
|
|
type UserInvite struct {
|
|
Token string
|
|
InvitedBy pgtype.UUID
|
|
Note *string
|
|
CreatedAt pgtype.Timestamptz
|
|
ExpiresAt pgtype.Timestamptz
|
|
RedeemedAt pgtype.Timestamptz
|
|
RedeemedBy pgtype.UUID
|
|
}
|
|
|
|
type YouMightLikeAlbum struct {
|
|
UserID pgtype.UUID
|
|
AlbumID pgtype.UUID
|
|
Rank int32
|
|
BuiltAt pgtype.Timestamptz
|
|
}
|
|
|
|
type YouMightLikeArtist struct {
|
|
UserID pgtype.UUID
|
|
ArtistID pgtype.UUID
|
|
Rank int32
|
|
BuiltAt pgtype.Timestamptz
|
|
}
|