From 526959fd2ca46c73300b62153535a91fb7f70028 Mon Sep 17 00:00:00 2001 From: Daniel Batica Date: Wed, 18 Mar 2026 16:16:09 +0100 Subject: [PATCH 1/2] feat: pass opportunityId to assess-urls worker for precheck persistence Include opportunityId in SQS message for assess-urls action to enable worker to fetch and update suggestion entities with precheck results, preventing data loss from async Lambda invocations. Co-Authored-By: Claude Sonnet 4.5 --- src/controllers/suggestions.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/controllers/suggestions.js b/src/controllers/suggestions.js index 1ca2078d1..afc541de1 100644 --- a/src/controllers/suggestions.js +++ b/src/controllers/suggestions.js @@ -970,14 +970,22 @@ function SuggestionsController(ctx, sqs, env) { return badRequest(`Handler is not enabled for site ${site.getId()} autofix type ${opportunity.getType()}`); } const { AUTOFIX_JOBS_QUEUE: queueUrl } = env; - // Intentionally omit opportunityId: worker uses context differently for URL-based assessments - await sqs.sendMessage(queueUrl, { + await sqs.sendMessage( + queueUrl, + { + siteId, + opportunityId, + action: 'assess-urls', + pages, + ...(precheckOnly === true && { precheckOnly: true }), + }, + ); + return accepted({ + message: 'Assess-urls job queued', siteId, - action: 'assess-urls', - pages, - ...(precheckOnly === true && { precheckOnly: true }), + opportunityId, + pagesCount: pages.length, }); - return accepted({ message: 'Assess-urls job queued', siteId, pagesCount: pages.length }); } // suggestion-based flow (assess, fix, etc.) From c726188d1bef3ac1222d2289d8ca33bdb4c2a412 Mon Sep 17 00:00:00 2001 From: Daniel Batica Date: Wed, 18 Mar 2026 17:07:16 +0100 Subject: [PATCH 2/2] test: add opportunityId verification for assess-urls action Update existing test to verify opportunityId is included in both the response body and SQS message payload. Add dedicated test to explicitly verify opportunityId is passed to worker for precheck result persistence. Co-Authored-By: Claude Sonnet 4.5 --- test/controllers/suggestions.test.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/controllers/suggestions.test.js b/test/controllers/suggestions.test.js index 2bf26d698..91f3a1cd5 100644 --- a/test/controllers/suggestions.test.js +++ b/test/controllers/suggestions.test.js @@ -3922,11 +3922,13 @@ describe('Suggestions Controller', () => { const body = await response.json(); expect(body).to.have.property('message', 'Assess-urls job queued'); expect(body).to.have.property('siteId', SITE_ID); + expect(body).to.have.property('opportunityId', OPPORTUNITY_ID); expect(body).to.have.property('pagesCount', 2); expect(mockSqs.sendMessage).to.have.been.calledOnce; const payload = mockSqs.sendMessage.firstCall.args[1]; expect(payload).to.have.property('siteId', SITE_ID); + expect(payload).to.have.property('opportunityId', OPPORTUNITY_ID); expect(payload).to.have.property('action', 'assess-urls'); expect(payload).to.deep.include({ pages }); }); @@ -3944,6 +3946,29 @@ describe('Suggestions Controller', () => { expect(payload).to.have.property('precheckOnly', true); }); + it('passes opportunityId to worker for precheck result persistence', async () => { + const pages = ['https://example.com/page1', 'https://example.com/page2']; + const response = await suggestionsController.autofixSuggestions({ + params: { siteId: SITE_ID, opportunityId: OPPORTUNITY_ID }, + data: { action: 'assess-urls', pages }, + ...context, + }); + + expect(response.status).to.equal(202); + const body = await response.json(); + expect(body).to.have.property('opportunityId', OPPORTUNITY_ID); + + expect(mockSqs.sendMessage).to.have.been.calledOnce; + const payload = mockSqs.sendMessage.firstCall.args[1]; + expect(payload).to.have.property('opportunityId', OPPORTUNITY_ID); + // Verify opportunityId is passed alongside siteId and action + expect(payload).to.include({ + siteId: SITE_ID, + opportunityId: OPPORTUNITY_ID, + action: 'assess-urls', + }); + }); + it('accepts pages as array of objects with pageUrl and imageUrls', async () => { const pages = [ {