[601174 Phase 3] Expose persistent MR ↔ Work Item relations via GraphQL + deprecate linkedWorkItems
Part of #601174 (Option B implementation). Depends on Phases 1 and 2. **Scope:** New persistent GraphQL field + mutations; deprecate the existing experimental `linkedWorkItems` field. Also introduces the `mr_work_item_relations` feature flag (moved here from Phase 1 — the flag must ship with its first caller, which lives in this slice). ### Feature flag - `config/feature_flags/wip/mr_work_item_relations.yml` (type: `wip`, default off, group `group::project management`). - First callers: the new GraphQL resolver returns `nil` when disabled; the new mutations fail authorization when disabled. ### Changes - New PORO `app/models/merge_requests/work_item_relation.rb` (originally scoped for Phase 1; moved here since it has no caller until this slice). - `Types::MergeRequests::WorkItemLinkTypeEnum` and `Types::MergeRequests::WorkItemRelationType` (new). - `Resolvers::MergeRequests::WorkItemRelationsResolver` (new) — reads filtered rows, caps at 500. - New field `work_item_relations` on `Types::MergeRequestType`. - Deprecate existing `linked_work_items` field (`Use 'workItemRelations' instead.`, runtime unchanged during deprecation window). - Mutations under `app/graphql/mutations/merge_requests/work_item_relations/{create,destroy}.rb` + registration in `Types::MutationType`. - Request specs: new `work_item_relations_spec.rb`; extend `linked_work_items_spec.rb` to assert the deprecation annotation. ### To confirm before opening this MR - Actual milestone string for the deprecation annotation (issue currently says `<current>`). ### Notes - MR target: parent branch `601174-mr-work-item-relations`.
task