fix: security results update (IN-1093)#4029
Conversation
Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
There was a problem hiding this comment.
Pull request overview
Updates security insights DAL upsert behavior so insightsProjectId and insightsProjectSlug are also updated during ON CONFLICT DO UPDATE, keeping these fields consistent when re-processing results for an existing suite/evaluation/assessment.
Changes:
- Extend
addEvaluationSuiteupsert conflict-update to includeinsightsProjectIdandinsightsProjectSlug. - Extend
addSuiteControlEvaluationupsert conflict-update to includeinsightsProjectIdandinsightsProjectSlug. - Extend
addControlEvaluationAssessmentupsert conflict-update to includeinsightsProjectIdandinsightsProjectSlug.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| set "updatedAt" = EXCLUDED."updatedAt", | ||
| "name" = EXCLUDED."name", | ||
| "result" = EXCLUDED."result", | ||
| "corruptedState" = EXCLUDED."corruptedState", | ||
| "insightsProjectId" = EXCLUDED."insightsProjectId", | ||
| "insightsProjectSlug" = EXCLUDED."insightsProjectSlug" |
There was a problem hiding this comment.
insightsProjectSlug has a FK to insightsProjects.slug with ON UPDATE CASCADE (see backend/src/database/migrations/V1753457861__add_unique_contraint_on_insights_slug.sql). Updating the slug from EXCLUDED during the conflict update can cause the upsert to fail if the caller provides a stale slug (e.g., slug changed between read and write); previously the row would keep the cascaded/current slug. Consider not updating insightsProjectSlug on conflict, or deriving it from insightsProjectId/insightsProjects inside the update so it always remains valid/current.
| set "updatedAt" = EXCLUDED."updatedAt", | |
| "name" = EXCLUDED."name", | |
| "result" = EXCLUDED."result", | |
| "corruptedState" = EXCLUDED."corruptedState", | |
| "insightsProjectId" = EXCLUDED."insightsProjectId", | |
| "insightsProjectSlug" = EXCLUDED."insightsProjectSlug" | |
| set "updatedAt" = EXCLUDED."updatedAt", | |
| "name" = EXCLUDED."name", | |
| "result" = EXCLUDED."result", | |
| "corruptedState" = EXCLUDED."corruptedState", | |
| "insightsProjectId" = EXCLUDED."insightsProjectId" |
| "corruptedState" = EXCLUDED."corruptedState", | ||
| "remediationGuide" = EXCLUDED."remediationGuide", | ||
| "insightsProjectId" = EXCLUDED."insightsProjectId", | ||
| "insightsProjectSlug" = EXCLUDED."insightsProjectSlug" |
There was a problem hiding this comment.
insightsProjectSlug is enforced via FK to insightsProjects.slug (ON UPDATE CASCADE). Setting it to EXCLUDED.insightsProjectSlug on conflict makes this upsert sensitive to stale slug inputs (race with slug rename) and can cause FK violations at update time. Safer options are to avoid updating the slug on conflict, or compute the slug from insightsProjectId/insightsProjects in the update.
| "insightsProjectSlug" = EXCLUDED."insightsProjectSlug" | |
| "insightsProjectSlug" = ( | |
| select "slug" | |
| from "insightsProjects" | |
| where "id" = EXCLUDED."insightsProjectId" | |
| ) |
| "insightsProjectId" = EXCLUDED."insightsProjectId", | ||
| "insightsProjectSlug" = EXCLUDED."insightsProjectSlug" |
There was a problem hiding this comment.
Like the other security insights tables, insightsProjectSlug has an FK to insightsProjects.slug with ON UPDATE CASCADE. Updating it from EXCLUDED during the upsert can fail if the caller’s slug is stale (after a rename) and may undo the cascaded value. Consider leaving insightsProjectSlug untouched on conflict, or deriving it from insightsProjectId/insightsProjects within the update clause to guarantee consistency.
| "insightsProjectId" = EXCLUDED."insightsProjectId", | |
| "insightsProjectSlug" = EXCLUDED."insightsProjectSlug" | |
| "insightsProjectId" = EXCLUDED."insightsProjectId" |
This pull request updates several database upsert operations in the
security_insightsdata access layer to include two new fields:insightsProjectIdandinsightsProjectSlug. These fields are now handled consistently across the relevant insert/update functions.Database schema and data consistency improvements:
insightsProjectIdandinsightsProjectSlugto the upsert statement inaddEvaluationSuite, ensuring these fields are updated when conflicts occur.addSuiteControlEvaluationto includeinsightsProjectIdandinsightsProjectSlugin conflict resolution.addControlEvaluationAssessmentto handleinsightsProjectIdandinsightsProjectSlugas part of the conflict update.Note
Medium Risk
Changes persistence behavior for security insights results by updating
insightsProjectId/insightsProjectSlugon conflict, which could overwrite existing values for the same(repo, catalog/control/requirement)keys if upstream data is wrong.Overview
Ensures security insights result upserts keep project metadata in sync by updating
insightsProjectIdandinsightsProjectSlugduring conflict resolution.This applies to suite (
securityInsightsEvaluationSuites), control evaluation (securityInsightsEvaluations), and assessment (securityInsightsEvaluationAssessments) inserts so re-runs no longer leave stale project identifiers when rows already exist.Reviewed by Cursor Bugbot for commit 11dde9f. Bugbot is set up for automated code reviews on this repo. Configure here.