1- import { db } from '@sim/db'
1+ import { db , dbFor } from '@sim/db'
22import {
33 copilotChats ,
44 document ,
@@ -37,6 +37,13 @@ import { deleteFileMetadata } from '@/lib/uploads/server/metadata'
3737
3838const logger = createLogger ( 'CleanupSoftDeletes' )
3939
40+ /**
41+ * Cleanup queries run on the dedicated cleanup pool. The one exception is the
42+ * billable-file transaction below, which couples row deletion with a storage
43+ * billing decrement — billing writes stay on the default client.
44+ */
45+ const cleanupDb = dbFor ( 'cleanup' )
46+
4047const KB_ORPHAN_BINDING_BATCH_SIZE = 500
4148const KB_ORPHAN_BINDING_TOTAL_LIMIT = 5_000
4249/**
@@ -81,7 +88,7 @@ async function selectExpiredWorkspaceFiles(
8188) : Promise < WorkspaceFileScope > {
8289 const [ legacyRows , multiContextRows ] = await Promise . all ( [
8390 selectRowsByIdChunks ( workspaceIds , ( chunkIds , chunkLimit ) =>
84- db
91+ cleanupDb
8592 . select ( {
8693 id : workspaceFile . id ,
8794 key : workspaceFile . key ,
@@ -98,7 +105,7 @@ async function selectExpiredWorkspaceFiles(
98105 . limit ( chunkLimit )
99106 ) ,
100107 selectRowsByIdChunks ( workspaceIds , ( chunkIds , chunkLimit ) =>
101- db
108+ cleanupDb
102109 . select ( {
103110 id : workspaceFiles . id ,
104111 key : workspaceFiles . key ,
@@ -200,7 +207,7 @@ async function deleteExpiredLegacyWorkspaceFileRows(
200207 const result = { deleted : 0 , failed : 0 }
201208 for ( const batch of chunkArray ( rows , DEFAULT_DELETE_CHUNK_SIZE ) ) {
202209 try {
203- const deleted = await db
210+ const deleted = await cleanupDb
204211 . delete ( workspaceFile )
205212 . where (
206213 and (
@@ -240,7 +247,7 @@ async function deleteExpiredUnbilledWorkspaceFileRows(
240247 for ( const [ context , contextRows ] of rowsByContext ) {
241248 for ( const batch of chunkArray ( contextRows , DEFAULT_DELETE_CHUNK_SIZE ) ) {
242249 try {
243- const deleted = await db
250+ const deleted = await cleanupDb
244251 . delete ( workspaceFiles )
245252 . where (
246253 and (
@@ -343,7 +350,7 @@ async function hardDeleteKnowledgeBaseDocuments(
343350 label : string
344351) : Promise < void > {
345352 for ( let batch = 0 ; batch < KB_DOCUMENT_DELETE_MAX_BATCHES ; batch ++ ) {
346- const documentRows = await db
353+ const documentRows = await cleanupDb
347354 . select ( { id : document . id } )
348355 . from ( document )
349356 . where ( inArray ( document . knowledgeBaseId , knowledgeBaseIds ) )
@@ -358,7 +365,7 @@ async function hardDeleteKnowledgeBaseDocuments(
358365 }
359366 }
360367
361- const remaining = await db
368+ const remaining = await cleanupDb
362369 . select ( { id : document . id } )
363370 . from ( document )
364371 . where ( inArray ( document . knowledgeBaseId , knowledgeBaseIds ) )
@@ -378,8 +385,9 @@ async function cleanupExpiredKnowledgeBases(
378385 workspaceIds,
379386 tableName : `${ label } /knowledgeBase` ,
380387 batchSize : KB_RETENTION_BATCH_SIZE ,
388+ dbClient : cleanupDb ,
381389 selectChunk : ( chunkIds , limit ) =>
382- db
390+ cleanupDb
383391 . select ( { id : knowledgeBase . id } )
384392 . from ( knowledgeBase )
385393 . where (
@@ -458,7 +466,7 @@ async function cleanupOrphanedKnowledgeBaseBindings(
458466 KB_ORPHAN_BINDING_BATCH_SIZE ,
459467 KB_ORPHAN_BINDING_TOTAL_LIMIT - attempted
460468 )
461- const rows = await db
469+ const rows = await cleanupDb
462470 . select ( { key : workspaceFiles . key } )
463471 . from ( workspaceFiles )
464472 . where (
@@ -535,7 +543,7 @@ export async function runCleanupSoftDeletes(payload: CleanupJobPayload): Promise
535543 // different subsets above the LIMIT cap and orphan or prematurely purge data.
536544 const [ doomedWorkflows , fileScope ] = await Promise . all ( [
537545 selectRowsByIdChunks ( workspaceIds , ( chunkIds , chunkLimit ) =>
538- db
546+ cleanupDb
539547 . select ( { id : workflow . id } )
540548 . from ( workflow )
541549 . where (
@@ -555,7 +563,7 @@ export async function runCleanupSoftDeletes(payload: CleanupJobPayload): Promise
555563
556564 if ( doomedWorkflowIds . length > 0 ) {
557565 const doomedChats = await selectRowsByIdChunks ( doomedWorkflowIds , ( chunkIds , chunkLimit ) =>
558- db
566+ cleanupDb
559567 . select ( { id : copilotChats . id } )
560568 . from ( copilotChats )
561569 . where ( inArray ( copilotChats . workflowId , chunkIds ) )
@@ -577,7 +585,8 @@ export async function runCleanupSoftDeletes(payload: CleanupJobPayload): Promise
577585 workflow ,
578586 workflow . id ,
579587 doomedWorkflowIds ,
580- `${ label } /workflow`
588+ `${ label } /workflow` ,
589+ cleanupDb
581590 )
582591 totalDeleted += workflowResult . deleted
583592
@@ -614,6 +623,7 @@ export async function runCleanupSoftDeletes(payload: CleanupJobPayload): Promise
614623 retentionDate,
615624 tableName : `${ label } /${ target . name } ` ,
616625 requireTimestampNotNull : true ,
626+ dbClient : cleanupDb ,
617627 } )
618628 totalDeleted += result . deleted
619629 }
0 commit comments