SD/Exclude No Longer Detected - Backend - Backfill detection_transitions

What does this MR do and why?

With this backfill we mark historical vulnerability findings as no longer detected by creating a detection_transition record when:

  • The vulnerability has resolved_on_default_branch = true
  • The finding's updated_at < fixed_date (cutoff date)
  • No detection_transition record already exists for the finding

References

#582985

Database

Query Plan:

SELECT "vulnerability_occurrences"."id", "vulnerability_occurrences"."project_id" FROM "vulnerability_occurrences" INNER JOIN vulnerabilities ON vulnerabilities.id = vulnerability_occurrences.vulnerability_id WHERE "vulnerabilities"."resolved_on_default_branch" = TRUE AND "vulnerability_occurrences"."id" BETWEEN 1 AND 10000

How to set up and validate locally

  1. Run this in your GDK rails console by running bin/rails c

  2. Run the following:

    job = Gitlab::BackgroundMigration::BackfillVulnerabilityDetectionTransitions.new(
      start_id: Vulnerabilities::Finding.minimum(:id),
      end_id: Vulnerabilities::Finding.maximum(:id),
      batch_table: :vulnerability_occurrences,
      batch_column: :id,
      sub_batch_size: 500,
      pause_ms: 0,
      connection: SecApplicationRecord.connection
    )
    
    job.perform
    # this should return: #=> nil
  3. Check if the transitions were created, by running `

    Vulnerabilities::DetectionTransition.count
    # should return any number > 0
  4. Check if the records are created

    Vulnerabilities::DetectionTransition.last(3)
    #Should show records with:
    #   - detected: false
    #   - created_at: "2025-12-15 00:00:00.000000000 +0000",
    #   - vulnerability_occurrence_id: <some finding id>

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Charlie Kroon

Merge request reports

Loading