Migrate `Vulnerability::Read` create / update logic from postgresql to Rails
<!--Implementation issues are used break-up a large piece of work into small, discrete tasks that can move independently through the build workflow steps. They're typically used to populate a Feature Epic. Once created, an implementation issue is usually refined in order to populate and review the implementation plan and weight. Example workflow: https://about.gitlab.com/handbook/engineering/development/threat-management/planning/diagram.html#plan--> ## Why are we doing this work <!--A brief explanation of the why, not the what or how. Assume the reader doesn't know the background and won't have time to dig-up information from comment threads.--> `Vulnerability::Read` records are currently created / updated via PostgresQL triggers. This has many downsides. 1. It's difficult to change. Every update requires creating a database migration with raw SQL. There is not even a file that we can edit. e.g. https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112233 2. It's invisible when reading or grepping application code. 3. It's difficult to test, since it's decoupled from the application. 4. It's not re-useable. 5. It has less flexibility compared to Ruby and the triggers have grown more complex over time, to the point where they would benefit from being written in a more flexible language. 6. Reviewers aren't accustomed to seeing business logic written in plpgsql, which means that there is a lack of domain expertise among reviewers. 7. We cannot make use of other application-level logic (ex: feature flags). We should migrate this logic from Postgres over to Rails. ## Relevant links <!--Information that the developer might need to refer to when implementing the issue. - [Design Issue](https://gitlab.com/gitlab-org/gitlab/-/issues/<id>) - [Design 1](https://gitlab.com/gitlab-org/gitlab/-/issues/<id>/designs/<image>.png) - [Design 2](https://gitlab.com/gitlab-org/gitlab/-/issues/<id>/designs/<image>.png) - [Similar implementation](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/<id>)--> - https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112233#note_1299594178 - https://gitlab.com/gitlab-org/gitlab/-/issues/386434#note_1282045681 ## Non-functional requirements <!--Add details for required items and delete others.--> - [ ] Documentation: - [ ] Feature flag: - [ ] Performance: - [ ] Testing: ## Implementation plan <!--Steps and the parts of the code that will need to get updated. The plan can also call-out responsibilities for other team members or teams and can be split into smaller MRs to simplify the code review process. e.g.: - MR 1: Part 1 - [ ] gitlab~3412464 Step 1 - [ ] gitlab~3412464 Step 2 - MR 2: Part 2 - [ ] gitlab~2492649 Step 1 - [ ] gitlab~2492649 Step 2 - MR 3: Part 3 - [ ] gitlab~3412464 Step 1 - [ ] gitlab~3412464 Step 2--> Considerations: 1. Security report ingestion uses bulk inserts which prevents us from using traditional Rails models. For cases where we need to check values before and after update (ex: Create a vulnerability_read when a vulnerability becomes present on the default branch), we'd need to have the insert return that value and manually check it. 2. Vulnerabilities / Findings can be created from multiple places and we need to ensure that all of them create / update Reads in a consistent manner. <!--Workflow and other relevant labels # ~"group::" ~"Category:" gitlab~3207279 Other settings you might want to include when creating the issue. # /assign @ # /epic &--> ## Verification steps <!--Add verification steps to help GitLab team members test the implementation. This is particularly useful during the MR review and the gitlab~11090870 step. You may not know exactly what the verification steps should be during issue refinement, so you can always come back later to add them. 1. Check-out the corresponding branch 1. ... 1. Profit!-->
epic