refactor: rename Ai* database identifiers to AI* (AIGOV-369) (#26327)

Adds `ai` to sqlc's `gen.go.initialisms` in `coderd/database/sqlc.yaml`
so the generated DB code follows Go's initialism convention. Adds the
matching `ai` -> `AI` case to the dbgen PascalCase helper
(`scripts/dbgen/main.go`) so the corresponding `dbmem` / mock
identifiers stay in sync. `make gen` regenerates the rest; hand-written
call sites that consume DB-generated identifiers
(`enterprise/audit/table.go`, `coderd/database/modelmethods.go`,
`enterprise/coderd/aigatewaykeys.go`, `coderd/database/dbauthz/*`, etc.)
are updated to match.

Scope is deliberately limited to the database layer:

- `coderd/rbac/*` (resource and scope generators) is untouched —
`ResourceAi*` / `ScopeAi*` constants stay on main's casing.
- `codersdk/*` (Go SDK) is untouched — `codersdk.ResourceAi*` /
`codersdk.APIKeyScopeAi*` constants stay on main's casing, so external
Go SDK consumers see no source-level break.
- `Aibridge*` identifiers (one SQL token `aibridge`, not `ai_bridge`)
are out of scope.

On-the-wire values are unchanged: enum strings, RBAC resource type
strings, API key scope strings, and JSON tags all stay the same. The
HTTP/JSON surface is unaffected.

Refs:
[AIGOV-369](https://linear.app/codercom/issue/AIGOV-369/change-ai-references-in-coderddatabasemodelsgo-to-ai)

🤖 Generated with [Coder Agents](https://coder.com)
This commit is contained in:
Danny Kopping
2026-06-16 09:01:43 +00:00
committed by GitHub
parent 00a08f35cc
commit a1330e3a8c
53 changed files with 612 additions and 605 deletions
+2 -2
View File
@@ -97,13 +97,13 @@ func (t *SeatTracker) RecordUsage(ctx context.Context, userID uuid.UUID, reason
if auditor == nil || *auditor == nil {
return
}
audit.BackgroundAudit[database.AiSeatState](ctx, &audit.BackgroundAuditParams[database.AiSeatState]{
audit.BackgroundAudit[database.AISeatState](ctx, &audit.BackgroundAuditParams[database.AISeatState]{
Audit: *auditor,
Log: t.logger,
UserID: userID,
Time: now,
Action: database.AuditActionCreate,
New: database.AiSeatState{
New: database.AISeatState{
UserID: userID,
FirstUsedAt: now,
LastUsedAt: now,
+1 -1
View File
@@ -146,7 +146,7 @@ func TestSeatTrackerDB(t *testing.T) {
require.EqualValues(t, 1, count)
require.Len(t, a.AuditLogs(), 1)
require.Equal(t, database.ResourceTypeAiSeat, a.AuditLogs()[0].ResourceType)
require.Equal(t, database.ResourceTypeAISeat, a.AuditLogs()[0].ResourceType)
})
// Provisionerd also calls RecordUsage via SeatTracker for
+2 -2
View File
@@ -463,7 +463,7 @@ func Test_diff(t *testing.T) {
name: "PropertyChange",
left: database.AIProvider{
ID: uuid.UUID{1},
Type: database.AiProviderTypeOpenai,
Type: database.AIProviderTypeOpenai,
Name: "primary-openai",
DisplayName: sql.NullString{String: "Primary", Valid: true},
Enabled: true,
@@ -471,7 +471,7 @@ func Test_diff(t *testing.T) {
},
right: database.AIProvider{
ID: uuid.UUID{1},
Type: database.AiProviderTypeOpenai,
Type: database.AIProviderTypeOpenai,
Name: "primary-openai",
DisplayName: sql.NullString{String: "Renamed", Valid: true},
Enabled: false,
+6 -6
View File
@@ -28,12 +28,12 @@ var AuditActionMap = map[string][]codersdk.AuditAction{
"APIKey": {codersdk.AuditActionLogin, codersdk.AuditActionLogout, codersdk.AuditActionRegister, codersdk.AuditActionCreate, codersdk.AuditActionWrite, codersdk.AuditActionDelete},
"License": {codersdk.AuditActionCreate, codersdk.AuditActionDelete},
"Task": {codersdk.AuditActionCreate, codersdk.AuditActionWrite, codersdk.AuditActionDelete},
"AiSeatState": {codersdk.AuditActionCreate},
"AISeatState": {codersdk.AuditActionCreate},
"AIProvider": {codersdk.AuditActionCreate, codersdk.AuditActionWrite, codersdk.AuditActionDelete},
"AIProviderKey": {codersdk.AuditActionCreate, codersdk.AuditActionDelete},
"AIGatewayKey": {codersdk.AuditActionCreate, codersdk.AuditActionDelete},
"AuditableGroupAiBudget": {codersdk.AuditActionWrite, codersdk.AuditActionDelete},
"AuditableUserAiBudgetOverride": {codersdk.AuditActionWrite, codersdk.AuditActionDelete},
"AuditableGroupAIBudget": {codersdk.AuditActionWrite, codersdk.AuditActionDelete},
"AuditableUserAIBudgetOverride": {codersdk.AuditActionWrite, codersdk.AuditActionDelete},
"Chat": {codersdk.AuditActionCreate, codersdk.AuditActionWrite}, // chats get 'archived' by users, not deleted.
"UserSecret": {codersdk.AuditActionCreate, codersdk.AuditActionWrite, codersdk.AuditActionDelete},
"UserSkill": {codersdk.AuditActionCreate, codersdk.AuditActionWrite, codersdk.AuditActionDelete},
@@ -225,7 +225,7 @@ var auditableResourcesTypes = map[any]map[string]Action{
"source": ActionIgnore,
"chat_spend_limit_micros": ActionTrack,
},
&database.AuditableGroupAiBudget{}: {
&database.AuditableGroupAIBudget{}: {
"group_id": ActionIgnore, // Group name is already included in the title.
"spend_limit_micros": ActionIgnore,
"spend_limit": ActionTrack, // Track spend_limit, which is the human-readable version.
@@ -233,7 +233,7 @@ var auditableResourcesTypes = map[any]map[string]Action{
"created_at": ActionIgnore, // Redundant with the audit log's own timestamp.
"updated_at": ActionIgnore, // Redundant with the audit log's own timestamp.
},
&database.AuditableUserAiBudgetOverride{}: {
&database.AuditableUserAIBudgetOverride{}: {
"user_id": ActionIgnore, // Username is already included in the title.
"username": ActionIgnore, // Username is already included in the title.
"group_id": ActionTrack,
@@ -382,7 +382,7 @@ var auditableResourcesTypes = map[any]map[string]Action{
"field": ActionTrack,
"mapping": ActionTrack,
},
&database.AiSeatState{}: {
&database.AISeatState{}: {
"user_id": ActionTrack,
"first_used_at": ActionTrack,
"last_event_type": ActionTrack,
@@ -21,7 +21,7 @@ func TestClassifyProviderRow(t *testing.T) {
enabledRow := func(name, baseURL string) database.AIProvider {
return database.AIProvider{
Name: name,
Type: database.AiProviderTypeOpenai,
Type: database.AIProviderTypeOpenai,
Enabled: true,
BaseUrl: baseURL,
}
@@ -33,7 +33,7 @@ func TestClassifyProviderRow(t *testing.T) {
seen := map[string]string{}
got := classifyProviderRow(enabledRow("openai", "https://api.openai.com/v1"), seen)
assert.Equal(t, "openai", got.Name)
assert.Equal(t, string(database.AiProviderTypeOpenai), got.Type)
assert.Equal(t, string(database.AIProviderTypeOpenai), got.Type)
assert.Equal(t, aibridged.ProviderStatusEnabled, got.Status)
assert.Equal(t, "api.openai.com", got.Host)
assert.NoError(t, got.Err)
@@ -37,7 +37,7 @@ func TestBackfillBedrockProviderTypeEncryptedSettings(t *testing.T) {
})
require.NoError(t, err)
provider := dbgen.AIProvider(t, cryptDB, database.AIProvider{
Type: database.AiProviderTypeAnthropic,
Type: database.AIProviderTypeAnthropic,
Settings: sql.NullString{String: string(rawSettings), Valid: true},
})
@@ -46,6 +46,6 @@ func TestBackfillBedrockProviderTypeEncryptedSettings(t *testing.T) {
// Verify via raw DB: type is not encrypted so it is directly readable.
row, err := rawDB.GetAIProviderByName(ctx, provider.Name)
require.NoError(t, err)
require.Equal(t, database.AiProviderTypeBedrock, row.Type, "encrypted legacy row must be promoted")
require.Equal(t, database.AIProviderTypeBedrock, row.Type, "encrypted legacy row must be promoted")
require.True(t, row.SettingsKeyID.Valid, "settings must remain encrypted after backfill")
}
+4 -4
View File
@@ -575,7 +575,7 @@ func (api *API) upsertGroupAIBudget(rw http.ResponseWriter, r *http.Request) {
ctx = r.Context()
group = httpmw.GroupParam(r)
auditor = api.AGPL.Auditor.Load()
aReq, commitAudit = audit.InitRequest[database.AuditableGroupAiBudget](rw, &audit.RequestParams{
aReq, commitAudit = audit.InitRequest[database.AuditableGroupAIBudget](rw, &audit.RequestParams{
Audit: *auditor,
Log: api.Logger,
Request: r,
@@ -630,7 +630,7 @@ func (api *API) deleteGroupAIBudget(rw http.ResponseWriter, r *http.Request) {
ctx = r.Context()
group = httpmw.GroupParam(r)
auditor = api.AGPL.Auditor.Load()
aReq, commitAudit = audit.InitRequest[database.AuditableGroupAiBudget](rw, &audit.RequestParams{
aReq, commitAudit = audit.InitRequest[database.AuditableGroupAIBudget](rw, &audit.RequestParams{
Audit: *auditor,
Log: api.Logger,
Request: r,
@@ -714,7 +714,7 @@ func (api *API) upsertUserAIBudgetOverride(rw http.ResponseWriter, r *http.Reque
}
auditor := api.AGPL.Auditor.Load()
aReq, commitAudit := audit.InitRequest[database.AuditableUserAiBudgetOverride](rw, &audit.RequestParams{
aReq, commitAudit := audit.InitRequest[database.AuditableUserAIBudgetOverride](rw, &audit.RequestParams{
Audit: *auditor,
Log: api.Logger,
Request: r,
@@ -809,7 +809,7 @@ func (api *API) deleteUserAIBudgetOverride(rw http.ResponseWriter, r *http.Reque
}
auditor := api.AGPL.Auditor.Load()
aReq, commitAudit := audit.InitRequest[database.AuditableUserAiBudgetOverride](rw, &audit.RequestParams{
aReq, commitAudit := audit.InitRequest[database.AuditableUserAIBudgetOverride](rw, &audit.RequestParams{
Audit: *auditor,
Log: api.Logger,
Request: r,
+9 -9
View File
@@ -2208,7 +2208,7 @@ func TestGroupAIBudget(t *testing.T) {
rows, err := db.GetAuditLogsOffset(
ctx,
database.GetAuditLogsOffsetParams{
ResourceType: string(database.ResourceTypeGroupAiBudget),
ResourceType: string(database.ResourceTypeGroupAIBudget),
LimitOpt: 10,
},
)
@@ -2220,7 +2220,7 @@ func TestGroupAIBudget(t *testing.T) {
require.Equal(t, database.AuditActionWrite, upsertLog.Action)
require.Equal(t, group.ID, upsertLog.ResourceID)
require.Equal(t, database.ResourceTypeGroupAiBudget, upsertLog.ResourceType)
require.Equal(t, database.ResourceTypeGroupAIBudget, upsertLog.ResourceType)
require.Equal(t, group.Name, upsertLog.ResourceTarget)
require.Equal(t, owner.OrganizationID, upsertLog.OrganizationID)
@@ -2238,7 +2238,7 @@ func TestGroupAIBudget(t *testing.T) {
require.Equal(t, database.AuditActionDelete, deleteLog.Action)
require.Equal(t, group.ID, deleteLog.ResourceID)
require.Equal(t, database.ResourceTypeGroupAiBudget, deleteLog.ResourceType)
require.Equal(t, database.ResourceTypeGroupAIBudget, deleteLog.ResourceType)
require.Equal(t, group.Name, deleteLog.ResourceTarget)
require.Equal(t, owner.OrganizationID, deleteLog.OrganizationID)
@@ -2495,7 +2495,7 @@ func TestUserAIBudgetOverride(t *testing.T) {
rows, err := db.GetAuditLogsOffset(
ctx,
database.GetAuditLogsOffsetParams{
ResourceType: string(database.ResourceTypeUserAiBudgetOverride),
ResourceType: string(database.ResourceTypeUserAIBudgetOverride),
LimitOpt: 10,
},
)
@@ -2507,7 +2507,7 @@ func TestUserAIBudgetOverride(t *testing.T) {
require.Equal(t, database.AuditActionWrite, upsertLog.Action)
require.Equal(t, targetUser.ID, upsertLog.ResourceID)
require.Equal(t, database.ResourceTypeUserAiBudgetOverride, upsertLog.ResourceType)
require.Equal(t, database.ResourceTypeUserAIBudgetOverride, upsertLog.ResourceType)
require.Equal(t, targetUser.Username, upsertLog.ResourceTarget)
require.Equal(t, owner.OrganizationID, upsertLog.OrganizationID)
@@ -2531,7 +2531,7 @@ func TestUserAIBudgetOverride(t *testing.T) {
require.Equal(t, database.AuditActionDelete, deleteLog.Action)
require.Equal(t, targetUser.ID, deleteLog.ResourceID)
require.Equal(t, database.ResourceTypeUserAiBudgetOverride, deleteLog.ResourceType)
require.Equal(t, database.ResourceTypeUserAIBudgetOverride, deleteLog.ResourceType)
require.Equal(t, targetUser.Username, deleteLog.ResourceTarget)
require.Equal(t, owner.OrganizationID, deleteLog.OrganizationID)
@@ -2564,7 +2564,7 @@ func TestUserAIBudgetOverride(t *testing.T) {
rows, err := db.GetAuditLogsOffset(
ctx,
database.GetAuditLogsOffsetParams{
ResourceType: string(database.ResourceTypeUserAiBudgetOverride),
ResourceType: string(database.ResourceTypeUserAIBudgetOverride),
LimitOpt: 10,
},
)
@@ -2616,7 +2616,7 @@ func TestUserAIBudgetOverride(t *testing.T) {
rows, err := db.GetAuditLogsOffset(
ctx,
database.GetAuditLogsOffsetParams{
ResourceType: string(database.ResourceTypeUserAiBudgetOverride),
ResourceType: string(database.ResourceTypeUserAIBudgetOverride),
LimitOpt: 10,
},
)
@@ -2673,7 +2673,7 @@ func TestUserAIBudgetOverride(t *testing.T) {
rows, err := db.GetAuditLogsOffset(
ctx,
database.GetAuditLogsOffsetParams{
ResourceType: string(database.ResourceTypeUserAiBudgetOverride),
ResourceType: string(database.ResourceTypeUserAIBudgetOverride),
LimitOpt: 10,
},
)
+2 -2
View File
@@ -87,14 +87,14 @@ func writeKeyInsertError(ctx context.Context, rw http.ResponseWriter, err error)
switch {
case httpapi.IsUnauthorizedError(err):
httpapi.Forbidden(rw)
case database.IsCheckViolation(err, database.CheckAiGatewayKeysNameCheck):
case database.IsCheckViolation(err, database.CheckAIGatewayKeysNameCheck):
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
Message: "Invalid key name.",
Validations: []codersdk.ValidationError{
{Field: "name", Detail: nameFormatDetail},
},
})
case database.IsUniqueViolation(err, database.UniqueAiGatewayKeysNameIndex):
case database.IsUniqueViolation(err, database.UniqueAIGatewayKeysNameIndex):
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
Message: "Key name must be unique.",
Validations: []codersdk.ValidationError{
+18 -18
View File
@@ -589,22 +589,22 @@ func (db *dbCrypt) UpdateEncryptedAIProviderKey(ctx context.Context, params data
return key, nil
}
func (db *dbCrypt) decryptUserAIProviderKey(key *database.UserAiProviderKey) error {
func (db *dbCrypt) decryptUserAIProviderKey(key *database.UserAIProviderKey) error {
return db.decryptField(&key.APIKey, key.ApiKeyKeyID)
}
func (db *dbCrypt) GetUserAIProviderKeyByProviderID(ctx context.Context, params database.GetUserAIProviderKeyByProviderIDParams) (database.UserAiProviderKey, error) {
func (db *dbCrypt) GetUserAIProviderKeyByProviderID(ctx context.Context, params database.GetUserAIProviderKeyByProviderIDParams) (database.UserAIProviderKey, error) {
key, err := db.Store.GetUserAIProviderKeyByProviderID(ctx, params)
if err != nil {
return database.UserAiProviderKey{}, err
return database.UserAIProviderKey{}, err
}
if err := db.decryptUserAIProviderKey(&key); err != nil {
return database.UserAiProviderKey{}, err
return database.UserAIProviderKey{}, err
}
return key, nil
}
func (db *dbCrypt) GetUserAIProviderKeysByUserID(ctx context.Context, userID uuid.UUID) ([]database.UserAiProviderKey, error) {
func (db *dbCrypt) GetUserAIProviderKeysByUserID(ctx context.Context, userID uuid.UUID) ([]database.UserAIProviderKey, error) {
keys, err := db.Store.GetUserAIProviderKeysByUserID(ctx, userID)
if err != nil {
return nil, err
@@ -617,7 +617,7 @@ func (db *dbCrypt) GetUserAIProviderKeysByUserID(ctx context.Context, userID uui
return keys, nil
}
func (db *dbCrypt) GetUserAIProviderKeys(ctx context.Context) ([]database.UserAiProviderKey, error) {
func (db *dbCrypt) GetUserAIProviderKeys(ctx context.Context) ([]database.UserAIProviderKey, error) {
keys, err := db.Store.GetUserAIProviderKeys(ctx)
if err != nil {
return nil, err
@@ -630,53 +630,53 @@ func (db *dbCrypt) GetUserAIProviderKeys(ctx context.Context) ([]database.UserAi
return keys, nil
}
func (db *dbCrypt) UpsertUserAIProviderKey(ctx context.Context, params database.UpsertUserAIProviderKeyParams) (database.UserAiProviderKey, error) {
func (db *dbCrypt) UpsertUserAIProviderKey(ctx context.Context, params database.UpsertUserAIProviderKeyParams) (database.UserAIProviderKey, error) {
if strings.TrimSpace(params.APIKey) == "" {
params.ApiKeyKeyID = sql.NullString{}
} else if err := db.encryptField(&params.APIKey, &params.ApiKeyKeyID); err != nil {
return database.UserAiProviderKey{}, err
return database.UserAIProviderKey{}, err
}
key, err := db.Store.UpsertUserAIProviderKey(ctx, params)
if err != nil {
return database.UserAiProviderKey{}, err
return database.UserAIProviderKey{}, err
}
if err := db.decryptUserAIProviderKey(&key); err != nil {
return database.UserAiProviderKey{}, err
return database.UserAIProviderKey{}, err
}
return key, nil
}
func (db *dbCrypt) UpdateUserAIProviderKey(ctx context.Context, params database.UpdateUserAIProviderKeyParams) (database.UserAiProviderKey, error) {
func (db *dbCrypt) UpdateUserAIProviderKey(ctx context.Context, params database.UpdateUserAIProviderKeyParams) (database.UserAIProviderKey, error) {
if strings.TrimSpace(params.APIKey) == "" {
params.ApiKeyKeyID = sql.NullString{}
} else if err := db.encryptField(&params.APIKey, &params.ApiKeyKeyID); err != nil {
return database.UserAiProviderKey{}, err
return database.UserAIProviderKey{}, err
}
key, err := db.Store.UpdateUserAIProviderKey(ctx, params)
if err != nil {
return database.UserAiProviderKey{}, err
return database.UserAIProviderKey{}, err
}
if err := db.decryptUserAIProviderKey(&key); err != nil {
return database.UserAiProviderKey{}, err
return database.UserAIProviderKey{}, err
}
return key, nil
}
func (db *dbCrypt) UpdateEncryptedUserAIProviderKey(ctx context.Context, params database.UpdateEncryptedUserAIProviderKeyParams) (database.UserAiProviderKey, error) {
func (db *dbCrypt) UpdateEncryptedUserAIProviderKey(ctx context.Context, params database.UpdateEncryptedUserAIProviderKeyParams) (database.UserAIProviderKey, error) {
if strings.TrimSpace(params.APIKey) == "" {
params.ApiKeyKeyID = sql.NullString{}
} else if err := db.encryptField(&params.APIKey, &params.ApiKeyKeyID); err != nil {
return database.UserAiProviderKey{}, err
return database.UserAIProviderKey{}, err
}
key, err := db.Store.UpdateEncryptedUserAIProviderKey(ctx, params)
if err != nil {
return database.UserAiProviderKey{}, err
return database.UserAIProviderKey{}, err
}
if err := db.decryptUserAIProviderKey(&key); err != nil {
return database.UserAiProviderKey{}, err
return database.UserAIProviderKey{}, err
}
return key, nil
}
+4 -4
View File
@@ -1127,7 +1127,7 @@ func TestAIProviders(t *testing.T) {
t.Helper()
provider := dbgen.AIProvider(t, crypt, database.AIProvider{
Name: "anthropic-bedrock",
Type: database.AiProviderTypeAnthropic,
Type: database.AIProviderTypeAnthropic,
BaseUrl: "https://bedrock-runtime.us-west-2.amazonaws.com/",
Settings: sql.NullString{String: settings, Valid: true},
})
@@ -1237,7 +1237,7 @@ func TestAIProviderKeys(t *testing.T) {
t.Helper()
provider := dbgen.AIProvider(t, crypt, database.AIProvider{
Name: "openai-test",
Type: database.AiProviderTypeOpenai,
Type: database.AIProviderTypeOpenai,
BaseUrl: "https://api.openai.com/v1/",
})
key := dbgen.AIProviderKey(t, crypt, database.AIProviderKey{
@@ -1323,7 +1323,7 @@ func TestUserAIProviderKeys(t *testing.T) {
t *testing.T,
crypt *dbCrypt,
ciphers []Cipher,
) (database.AIProvider, database.UserAiProviderKey) {
) (database.AIProvider, database.UserAIProviderKey) {
t.Helper()
user := dbgen.User(t, crypt, database.User{})
provider := dbgen.AIProvider(t, crypt, database.AIProvider{})
@@ -1343,7 +1343,7 @@ func TestUserAIProviderKeys(t *testing.T) {
return provider, key
}
getRawUserAIProviderKey := func(t *testing.T, store database.Store, userID uuid.UUID, providerID uuid.UUID) database.UserAiProviderKey {
getRawUserAIProviderKey := func(t *testing.T, store database.Store, userID uuid.UUID, providerID uuid.UUID) database.UserAIProviderKey {
t.Helper()
key, err := store.GetUserAIProviderKeyByProviderID(ctx, database.GetUserAIProviderKeyByProviderIDParams{
UserID: userID,