@@ -759,12 +759,13 @@ func TestDeleteOldTelemetryHeartbeats(t *testing.T) {
759759},testutil .WaitShort ,testutil .IntervalFast ,"it should delete old telemetry heartbeats" )
760760}
761761
762- //nolint:paralleltest // It uses LockIDDBPurge.
763762func TestDeleteOldAIBridgeRecords (t * testing.T ) {
763+ t .Parallel ()
764+
764765ctx := testutil .Context (t ,testutil .WaitShort )
765766
766767clk := quartz .NewMock (t )
767- now := dbtime . Now ( )
768+ now := time . Date ( 2025 , 1 , 15 , 7 , 30 , 0 , 0 , time . UTC )
768769retentionPeriod := 30 * 24 * time .Hour // 30 days
769770afterThreshold := now .Add (- retentionPeriod ).Add (- 24 * time .Hour )// 31 days ago (older than threshold)
770771beforeThreshold := now .Add (- 15 * 24 * time .Hour )// 15 days ago (newer than threshold)
@@ -774,12 +775,11 @@ func TestDeleteOldAIBridgeRecords(t *testing.T) {
774775db ,_ := dbtestutil .NewDB (t ,dbtestutil .WithDumpOnFailure ())
775776logger := slogtest .Make (t ,& slogtest.Options {IgnoreErrors :true })
776777user := dbgen .User (t ,db , database.User {})
777- apiKey ,_ := dbgen .APIKey (t ,db , database.APIKey {UserID :user .ID })
778778
779779// Create old AI Bridge interception (should be deleted)
780780oldInterception := dbgen .AIBridgeInterception (t ,db , database.InsertAIBridgeInterceptionParams {
781781ID :uuid .New (),
782- APIKeyID : sql.NullString {String : apiKey . ID , Valid : true },
782+ APIKeyID : sql.NullString {},
783783InitiatorID :user .ID ,
784784Provider :"anthropic" ,
785785Model :"claude-3-5-sonnet" ,
@@ -789,14 +789,14 @@ func TestDeleteOldAIBridgeRecords(t *testing.T) {
789789// Create old interception with related records (should all be deleted)
790790oldInterceptionWithRelated := dbgen .AIBridgeInterception (t ,db , database.InsertAIBridgeInterceptionParams {
791791ID :uuid .New (),
792- APIKeyID : sql.NullString {String : apiKey . ID , Valid : true },
792+ APIKeyID : sql.NullString {},
793793InitiatorID :user .ID ,
794794Provider :"openai" ,
795795Model :"gpt-4" ,
796796StartedAt :afterThreshold ,
797797},& afterThreshold )
798798
799- oldTokenUsage : =dbgen .AIBridgeTokenUsage (t ,db , database.InsertAIBridgeTokenUsageParams {
799+ _ = dbgen .AIBridgeTokenUsage (t ,db , database.InsertAIBridgeTokenUsageParams {
800800ID :uuid .New (),
801801InterceptionID :oldInterceptionWithRelated .ID ,
802802ProviderResponseID :"resp-1" ,
@@ -805,15 +805,15 @@ func TestDeleteOldAIBridgeRecords(t *testing.T) {
805805CreatedAt :afterThreshold ,
806806})
807807
808- oldUserPrompt : =dbgen .AIBridgeUserPrompt (t ,db , database.InsertAIBridgeUserPromptParams {
808+ _ = dbgen .AIBridgeUserPrompt (t ,db , database.InsertAIBridgeUserPromptParams {
809809ID :uuid .New (),
810810InterceptionID :oldInterceptionWithRelated .ID ,
811811ProviderResponseID :"resp-1" ,
812812Prompt :"test prompt" ,
813813CreatedAt :afterThreshold ,
814814})
815815
816- oldToolUsage : =dbgen .AIBridgeToolUsage (t ,db , database.InsertAIBridgeToolUsageParams {
816+ _ = dbgen .AIBridgeToolUsage (t ,db , database.InsertAIBridgeToolUsageParams {
817817ID :uuid .New (),
818818InterceptionID :oldInterceptionWithRelated .ID ,
819819ProviderResponseID :"resp-1" ,
@@ -827,7 +827,7 @@ func TestDeleteOldAIBridgeRecords(t *testing.T) {
827827// Create recent AI Bridge interception (should be kept)
828828recentInterception := dbgen .AIBridgeInterception (t ,db , database.InsertAIBridgeInterceptionParams {
829829ID :uuid .New (),
830- APIKeyID : sql.NullString {String : apiKey . ID , Valid : true },
830+ APIKeyID : sql.NullString {},
831831InitiatorID :user .ID ,
832832Provider :"anthropic" ,
833833Model :"claude-3-5-sonnet" ,
@@ -837,13 +837,41 @@ func TestDeleteOldAIBridgeRecords(t *testing.T) {
837837// Create interception close to threshold (should be kept)
838838nearThresholdInterception := dbgen .AIBridgeInterception (t ,db , database.InsertAIBridgeInterceptionParams {
839839ID :uuid .New (),
840- APIKeyID : sql.NullString {String : apiKey . ID , Valid : true },
840+ APIKeyID : sql.NullString {},
841841InitiatorID :user .ID ,
842842Provider :"anthropic" ,
843843Model :"claude-3-5-sonnet" ,
844844StartedAt :closeBeforeThreshold ,
845845},& closeBeforeThreshold )
846846
847+ _ = dbgen .AIBridgeTokenUsage (t ,db , database.InsertAIBridgeTokenUsageParams {
848+ ID :uuid .New (),
849+ InterceptionID :nearThresholdInterception .ID ,
850+ ProviderResponseID :"resp-1" ,
851+ InputTokens :100 ,
852+ OutputTokens :50 ,
853+ CreatedAt :closeBeforeThreshold ,
854+ })
855+
856+ _ = dbgen .AIBridgeUserPrompt (t ,db , database.InsertAIBridgeUserPromptParams {
857+ ID :uuid .New (),
858+ InterceptionID :nearThresholdInterception .ID ,
859+ ProviderResponseID :"resp-1" ,
860+ Prompt :"test prompt" ,
861+ CreatedAt :closeBeforeThreshold ,
862+ })
863+
864+ _ = dbgen .AIBridgeToolUsage (t ,db , database.InsertAIBridgeToolUsageParams {
865+ ID :uuid .New (),
866+ InterceptionID :nearThresholdInterception .ID ,
867+ ProviderResponseID :"resp-1" ,
868+ Tool :"test-tool" ,
869+ ServerUrl : sql.NullString {String :"http://test" ,Valid :true },
870+ Input :"{}" ,
871+ Injected :true ,
872+ CreatedAt :closeBeforeThreshold ,
873+ })
874+
847875// Run the purge with configured retention period
848876done := awaitDoTick (ctx ,t ,clk )
849877closer := dbpurge .New (ctx ,logger ,db ,& codersdk.DeploymentValues {
@@ -869,24 +897,33 @@ func TestDeleteOldAIBridgeRecords(t *testing.T) {
869897
870898require .NotContains (t ,interceptionIDs ,oldInterception .ID ,"old interception should be deleted" )
871899require .NotContains (t ,interceptionIDs ,oldInterceptionWithRelated .ID ,"old interception with related records should be deleted" )
872- require .Contains (t ,interceptionIDs ,recentInterception .ID ,"recent interception should be kept" )
873- require .Contains (t ,interceptionIDs ,nearThresholdInterception .ID ,"near threshold interception should be kept" )
874900
875901// Verify related records were also deleted
876- tokenUsages ,err := db .GetAIBridgeTokenUsagesByInterceptionID (ctx ,oldInterceptionWithRelated .ID )
902+ oldTokenUsages ,err := db .GetAIBridgeTokenUsagesByInterceptionID (ctx ,oldInterceptionWithRelated .ID )
877903require .NoError (t ,err )
878- require .Empty (t ,tokenUsages ,"old token usages should be deleted" )
904+ require .Empty (t ,oldTokenUsages ,"old token usages should be deleted" )
879905
880- userPrompts ,err := db .GetAIBridgeUserPromptsByInterceptionID (ctx ,oldInterceptionWithRelated .ID )
906+ oldUserPrompts ,err := db .GetAIBridgeUserPromptsByInterceptionID (ctx ,oldInterceptionWithRelated .ID )
881907require .NoError (t ,err )
882- require .Empty (t ,userPrompts ,"old user prompts should be deleted" )
908+ require .Empty (t ,oldUserPrompts ,"old user prompts should be deleted" )
883909
884- toolUsages ,err := db .GetAIBridgeToolUsagesByInterceptionID (ctx ,oldInterceptionWithRelated .ID )
910+ oldToolUsages ,err := db .GetAIBridgeToolUsagesByInterceptionID (ctx ,oldInterceptionWithRelated .ID )
885911require .NoError (t ,err )
886- require .Empty (t ,toolUsages ,"old tool usages should be deleted" )
912+ require .Empty (t ,oldToolUsages ,"old tool usages should be deleted" )
887913
888- // Silence unused variable warnings
889- _ = oldTokenUsage
890- _ = oldUserPrompt
891- _ = oldToolUsage
914+ require .Contains (t ,interceptionIDs ,recentInterception .ID ,"recent interception should be kept" )
915+ require .Contains (t ,interceptionIDs ,nearThresholdInterception .ID ,"near threshold interception should be kept" )
916+
917+ // Verify related records were NOT deleted
918+ newTokenUsages ,err := db .GetAIBridgeTokenUsagesByInterceptionID (ctx ,nearThresholdInterception .ID )
919+ require .NoError (t ,err )
920+ require .Len (t ,newTokenUsages ,1 ,"near threshold token usages should not be deleted" )
921+
922+ newUserPrompts ,err := db .GetAIBridgeUserPromptsByInterceptionID (ctx ,nearThresholdInterception .ID )
923+ require .NoError (t ,err )
924+ require .Len (t ,newUserPrompts ,1 ,"near threshold user prompts should not be deleted" )
925+
926+ newToolUsages ,err := db .GetAIBridgeToolUsagesByInterceptionID (ctx ,nearThresholdInterception .ID )
927+ require .NoError (t ,err )
928+ require .Len (t ,newToolUsages ,1 ,"near threshold tool usages should not be deleted" )
892929}