Documentation
¶
Index ¶
- Constants
- Variables
- func NormalizeUserPath(raw string) (string, error)
- func PeriodBounds(now time.Time, seconds int64, settings Settings) (time.Time, time.Time)
- func PeriodLabel(seconds int64) string
- func PeriodSeconds(period string) (int64, bool)
- func ValidateSettings(settings Settings) error
- type Budget
- type CheckResult
- type ExceededError
- type MongoDBStore
- func (s *MongoDBStore) Close() error
- func (s *MongoDBStore) DeleteBudget(ctx context.Context, userPath string, periodSeconds int64) error
- func (s *MongoDBStore) GetSettings(ctx context.Context) (Settings, error)
- func (s *MongoDBStore) ListBudgets(ctx context.Context) ([]Budget, error)
- func (s *MongoDBStore) ReplaceConfigBudgets(ctx context.Context, budgets []Budget) error
- func (s *MongoDBStore) ResetAllBudgets(ctx context.Context, at time.Time) error
- func (s *MongoDBStore) ResetBudget(ctx context.Context, userPath string, periodSeconds int64, at time.Time) error
- func (s *MongoDBStore) SaveSettings(ctx context.Context, settings Settings) (Settings, error)
- func (s *MongoDBStore) SumUsageCost(ctx context.Context, userPath string, start, end time.Time) (float64, bool, error)
- func (s *MongoDBStore) UpsertBudgets(ctx context.Context, budgets []Budget) error
- type PostgreSQLStore
- func (s *PostgreSQLStore) Close() error
- func (s *PostgreSQLStore) DeleteBudget(ctx context.Context, userPath string, periodSeconds int64) error
- func (s *PostgreSQLStore) GetSettings(ctx context.Context) (Settings, error)
- func (s *PostgreSQLStore) ListBudgets(ctx context.Context) ([]Budget, error)
- func (s *PostgreSQLStore) ReplaceConfigBudgets(ctx context.Context, budgets []Budget) error
- func (s *PostgreSQLStore) ResetAllBudgets(ctx context.Context, at time.Time) error
- func (s *PostgreSQLStore) ResetBudget(ctx context.Context, userPath string, periodSeconds int64, at time.Time) error
- func (s *PostgreSQLStore) SaveSettings(ctx context.Context, settings Settings) (Settings, error)
- func (s *PostgreSQLStore) SumUsageCost(ctx context.Context, userPath string, start, end time.Time) (float64, bool, error)
- func (s *PostgreSQLStore) UpsertBudgets(ctx context.Context, budgets []Budget) error
- type Result
- type SQLiteStore
- func (s *SQLiteStore) Close() error
- func (s *SQLiteStore) DeleteBudget(ctx context.Context, userPath string, periodSeconds int64) error
- func (s *SQLiteStore) GetSettings(ctx context.Context) (Settings, error)
- func (s *SQLiteStore) ListBudgets(ctx context.Context) ([]Budget, error)
- func (s *SQLiteStore) ReplaceConfigBudgets(ctx context.Context, budgets []Budget) error
- func (s *SQLiteStore) ResetAllBudgets(ctx context.Context, at time.Time) error
- func (s *SQLiteStore) ResetBudget(ctx context.Context, userPath string, periodSeconds int64, at time.Time) error
- func (s *SQLiteStore) SaveSettings(ctx context.Context, settings Settings) (Settings, error)
- func (s *SQLiteStore) SumUsageCost(ctx context.Context, userPath string, start, end time.Time) (float64, bool, error)
- func (s *SQLiteStore) UpsertBudgets(ctx context.Context, budgets []Budget) error
- type Service
- func (s *Service) Budgets() []Budget
- func (s *Service) Check(ctx context.Context, userPath string, now time.Time) error
- func (s *Service) CheckWithResults(ctx context.Context, userPath string, now time.Time) ([]CheckResult, error)
- func (s *Service) DeleteBudget(ctx context.Context, userPath string, periodSeconds int64) error
- func (s *Service) Refresh(ctx context.Context) error
- func (s *Service) ReplaceConfigBudgets(ctx context.Context, budgets []Budget) error
- func (s *Service) ResetAll(ctx context.Context, at time.Time) error
- func (s *Service) ResetBudget(ctx context.Context, userPath string, periodSeconds int64, at time.Time) error
- func (s *Service) SaveSettings(ctx context.Context, settings Settings) (Settings, error)
- func (s *Service) Settings() Settings
- func (s *Service) Statuses(ctx context.Context, now time.Time) ([]CheckResult, error)
- func (s *Service) StatusesForPath(ctx context.Context, userPath string, now time.Time) ([]CheckResult, error)
- func (s *Service) UpsertBudgets(ctx context.Context, budgets []Budget) error
- type Settings
- type Store
Constants ¶
const ( PeriodHourlySeconds int64 = 3600 PeriodDailySeconds int64 = 86400 PeriodWeeklySeconds int64 = 604800 // PeriodMonthlySeconds is a sentinel key for calendar-month windows, not a literal 30-day duration. PeriodMonthlySeconds int64 = 2592000 )
const ( // SourceConfig marks budgets seeded from static configuration. SourceConfig = "config" // SourceManual marks budgets created or changed through admin APIs. SourceManual = "manual" )
Variables ¶
var ErrNotFound = errors.New("budget not found")
ErrUnavailable indicates a budget service was used without an initialized store.
Functions ¶
func NormalizeUserPath ¶
func PeriodBounds ¶
func PeriodLabel ¶
func PeriodSeconds ¶
func ValidateSettings ¶
Types ¶
type Budget ¶
type Budget struct {
UserPath string `json:"user_path" bson:"user_path"`
PeriodSeconds int64 `json:"period_seconds" bson:"period_seconds"`
Amount float64 `json:"amount" bson:"amount"`
Source string `json:"source,omitempty" bson:"source,omitempty"`
LastResetAt *time.Time `json:"last_reset_at,omitempty" bson:"last_reset_at,omitempty"`
CreatedAt time.Time `json:"created_at" bson:"created_at"`
UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`
}
Budget stores one spend limit for one user path and reset period.
func NormalizeBudget ¶
type CheckResult ¶
type CheckResult struct {
Budget Budget `json:"budget"`
PeriodStart time.Time `json:"period_start"`
PeriodEnd time.Time `json:"period_end"`
Spent float64 `json:"spent"`
HasUsage bool `json:"has_usage"`
Remaining float64 `json:"remaining"`
}
CheckResult describes one evaluated budget limit.
func (CheckResult) PeriodRatio ¶
func (r CheckResult) PeriodRatio(now time.Time) float64
PeriodRatio returns the elapsed fraction of the budget period at now, clamped to [0, 1].
func (CheckResult) UsageRatio ¶
func (r CheckResult) UsageRatio() float64
UsageRatio returns spent/amount for the period, or 0 when the budget amount is not positive. It is deliberately not clamped: values above 1 indicate an exceeded budget.
type ExceededError ¶
type ExceededError struct {
Result CheckResult
}
ExceededError indicates a budget has already been exhausted.
func (*ExceededError) Error ¶
func (e *ExceededError) Error() string
type MongoDBStore ¶
type MongoDBStore struct {
// contains filtered or unexported fields
}
func NewMongoDBStore ¶
func (*MongoDBStore) Close ¶
func (s *MongoDBStore) Close() error
func (*MongoDBStore) DeleteBudget ¶
func (*MongoDBStore) GetSettings ¶
func (s *MongoDBStore) GetSettings(ctx context.Context) (Settings, error)
func (*MongoDBStore) ListBudgets ¶
func (s *MongoDBStore) ListBudgets(ctx context.Context) ([]Budget, error)
func (*MongoDBStore) ReplaceConfigBudgets ¶
func (s *MongoDBStore) ReplaceConfigBudgets(ctx context.Context, budgets []Budget) error
func (*MongoDBStore) ResetAllBudgets ¶
func (*MongoDBStore) ResetBudget ¶
func (*MongoDBStore) SaveSettings ¶
func (*MongoDBStore) SumUsageCost ¶
func (*MongoDBStore) UpsertBudgets ¶
func (s *MongoDBStore) UpsertBudgets(ctx context.Context, budgets []Budget) error
type PostgreSQLStore ¶
type PostgreSQLStore struct {
// contains filtered or unexported fields
}
func NewPostgreSQLStore ¶
func (*PostgreSQLStore) Close ¶
func (s *PostgreSQLStore) Close() error
func (*PostgreSQLStore) DeleteBudget ¶
func (*PostgreSQLStore) GetSettings ¶
func (s *PostgreSQLStore) GetSettings(ctx context.Context) (Settings, error)
func (*PostgreSQLStore) ListBudgets ¶
func (s *PostgreSQLStore) ListBudgets(ctx context.Context) ([]Budget, error)
func (*PostgreSQLStore) ReplaceConfigBudgets ¶
func (s *PostgreSQLStore) ReplaceConfigBudgets(ctx context.Context, budgets []Budget) error
func (*PostgreSQLStore) ResetAllBudgets ¶
func (*PostgreSQLStore) ResetBudget ¶
func (*PostgreSQLStore) SaveSettings ¶
func (*PostgreSQLStore) SumUsageCost ¶
func (*PostgreSQLStore) UpsertBudgets ¶
func (s *PostgreSQLStore) UpsertBudgets(ctx context.Context, budgets []Budget) error
type Result ¶
type Result struct {
Service *Service
Store Store
Storage storage.Storage
// contains filtered or unexported fields
}
func NewWithSharedStorage ¶
type SQLiteStore ¶
type SQLiteStore struct {
// contains filtered or unexported fields
}
func NewSQLiteStore ¶
func NewSQLiteStore(db *sql.DB) (*SQLiteStore, error)
func (*SQLiteStore) Close ¶
func (s *SQLiteStore) Close() error
func (*SQLiteStore) DeleteBudget ¶
func (*SQLiteStore) GetSettings ¶
func (s *SQLiteStore) GetSettings(ctx context.Context) (Settings, error)
func (*SQLiteStore) ListBudgets ¶
func (s *SQLiteStore) ListBudgets(ctx context.Context) ([]Budget, error)
func (*SQLiteStore) ReplaceConfigBudgets ¶
func (s *SQLiteStore) ReplaceConfigBudgets(ctx context.Context, budgets []Budget) error
func (*SQLiteStore) ResetAllBudgets ¶
func (*SQLiteStore) ResetBudget ¶
func (*SQLiteStore) SaveSettings ¶
func (*SQLiteStore) SumUsageCost ¶
func (*SQLiteStore) UpsertBudgets ¶
func (s *SQLiteStore) UpsertBudgets(ctx context.Context, budgets []Budget) error
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func (*Service) CheckWithResults ¶
func (*Service) DeleteBudget ¶
func (*Service) ReplaceConfigBudgets ¶
func (*Service) ResetBudget ¶
func (*Service) SaveSettings ¶
func (*Service) StatusesForPath ¶
func (s *Service) StatusesForPath(ctx context.Context, userPath string, now time.Time) ([]CheckResult, error)
StatusesForPath evaluates every budget covering userPath without enforcing limits. Unlike CheckWithResults it never stops at an exhausted budget, so callers get the full status picture even when several budgets are exceeded.
type Settings ¶
type Settings struct {
DailyResetHour int `json:"daily_reset_hour" bson:"daily_reset_hour"`
DailyResetMinute int `json:"daily_reset_minute" bson:"daily_reset_minute"`
WeeklyResetWeekday int `json:"weekly_reset_weekday" bson:"weekly_reset_weekday"`
WeeklyResetHour int `json:"weekly_reset_hour" bson:"weekly_reset_hour"`
WeeklyResetMinute int `json:"weekly_reset_minute" bson:"weekly_reset_minute"`
MonthlyResetDay int `json:"monthly_reset_day" bson:"monthly_reset_day"`
MonthlyResetHour int `json:"monthly_reset_hour" bson:"monthly_reset_hour"`
MonthlyResetMinute int `json:"monthly_reset_minute" bson:"monthly_reset_minute"`
UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`
}
Settings controls the calendar anchors used to find the active budget period. Values are interpreted in UTC.
func DefaultSettings ¶
func DefaultSettings() Settings
DefaultSettings returns the reset anchors used when no DB setting exists.
type Store ¶
type Store interface {
ListBudgets(ctx context.Context) ([]Budget, error)
UpsertBudgets(ctx context.Context, budgets []Budget) error
DeleteBudget(ctx context.Context, userPath string, periodSeconds int64) error
ReplaceConfigBudgets(ctx context.Context, budgets []Budget) error
GetSettings(ctx context.Context) (Settings, error)
SaveSettings(ctx context.Context, settings Settings) (Settings, error)
ResetBudget(ctx context.Context, userPath string, periodSeconds int64, at time.Time) error
ResetAllBudgets(ctx context.Context, at time.Time) error
SumUsageCost(ctx context.Context, userPath string, start, end time.Time) (float64, bool, error)
Close() error
}
Store persists budget definitions, reset settings, and spend lookups.