RecordUsage will record the AI seat usage for the user. There is a race condition between checking if the user should be recorded or throttled and actually recording. This is fine, as it just means we record the usage twice. The throttle just exists to prevent excessive database queries.
(ctx context.Context, userID uuid.UUID, reason agplaiseats.Reason)
| 73 | // it just means we record the usage twice. |
| 74 | // The throttle just exists to prevent excessive database queries. |
| 75 | func (t *SeatTracker) RecordUsage(ctx context.Context, userID uuid.UUID, reason agplaiseats.Reason) { |
| 76 | now := t.clock.Now() |
| 77 | if t.skipRecord(userID, now) { |
| 78 | return |
| 79 | } |
| 80 | |
| 81 | isNew, err := t.db.UpsertAISeatState(ctx, database.UpsertAISeatStateParams{ |
| 82 | UserID: userID, |
| 83 | FirstUsedAt: now, |
| 84 | LastEventType: reason.EventType, |
| 85 | LastEventDescription: reason.Description, |
| 86 | }) |
| 87 | if err != nil { |
| 88 | t.logger.Warn(ctx, "upsert AI seat state", slog.Error(err), slog.F("user_id", userID), slog.F("event_type", reason.EventType)) |
| 89 | t.recordThrottle(userID, now, failedThrottleInterval) |
| 90 | return |
| 91 | } |
| 92 | |
| 93 | t.recordThrottle(userID, now, throttleInterval) |
| 94 | if isNew && t.auditor != nil { |
| 95 | // Record an audit log for the first time a user uses an AI seat. |
| 96 | auditor := t.auditor.Load() |
| 97 | if auditor == nil || *auditor == nil { |
| 98 | return |
| 99 | } |
| 100 | audit.BackgroundAudit[database.AiSeatState](ctx, &audit.BackgroundAuditParams[database.AiSeatState]{ |
| 101 | Audit: *auditor, |
| 102 | Log: t.logger, |
| 103 | UserID: userID, |
| 104 | Time: now, |
| 105 | Action: database.AuditActionCreate, |
| 106 | New: database.AiSeatState{ |
| 107 | UserID: userID, |
| 108 | FirstUsedAt: now, |
| 109 | LastUsedAt: now, |
| 110 | LastEventType: reason.EventType, |
| 111 | LastEventDescription: reason.Description, |
| 112 | UpdatedAt: now, |
| 113 | }, |
| 114 | }) |
| 115 | } |
| 116 | } |
nothing calls this directly
no test coverage detected