@@ -269,6 +269,31 @@ describe('cleanup-failed', () => {
269269 expect ( updates ( ) ) . toHaveLength ( 0 )
270270 expect ( mockInvalidateDeployedStateCache ) . not . toHaveBeenCalled ( )
271271 } )
272+
273+ it ( 'attempts every workflow, then reports a workflow-scoped cleanup failure' , async ( ) => {
274+ queueTableRows ( workflowDeploymentVersion , [
275+ { id : 'dv-failed' , version : 5 , state : versionState ( 'failed-kb' ) } ,
276+ ] )
277+ queueTableRows ( workflowDeploymentVersion , [
278+ { id : 'dv-cleaned' , version : 5 , state : versionState ( 'failed-kb' ) } ,
279+ ] )
280+ dbChainMockFns . set . mockImplementationOnce ( ( ) => {
281+ throw new Error ( 'first workflow update failed' )
282+ } )
283+
284+ await expect (
285+ clearFailedReferencesInDeploymentVersions (
286+ new Set ( [ 'wf-failed' , 'wf-cleaned' ] ) ,
287+ failedByKind ( ) ,
288+ 'test'
289+ )
290+ ) . rejects . toThrow ( 'Failed to clear deployment-version references for 1 workflow(s)' )
291+
292+ // The second workflow is still processed after the first workflow's update fails.
293+ expect ( dbChainMockFns . update ) . toHaveBeenCalledTimes ( 2 )
294+ expect ( mockInvalidateDeployedStateCache ) . toHaveBeenCalledTimes ( 1 )
295+ expect ( mockInvalidateDeployedStateCache ) . toHaveBeenCalledWith ( 'dv-cleaned' )
296+ } )
272297 } )
273298
274299 describe ( 'clearFailedForkResourceReferences' , ( ) => {
@@ -376,5 +401,26 @@ describe('cleanup-failed', () => {
376401 // The drop is skipped, so the placeholder row survives (no delete issued).
377402 expect ( dbChainMockFns . delete ) . not . toHaveBeenCalled ( )
378403 } )
404+
405+ it ( 'keeps placeholders when a deployed-version cleanup fails after draft cleanup succeeds' , async ( ) => {
406+ queueTableRows ( workflow , [ { id : 'wf-1' } ] )
407+ queueTableRows ( workflowBlocks , [ draftBlockRow ( 'other-kb' ) ] )
408+ queueTableRows ( workflowDeploymentVersion , [
409+ { id : 'dv-failed' , version : 5 , state : versionState ( 'failed-kb' ) } ,
410+ ] )
411+ dbChainMockFns . set . mockImplementationOnce ( ( ) => {
412+ throw new Error ( 'deployment update failed' )
413+ } )
414+
415+ const cleaned = await clearFailedForkResourceReferences ( {
416+ childWorkspaceId : 'child-ws' ,
417+ failures : [ { kind : 'knowledge-base' , childId : 'failed-kb' , documentChildIds : [ ] } ] ,
418+ deployedTargetWorkflowIds : [ 'wf-deployed' ] ,
419+ requestId : 'test' ,
420+ } )
421+
422+ expect ( cleaned ) . toEqual ( { cleared : 0 , clearingFailed : true } )
423+ expect ( dbChainMockFns . delete ) . not . toHaveBeenCalled ( )
424+ } )
379425 } )
380426} )
0 commit comments