From 722a6784a700bf6adf048605864feee293908f2a Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sat, 25 Apr 2026 20:46:23 -0400 Subject: [PATCH] feat(config): add events section (session timeout + skip rule thresholds) --- config.example.yaml | 9 +++++++++ internal/config/config.go | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/config.example.yaml b/config.example.yaml index eb3c6bee..b9a2ed80 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -36,3 +36,12 @@ subsonic: # apiKey (OpenSubsonic) and falls back to u+t+s token auth. # Env: SMARTMUSIC_SUBSONIC_ALLOW_PLAINTEXT_PASSWORD allow_plaintext_password: false + +events: + # Idle gap (minutes) between play_events that closes a play_session and + # starts a new one. Spec §6. + session_timeout_minutes: 30 + # Skip rule (spec §6): a play counts as a SKIP if completion ratio is below + # this threshold AND duration played (ms) is below the next threshold. + skip_max_completion_ratio: 0.5 + skip_max_duration_played_ms: 30000 diff --git a/internal/config/config.go b/internal/config/config.go index e20e23c9..af16e97d 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -16,6 +16,7 @@ type Config struct { Auth AuthConfig `yaml:"auth"` Library LibraryConfig `yaml:"library"` Subsonic SubsonicConfig `yaml:"subsonic"` + Events EventsConfig `yaml:"events"` } type ServerConfig struct { @@ -55,11 +56,23 @@ type SubsonicConfig struct { AllowPlaintextPassword bool `yaml:"allow_plaintext_password"` } +// EventsConfig governs play-event ingestion: session window, skip rule. +type EventsConfig struct { + SessionTimeoutMinutes int `yaml:"session_timeout_minutes"` + SkipMaxCompletionRatio float64 `yaml:"skip_max_completion_ratio"` + SkipMaxDurationPlayedMs int `yaml:"skip_max_duration_played_ms"` +} + func Default() Config { return Config{ Server: ServerConfig{Address: ":4533"}, Database: DatabaseConfig{URL: ""}, Log: LogConfig{Level: "info", Format: "text"}, + Events: EventsConfig{ + SessionTimeoutMinutes: 30, + SkipMaxCompletionRatio: 0.5, + SkipMaxDurationPlayedMs: 30000, + }, } }