fix: skip onboarding when insights project was soft-deleted (CM-1138) - #4568
fix: skip onboarding when insights project was soft-deleted (CM-1138)#4568ulemons wants to merge 3 commits into
Conversation
PR SummaryMedium Risk Overview Adds Onboarder HTTP errors now append a truncated response body via Reviewed by Cursor Bugbot for commit ccf26bb. Bugbot is set up for automated code reviews on this repo. Configure here. |
A soft-deleted insightsProjects row still owns its slug (the unique index can't be made partial on deletedAt: three FKs reference it), so segment creation returned an opaque HTTP 500 for repos like gerrit whose insights project had been deliberately removed. Instead of retrying forever, check for a soft-deleted row up front and mark the project catalog entry as skipped with a tracked reason for manual review, per Joana's call to evaluate these one by one. Also surface the HTTP error response body in onboarding failures so future issues are diagnosable from onboardingError alone. Signed-off-by: Umberto Sgueglia <usgueglia@contractor.linuxfoundation.org>
caaf8ca to
0907877
Compare
There was a problem hiding this comment.
Pull request overview
Prevents onboarding when a matching insights project was soft-deleted, preserving it for manual review.
Changes:
- Adds persisted skip reasons and guarded skip transitions.
- Detects deleted insights projects before onboarding.
- Improves HTTP error diagnostics and test coverage.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
project-catalog/types.ts |
Adds skip-reason types. |
project-catalog/projectCatalog.ts |
Persists and updates skip reasons. |
project-catalog/projectCatalog.test.ts |
Tests guarded skip transitions. |
collections/index.ts |
Adds deleted-inclusive slug lookup. |
collections/index.test.ts |
Tests slug lookup behavior. |
workflows/onboardProjects.ts |
Tracks skipped outcomes. |
automatic_onboarding_worker/src/types.ts |
Defines onboarding outcomes. |
onboarder/onboarder.ts |
Includes response bodies in errors. |
onboarder/onboarder.test.ts |
Tests error-body handling. |
activities/insightsProjectSkip.ts |
Builds skip reasons. |
activities/insightsProjectSkip.test.ts |
Tests reason formatting. |
activities/activities.ts |
Adds the deleted-project pre-check. |
V1788516039__skip-reason-to-project-catalog.sql |
Adds the database column. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Signed-off-by: Umberto Sgueglia <usgueglia@contractor.linuxfoundation.org>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
services/libs/data-access-layer/src/project-catalog/types.ts:63
IDbProjectCatalogCreatenow advertises that callers can persistskipReason, butinsertProjectCatalog, both bulk paths, andupsertProjectCatalogomit that field from their SQL/value maps, so it is silently discarded. Either wire the field through every create path or, since this PR only writes it during a transition, remove it from the create contract.
Signed-off-by: Umberto Sgueglia <usgueglia@contractor.linuxfoundation.org>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
Previously missed (1) — in code that hasn't changed since the last review.
services/libs/data-access-layer/src/project-catalog/projectCatalog.ts:579
- This line only narrates the visible SQL assignment and is not needed to preserve the non-obvious concurrency constraint. Remove it to follow the repository's comments convention while retaining the guard rationale.
services/apps/automatic_onboarding_worker/src/onboarder/onboarder.test.ts:21
- A
Responseconstructed with a null body has no stream to disturb, so the secondtext()call can return''normally and this test does not exercisereadErrorBody's catch branch. Use a non-empty body before consuming it once.
const response = new Response(null)
| onboardingError?: string | null | ||
| skipReason?: string | null |
Summary
gerritcodereview/gerrit(and any other repo whoseinsightsProjectsrow wasdeliberately soft-deleted in the 2026-04 cleanup) failed re-onboarding with an opaque
Segment creation returned HTTP 500: Internal Server Error. The insights project'sslug unique index can't be made partial on
deletedAt(three FKs fromsecurityInsights*tables reference it), so the soft-deleted row still owns the slugand blocks creating a new one. Per Joana's decision, we don't resurrect these
automatically — we skip onboarding, track a reason, and leave the list for manual
review one by one.
Changes
projectCatalog.skipReasoncolumn (migration) — kept separate fromonboardingError(a skip isn't an error) and fromevaluationReason(these rowshave
evaluationResult = 'true', so a non-onboarding reason there would becontradictory).
findInsightsProjectBySlugIncludingDeletedDAL lookup — deliberately does notapply
injectSoftDeletionCriteriaand doesn't touch the existingqueryInsightsProjects(blast-radius avoidance).markProjectCatalogOnboardingSkipped, same guard asmarkProjectCatalogOnboardingFailed(action = 'onboard' AND onboardedAt IS NULL)so a concurrent manual action always wins; clears any stale
onboardingErrorfrom aprior failed attempt.
onboardAndUpdateProjectpre-checks for a soft-deleted insights project beforecalling the onboarding API; on a match it skips the HTTP call entirely and returns a
typed
'skipped'outcome, counted separately fromsucceeded/failedin the batchlog.
(truncated to 500 chars), so future failures are diagnosable from
onboardingErroralone instead of needing the Slack error-reporter.and error-body truncation (passing), plus Postgres-backed DAL tests for the new
lookup and writer (written, not yet run in this environment — local test DB port
5434 is occupied by an unrelated container).
Post-merge / verification (manual, on staging/prod)
skipReasonexists.action = 'skip'with askipReasonciting the deletiondate, and no segment/subproject gets created.
Type of change
JIRA ticket
https://linuxfoundation.atlassian.net/browse/CM-1138