package cache import ( "fmt" "time" ) // Key prefixes for different data types const ( PrefixSession = "session" PrefixUser = "user" PrefixCatalog = "catalog" PrefixDownload = "download" PrefixRateLimit = "ratelimit" PrefixLock = "lock" PrefixSearch = "search" PrefixRecommendation = "recommendation" ) // TTL constants const ( TTLSession = 24 * time.Hour TTLUser = 15 * time.Minute TTLCatalog = 5 * time.Minute TTLDownload = 30 * time.Second TTLRateLimit = 1 * time.Minute TTLLock = 30 * time.Second TTLSearch = 10 * time.Minute TTLRecommendation = 1 * time.Hour ) // KeyBuilder provides methods to build cache keys type KeyBuilder struct { namespace string } // NewKeyBuilder creates a new key builder with a namespace func NewKeyBuilder(namespace string) *KeyBuilder { return &KeyBuilder{namespace: namespace} } // Build creates a cache key from parts func (kb *KeyBuilder) Build(parts ...string) string { if kb.namespace == "" { return join(parts...) } return join(append([]string{kb.namespace}, parts...)...) } // SessionKey builds a key for session data func (kb *KeyBuilder) SessionKey(sessionID string) string { return kb.Build(PrefixSession, sessionID) } // UserKey builds a key for user data func (kb *KeyBuilder) UserKey(userID string) string { return kb.Build(PrefixUser, userID) } // UserProfileKey builds a key for user profile data func (kb *KeyBuilder) UserProfileKey(userID string) string { return kb.Build(PrefixUser, userID, "profile") } // CatalogDashboardKey builds a key for dashboard data func (kb *KeyBuilder) CatalogDashboardKey(userID string) string { return kb.Build(PrefixCatalog, "dashboard", userID) } // CatalogDiscoverKey builds a key for discover sections func (kb *KeyBuilder) CatalogDiscoverKey(genre, mediaType string, page int) string { return kb.Build(PrefixCatalog, "discover", genre, mediaType, fmt.Sprintf("page:%d", page)) } // CatalogSearchKey builds a key for search results func (kb *KeyBuilder) CatalogSearchKey(query, genre, mediaType string) string { return kb.Build(PrefixSearch, query, genre, mediaType) } // DownloadJobKey builds a key for download job data func (kb *KeyBuilder) DownloadJobKey(jobID string) string { return kb.Build(PrefixDownload, "job", jobID) } // DownloadListKey builds a key for user's download list func (kb *KeyBuilder) DownloadListKey(userID string, status string) string { return kb.Build(PrefixDownload, "list", userID, status) } // RateLimitKey builds a key for rate limiting func (kb *KeyBuilder) RateLimitKey(identifier, action string) string { return kb.Build(PrefixRateLimit, identifier, action) } // LockKey builds a key for distributed locks func (kb *KeyBuilder) LockKey(resource string) string { return kb.Build(PrefixLock, resource) } // RecommendationKey builds a key for user recommendations func (kb *KeyBuilder) RecommendationKey(userID string) string { return kb.Build(PrefixRecommendation, userID) } // WatchLaterKey builds a key for watch later list func (kb *KeyBuilder) WatchLaterKey(userID string) string { return kb.Build(PrefixCatalog, "watchlater", userID) } // ContinueWatchingKey builds a key for continue watching list func (kb *KeyBuilder) ContinueWatchingKey(userID string) string { return kb.Build(PrefixCatalog, "continue", userID) } // join concatenates strings with a colon separator func join(parts ...string) string { if len(parts) == 0 { return "" } result := parts[0] for i := 1; i < len(parts); i++ { if parts[i] != "" { result += ":" + parts[i] } } return result }