Remove foreign key constraints from work_item_type_id columns

What does this MR do and why?

To allow storing both system-defined work item type IDs (1-9) and custom work item type IDs (1000+) in the same work_item_type_id column, we need to remove foreign key constraints from work_item_type_id columns.

Changes

Database changes

This MR removes foreign key constraints from the following tables using post-deployment migrations:

  • issues
  • work_item_type_custom_fields
  • work_item_custom_status_mappings
  • work_item_type_custom_lifecycles
  • work_item_type_user_preferences

Application-level validation

To maintain data integrity after removing foreign key constraints, this MR adds centralized application-level validation:

  • Creates WorkItems::TypesFramework::Validation concern that provides consistent validation across all affected models.
  • Uses WorkItems::TypesFramework::Provider pattern for centralized work item type validation logic.
  • Ensure validation runs regardless of work_item_system_defined_type feature flag state, preventing invalid work_item_type_id values during the transition period.

This ensures that invalid work item type references are caught at the application level, replacing the database-level foreign key constraint protection while providing stronger data integrity guarantees.

Safety measures during transition

  • Adds prevent_deletion_during_transition callback to WorkItems::Type model that prevents deletion of work item types when the work_item_system_defined_type feature flag is disabled.
  • This serves as a safety net against accidental deletions via Rails console during the transition period, preventing orphaned records that would reference non-existent work item types.

Considerations

  1. This MR can only be merged after the work_item_system_defined_type feature flag has been enabled and tested. Keeping it in draft for now.
  2. Once the FF flag is enabled, we will be removing the legacy work item types stored in the DB.
  3. The foreign key also needs to be dropped from work_item_widget_definitions. Since the work_item_widget_definitions table will be deleted once the work_item_system_defined_type feature flag is enabled (likely within the next couple of weeks), we decided it isn't necessary to remove the constraint now, as it will be removed together with the table itself.
  4. Deletion of custom work item types that reference existing records will be handled by the custom FK validation changes from !223997 (merged).

References

How to set up and validate locally

  1. Enable the work_item_system_defined_type FF.
  2. issues
    1. Navigate to a project and create a new work item, for example an issue or a task. Creating work items should behave exactly the same as before.
    2. Via the Rails console, verify the work item type ID of the newly created work item. The work item type should reference a system-defined one.
      1. WorkItem.last.work_item_type
      2. Issue.last.work_item_type
  3. work_item_type_custom_lifecycles
    1. Navigate to the work item settings at the root group, for example: http://127.0.0.1:3000/groups/public-group-1/-/settings/work_items.
    2. Create a new work item status lifecycle.
    3. Apply the lifecycle to a work item type, such as 'Issue' or 'Task'.
    4. Via the Rails console, verify the work item type associated with the lifecycle. It should reference a system-defined one.
      1. WorkItems::Statuses::Custom::Lifecycle.last.work_item_types.last
      2. WorkItems::TypeCustomLifecycle.last.work_item_type
  4. work_item_custom_status_mappings
    1. Remove one of the statuses within the lifecycle, for example 'In progress', and provide a status mapping.
    2. Via the Rails console, verify the work item type. It should reference a system-defined one.
      1. WorkItems::Statuses::Custom::Mapping.last.work_item_type
  5. work_item_type_custom_fields
    1. Navigate to the work item settings at the root group, for example: http://127.0.0.1:3000/groups/public-group-1/-/settings/work_items.
    2. Create a new custom field.
    3. Via the Rails console, verify the work item type. It should reference a system-defined one.
      1. WorkItems::TypeCustomField.last.work_item_type

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 Agnes Slota

Merge request reports

Loading