feat: add user AI spend endpoint (#26978)

## Description

Adds the `GET /api/v2/users/{user}/ai/spend` endpoint returning the
user's current AI spend, effective budget, and period bounds.

## Changes

- Add `userAISpendStatus` handler under the same feature/experiment gate
as `/api/v2/users/{user}/ai/budget`.
- Add `codersdk.UserAIBudgetSummary` (embedded into `UserAISpendStatus`)
and a `UserAISpendStatus` client method.
- Move `LimitSource` from `coderd/aibridge/budget` to `codersdk` so the
type is shared across endpoints.

Closes https://linear.app/codercom/issue/AIGOV-472

> [!NOTE]
> Initially generated by Claude Opus 4.7, modified and reviewed by
@ssncferreira
This commit is contained in:
Susana Ferreira
2026-07-08 12:46:47 +01:00
committed by GitHub
parent 60d0859bde
commit 48f07e6e13
11 changed files with 719 additions and 45 deletions
+9 -4
View File
@@ -641,7 +641,7 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
r.Get("/", api.userQuietHoursSchedule)
r.Put("/", api.putUserQuietHoursSchedule)
})
r.Route("/users/{user}/ai/budget", func(r chi.Router) {
r.Route("/users/{user}/ai", func(r chi.Router) {
// AI cost controls are a paid feature (AI Governance add-on).
r.Use(
// TODO(AIGOV-443): remove once AI Gateway cost control functionality is stable.
@@ -650,9 +650,14 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
apiKeyMiddleware,
httpmw.ExtractUserParam(options.Database),
)
r.Get("/", api.userAIBudgetOverride)
r.Put("/", api.upsertUserAIBudgetOverride)
r.Delete("/", api.deleteUserAIBudgetOverride)
r.Route("/budget", func(r chi.Router) {
r.Get("/", api.userAIBudgetOverride)
r.Put("/", api.upsertUserAIBudgetOverride)
r.Delete("/", api.deleteUserAIBudgetOverride)
})
r.Route("/spend", func(r chi.Router) {
r.Get("/", api.userAISpendStatus)
})
})
r.Route("/prebuilds", func(r chi.Router) {
r.Use(