Introduce concept of Merge Request Violation
<!-- 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 To implement the [next iteration of the "Compliance Dashboard"](https://gitlab.com/gitlab-org/gitlab/-/issues/299359) we should store compliance violations such as a failure of [separations of duties](https://docs.gitlab.com/ee/user/compliance/compliance_dashboard/#approval-status-and-separation-of-duties). Currently this information is generated on-the-fly but this proposal is to create a new domain model: `MergeRequests::ComplianceViolation` which encapsulates information about a single failure of an MR to adhere to a particular hard-coded rule. Examples of these include: * When an author approves their own MR. * When a committer approves their own MR. * When an MR is merged with an `X%` drop of code coverage. We should implement the following: * The new domain model as above. * Implementation of the new violation objects when an MR is merged. * A GraphQL implementation to allow the group-level querying of data for a group's merge requests. ## Proposed Data Structure * `MergeRequest` has zero or more `MergeRequests::ComplianceViolation` * Before merging, a `MergeRequest` **should have NO violations.** | Column Name | Type | Example | Notes | | ------ | ------ | ------ | ------ | | `merge_request_id` | bigint (foreign key on `merge_requests.id`) | `1` | Which MR? | | `violating_user_id` | bigint | (foreign key on `users.id`) | `1` | Which user _caused_ the violation? (Not who merged it, we can figure that out from the association to MR.) | | `reason` | enum | `approved_by_author: 0`, `approved_by_committer: 1`, `approved_by_insufficient_users: 2` | What caused the violation? We can map each of these to a hard-coded severity as defined by us. |
epic