Vulnerability UUID Migration Phase 2: Backfill new_uuid for existing vulnerabilities
<!--IssueSummary start-->
<details>
<summary>
Everyone can contribute. [Help move this issue forward](https://handbook.gitlab.com/handbook/marketing/developer-relations/contributor-success/community-contributors-workflows/#contributor-links) while earning points, leveling up and collecting rewards.
</summary>
- [Close this issue](https://contributors.gitlab.com/manage-issue?action=close&projectId=278964&issueIid=587802)
</details>
<!--IssueSummary end-->
## Problem
After Phase 1 (#587624) starts populating `new_uuid` for new vulnerabilities, existing vulnerabilities will still have NULL values in the `new_uuid` column. We need to backfill these with definition-level UUIDs.
## Background
**UUID composition for Vulnerability (definition - location-agnostic):**
- Report type
- Primary identifier fingerprint
- Project ID
**NOT included:**
- Location fingerprint
- Security_project_tracked_context_id
## Implementation
1. Create a batched background migration (BBM) to backfill `new_uuid` for all vulnerabilities where `new_uuid IS NULL`
2. The migration should:
- Process rows in batches to avoid locking issues
- Calculate the definition-level UUID using `Security::VulnerabilityUUID` (without location)
- Join to findings to get primary identifier fingerprint
3. Add migration tracking and monitoring
4. Verify completion before proceeding to Phase 3
## Acceptance Criteria
- [ ] BBM created and tested
- [ ] All existing vulnerabilities have `new_uuid` populated
- [ ] Migration completes successfully on GitLab.com
- [ ] No performance degradation during migration
## Dependencies
- Blocked by #587624 (Phase 1 must be complete first)
## Related
- Part of Vulnerability UUID migration series
- #587624 - Phase 1: Start populating new_uuid
- Related to #587625 (Finding UUID - context-aware)
issue