From 5b348f3ac17706b060b8b64817b14a0c0d6c3138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 22 May 2026 16:34:06 +0200 Subject: [PATCH] refactor(catalog-backend): make stitchTicket required in performStitching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that immediate mode is removed, the stitch ticket is always provided by the deferred worker. Remove the optional marker and all the conditional guards that checked for its presence. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Fredrik Adelöw --- .../operations/stitcher/performStitching.test.ts | 8 ++++++++ .../operations/stitcher/performStitching.ts | 13 ++++++------- .../src/stitching/DefaultStitcher.ts | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/plugins/catalog-backend/src/database/operations/stitcher/performStitching.test.ts b/plugins/catalog-backend/src/database/operations/stitcher/performStitching.test.ts index a3324c2881..eca65c4985 100644 --- a/plugins/catalog-backend/src/database/operations/stitcher/performStitching.test.ts +++ b/plugins/catalog-backend/src/database/operations/stitcher/performStitching.test.ts @@ -349,12 +349,20 @@ describe.each(databases.eachSupportedId())( }, ]); + await markForStitching({ knex, entityRefs: ['k:ns/n'] }); + const stitchLogger = mockServices.logger.mock(); await expect( performStitching({ knex, logger: stitchLogger, entityRef: 'k:ns/n', + stitchTicket: ( + await knex('stitch_queue') + .where('entity_ref', 'k:ns/n') + .select('stitch_ticket') + .first() + )?.stitch_ticket, }), ).resolves.toBe('changed'); diff --git a/plugins/catalog-backend/src/database/operations/stitcher/performStitching.ts b/plugins/catalog-backend/src/database/operations/stitcher/performStitching.ts index 786929c595..061a196d8a 100644 --- a/plugins/catalog-backend/src/database/operations/stitcher/performStitching.ts +++ b/plugins/catalog-backend/src/database/operations/stitcher/performStitching.ts @@ -52,10 +52,9 @@ export async function performStitching(options: { knex: Knex | Knex.Transaction; logger: LoggerService; entityRef: string; - stitchTicket?: string; + stitchTicket: string; }): Promise<'changed' | 'unchanged' | 'abandoned'> { - const { knex, logger, entityRef } = options; - const stitchTicket = options.stitchTicket; + const { knex, logger, entityRef, stitchTicket } = options; // The entity is removed from the stitch queue on ANY completion, except when // an exception is thrown. In the latter case, the entity will be retried at a @@ -205,7 +204,7 @@ export async function performStitching(options: { // stitch cycle). const isMySQL = String(knex.client.config.client).includes('mysql'); - if (stitchTicket && isMySQL) { + if (isMySQL) { const ticketValid = await knex('stitch_queue') .where('entity_ref', entityRef) .where('stitch_ticket', stitchTicket) @@ -229,7 +228,7 @@ export async function performStitching(options: { .onConflict('entity_id') .merge(['final_entity', 'hash', 'last_updated_at']); - if (stitchTicket && !isMySQL) { + if (!isMySQL) { upsert = upsert.where( knex.raw( 'exists (select 1 from stitch_queue where entity_ref = ? and stitch_ticket = ?)', @@ -244,7 +243,7 @@ export async function performStitching(options: { // database engines (row IDs vs row counts vs empty arrays), so we // check the hash directly — we already know hash !== previousHash // from the check above, so a mismatch means the write was blocked. - if (stitchTicket && !isMySQL) { + if (!isMySQL) { const written = await knex('final_entities') .where('entity_id', entityId) .where('hash', hash) @@ -265,7 +264,7 @@ export async function performStitching(options: { removeFromStitchQueueOnCompletion = false; throw error; } finally { - if (removeFromStitchQueueOnCompletion && stitchTicket) { + if (removeFromStitchQueueOnCompletion) { await markDeferredStitchCompleted({ knex: knex, entityRef, diff --git a/plugins/catalog-backend/src/stitching/DefaultStitcher.ts b/plugins/catalog-backend/src/stitching/DefaultStitcher.ts index a6f794a0aa..61d71f1a40 100644 --- a/plugins/catalog-backend/src/stitching/DefaultStitcher.ts +++ b/plugins/catalog-backend/src/stitching/DefaultStitcher.ts @@ -128,7 +128,7 @@ export class DefaultStitcher { async #stitchOne(options: { entityRef: string; - stitchTicket?: string; + stitchTicket: string; stitchRequestedAt?: DateTime; }) { const track = this.tracker.stitchStart({