feat: add ai_user_daily_spend table and queries (#26562)

## Description

Adds the spend tracking table and queries needed by [AIGOV-427](https://linear.app/codercom/issue/AIGOV-427/add-post-response-spend-accumulation) (post-response accumulation) and [AIGOV-428](https://linear.app/codercom/issue/AIGOV-428/add-pre-request-budget-enforcement) (pre-request enforcement).

## Changes

- Add `ai_user_daily_spend` table to aggregate per-user, per-effective-group AI spend by UTC day.
- Add `UpsertUserAIDailySpend` and `GetUserAISpendSince` queries.

Closes https://linear.app/codercom/issue/AIGOV-426/add-daily-spend-table-and-queries

> [!NOTE]
> Initially generated by Claude Opus 4.7, modified and reviewed by @ssncferreira
This commit is contained in:
Susana Ferreira
2026-07-02 16:29:25 +01:00
committed by GitHub
parent dee41c34e6
commit fcdd029d74
15 changed files with 613 additions and 0 deletions
+6
View File
@@ -813,6 +813,9 @@ type sqlcQuerier interface {
// Filters to active, non-deleted, non-system users to match the canonical
// seat count query (GetActiveAISeatCount).
GetUserAISeatStates(ctx context.Context, userIds []uuid.UUID) ([]uuid.UUID, error)
// Total spend for (user_id, effective_group_id) on or after period_start until NOW.
// The period_start parameter is normalized to its UTC calendar day.
GetUserAISpendSince(ctx context.Context, arg GetUserAISpendSinceParams) (GetUserAISpendSinceRow, error)
// GetUserActivityInsights returns the ranking with top active users.
// The result can be filtered on template_ids, meaning only user data
// from workspaces based on those templates will be included.
@@ -995,6 +998,9 @@ type sqlcQuerier interface {
HydrateAgentChatsContext(ctx context.Context, arg HydrateAgentChatsContextParams) error
// Increments generation_attempt and returns the resulting value.
IncrementChatGenerationAttempt(ctx context.Context, id uuid.UUID) (int64, error)
// Adds cost_micros to the spend for (user_id, effective_group_id, day).
// The day parameter is normalized to its UTC calendar day before storage.
IncrementUserAIDailySpend(ctx context.Context, arg IncrementUserAIDailySpendParams) (AIUserDailySpend, error)
InsertAIBridgeInterception(ctx context.Context, arg InsertAIBridgeInterceptionParams) (AIBridgeInterception, error)
InsertAIBridgeModelThought(ctx context.Context, arg InsertAIBridgeModelThoughtParams) (AIBridgeModelThought, error)
InsertAIBridgeTokenUsage(ctx context.Context, arg InsertAIBridgeTokenUsageParams) (AIBridgeTokenUsage, error)