Documentation
¶
Overview ¶
Package db persists parsed budgetclaw events and their per-day rollups in a local SQLite database.
Two tables:
events one row per (uuid) billable assistant message.
UUID is the primary key and dedupe guarantee: re-inserting
the same event is a no-op. Frozen historical fact.
rollups one row per (project, git_branch, day) aggregate.
Updated atomically with the event insert so the budget
evaluator can do O(1) reads for cap checks.
SQLite is opened with WAL journal mode on file-backed databases, enabling the CLI to read while the watcher writes from a separate process. The driver is modernc.org/sqlite (pure Go, no cgo) so the static-binary pledge holds.
Costs are passed in from the caller at insert time and stored as historical fact. The db package has no dependency on the pricing table. A future Anthropic rate change will not retroactively re-price old events.
Day boundaries in rollups are UTC. Budget evaluators that need local-timezone semantics should use RollupSum over a UTC time range computed from the user's tz, not the day string directly.
Index ¶
- type DB
- func (d *DB) Close() error
- func (d *DB) Insert(ctx context.Context, e *parser.Event, costUSD float64) error
- func (d *DB) RollupForDay(ctx context.Context, project, branch string, day time.Time) (*Rollup, error)
- func (d *DB) RollupSum(ctx context.Context, project, branch string, start, end time.Time) (*Rollup, error)
- func (d *DB) StatusByProject(ctx context.Context, start, end time.Time) ([]Rollup, error)
- type Rollup
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DB ¶
type DB struct {
// contains filtered or unexported fields
}
DB wraps a *sql.DB with budgetclaw-specific methods.
func Open ¶
Open opens or creates the state database.
If path is empty, Open resolves the default location via paths.StateDir() (honoring XDG_STATE_HOME) and creates any missing parent directories. If path is the literal string ":memory:", Open returns an in-memory database suitable for tests.
The schema is applied on every call. Existing tables are not recreated thanks to IF NOT EXISTS.
func OpenMemory ¶
OpenMemory returns an in-memory database for tests. Equivalent to Open(":memory:") but avoids forcing test code to know the magic string.
func (*DB) Insert ¶
Insert stores a billable event and updates its rollup row inside a single transaction. Idempotent on e.UUID: re-inserting the same event is a no-op (the rollup is not double-counted).
costUSD is passed in so the db package stays independent of the pricing table. Callers should compute it via pricing.CostForModel before calling Insert.
func (*DB) RollupForDay ¶
func (d *DB) RollupForDay(ctx context.Context, project, branch string, day time.Time) (*Rollup, error)
RollupForDay returns the rollup row for a specific (project, branch, day). Returns (nil, nil) if the row does not exist — "nothing spent today" is a valid state, not an error.
func (*DB) RollupSum ¶
func (d *DB) RollupSum(ctx context.Context, project, branch string, start, end time.Time) (*Rollup, error)
RollupSum returns the sum across a date range for a single (project, branch). Range is inclusive on both ends. Returned Rollup has empty Day and (Project, GitBranch) copied from args so callers don't need to re-thread them.
Used by the budget evaluator for weekly/monthly caps, and by the CLI for "status --period=week" output.
func (*DB) StatusByProject ¶
StatusByProject returns rollup totals grouped by (project, branch) across a date range. Ordered by project then branch for deterministic CLI output.
Empty result is not an error — a user with nothing tracked yet gets a nil slice and no rows.
type Rollup ¶
type Rollup struct {
Project string
GitBranch string
Day string
EventCount int
InputTokens int
OutputTokens int
CacheReadTokens int
CacheWrite5mTokens int
CacheWrite1hTokens int
CostUSD float64
}
Rollup is one (project, branch, day) aggregate. For range-sum queries, Day is empty because the result spans multiple days.