Skip to content

Commit 48857e5

Browse files
committed
chore: add audit log entry when ai seat is consumed
1 parent 4f9dbb1 commit 48857e5

24 files changed

Lines changed: 147 additions & 52 deletions

File tree

coderd/apidoc/docs.go

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/audit/diff.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ type Auditable interface {
3232
idpsync.OrganizationSyncSettings |
3333
idpsync.GroupSyncSettings |
3434
idpsync.RoleSyncSettings |
35-
database.TaskTable
35+
database.TaskTable |
36+
database.AiSeatState
3637
}
3738

3839
// Map is a map of changed fields in an audited resource. It maps field names to

coderd/audit/request.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ func ResourceTarget[T Auditable](tgt T) string {
132132
return "Organization Role Sync"
133133
case database.TaskTable:
134134
return typed.Name
135+
case database.AiSeatState:
136+
return "AI Seat"
135137
default:
136138
panic(fmt.Sprintf("unknown resource %T for ResourceTarget", tgt))
137139
}
@@ -196,6 +198,8 @@ func ResourceID[T Auditable](tgt T) uuid.UUID {
196198
return noID // Org field on audit log has org id
197199
case database.TaskTable:
198200
return typed.ID
201+
case database.AiSeatState:
202+
return typed.UserID
199203
default:
200204
panic(fmt.Sprintf("unknown resource %T for ResourceID", tgt))
201205
}
@@ -251,6 +255,8 @@ func ResourceType[T Auditable](tgt T) database.ResourceType {
251255
return database.ResourceTypeIdpSyncSettingsGroup
252256
case database.TaskTable:
253257
return database.ResourceTypeTask
258+
case database.AiSeatState:
259+
return database.ResourceTypeAiSeat
254260
default:
255261
panic(fmt.Sprintf("unknown resource %T for ResourceType", typed))
256262
}
@@ -309,6 +315,8 @@ func ResourceRequiresOrgID[T Auditable]() bool {
309315
return true
310316
case database.TaskTable:
311317
return true
318+
case database.AiSeatState:
319+
return false
312320
default:
313321
panic(fmt.Sprintf("unknown resource %T for ResourceRequiresOrgID", tgt))
314322
}

coderd/database/aiseats_test.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,31 +21,33 @@ func TestUpsertAISeatState(t *testing.T) {
2121
ctx := testutil.Context(t, testutil.WaitShort)
2222

2323
t1 := dbtime.Now().Add(-time.Minute)
24-
err := db.UpsertAISeatState(ctx, database.UpsertAISeatStateParams{
24+
isNew, err := db.UpsertAISeatState(ctx, database.UpsertAISeatStateParams{
2525
UserID: user.ID,
2626
FirstUsedAt: t1,
2727
LastEventType: database.AiSeatUsageReasonAibridge,
2828
LastEventDescription: "first",
2929
})
3030
require.NoError(t, err)
31+
require.True(t, isNew)
3132

3233
t2 := t1.Add(time.Hour)
33-
err = db.UpsertAISeatState(ctx, database.UpsertAISeatStateParams{
34+
isNew, err = db.UpsertAISeatState(ctx, database.UpsertAISeatStateParams{
3435
UserID: user.ID,
3536
FirstUsedAt: t2,
3637
LastEventType: database.AiSeatUsageReasonTask,
3738
LastEventDescription: "second",
3839
})
3940
require.NoError(t, err)
41+
require.False(t, isNew)
4042

4143
rows, err := db.ListAISeatState(ctx)
4244
require.NoError(t, err)
4345
require.Len(t, rows, 1)
4446
require.Equal(t, user.ID, rows[0].UserID)
4547
require.True(t, t1.Equal(rows[0].FirstUsedAt))
46-
require.True(t, t1.Equal(rows[0].LastUsedAt))
47-
require.Equal(t, database.AiSeatUsageReasonAibridge, rows[0].LastEventType)
48-
require.Equal(t, "first", rows[0].LastEventDescription)
48+
require.True(t, t2.Equal(rows[0].LastUsedAt))
49+
require.Equal(t, database.AiSeatUsageReasonTask, rows[0].LastEventType)
50+
require.Equal(t, "second", rows[0].LastEventDescription)
4951

5052
count, err := db.GetActiveAISeatCount(ctx)
5153
require.NoError(t, err)

coderd/database/dbauthz/dbauthz.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6474,9 +6474,9 @@ func (q *querier) UpdateWorkspacesTTLByTemplateID(ctx context.Context, arg datab
64746474
return q.db.UpdateWorkspacesTTLByTemplateID(ctx, arg)
64756475
}
64766476

6477-
func (q *querier) UpsertAISeatState(ctx context.Context, arg database.UpsertAISeatStateParams) error {
6477+
func (q *querier) UpsertAISeatState(ctx context.Context, arg database.UpsertAISeatStateParams) (bool, error) {
64786478
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil {
6479-
return err
6479+
return false, err
64806480
}
64816481
return q.db.UpsertAISeatState(ctx, arg)
64826482
}

coderd/database/dbmetrics/querymetrics.go

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbmock/dbmock.go

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dump.sql

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-- resource_type enum values cannot be removed safely; no-op.

0 commit comments

Comments
 (0)