package domain import "time" // Default rate limit values. These must match the defaults in // internal/db/migrations/005_rate_limiting.sql const ( DefaultRateLimitPerMinute = 60 DefaultRateLimitPerHour = 1000 ) // RateLimitConfig holds the rate limit configuration for an API key. type RateLimitConfig struct { // PerMinute is the maximum number of requests allowed per minute. PerMinute int // PerHour is the maximum number of requests allowed per hour. PerHour int } // DefaultRateLimitConfig returns the default rate limit configuration. func DefaultRateLimitConfig() RateLimitConfig { return RateLimitConfig{ PerMinute: DefaultRateLimitPerMinute, PerHour: DefaultRateLimitPerHour, } } // RateLimitState tracks the current usage within a time window. type RateLimitState struct { // APIKeyID is the identifier of the API key. APIKeyID string // WindowStart is the beginning of the current time window. WindowStart time.Time // WindowType indicates the type of window ("minute" or "hour"). WindowType string // RequestCount is the number of requests made in this window. RequestCount int // UpdatedAt is when this state was last updated. UpdatedAt time.Time } // WindowTypeMinute is the constant for minute-based windows. const WindowTypeMinute = "minute" // WindowTypeHour is the constant for hour-based windows. const WindowTypeHour = "hour" // RateLimitResult contains the result of a rate limit check. type RateLimitResult struct { // Allowed indicates whether the request is allowed. Allowed bool // RetryAfter is the duration to wait before retrying (when not allowed). RetryAfter time.Duration // RemainingMinute is the number of requests remaining in the current minute. RemainingMinute int // RemainingHour is the number of requests remaining in the current hour. RemainingHour int // LimitMinute is the per-minute limit for this key. LimitMinute int // LimitHour is the per-hour limit for this key. LimitHour int // ResetMinute is when the minute window resets. ResetMinute time.Time // ResetHour is when the hour window resets. ResetHour time.Time } // TruncateToMinute truncates a time to the start of the minute. func TruncateToMinute(t time.Time) time.Time { return t.Truncate(time.Minute) } // TruncateToHour truncates a time to the start of the hour. func TruncateToHour(t time.Time) time.Time { return t.Truncate(time.Hour) }