Skip to content

Realtime status mapping resolution

What does this MR do and why?

This code change adds real time status mapping resolution. Status mappings were introduced with Adds work_item_custom_status_mapping table and ... (!203127 - merged).

  1. Mapping logic: Adds logic to resolve the current status based on mapping
  2. Time-based mappings: Mapping can be restricted by valid_from and valid_until and multiple mappings can exist for a given old_status_id. The system resolves to the valid status when the current_status record was last updated.
  3. Takes converted statuses into account: Converted statuses are those custom statuses that were created from system-defined statuses. Some current status records might still refer to the system-defined status. This change takes the conversion mapping into account and applies existing status mappings after the converted mapping has been resolved.
  4. Performance optimization: The mapping data is cached to avoid repeatedly querying the database for the same information.
  5. Board List Exception: Board lists are excluded from this mapping system since they don't have the necessary context (work item type and timestamps) to determine which mapping to use.

🎏 I chose not to hide the resolution behind the work_item_status_mvc2 to reduce the available code paths for this already complex feature. Instead I'd guard creating and updating mappings with the feature flag.

References

  1. Resolve status based on mapping (#566527 - closed)
  2. #558275 (closed)

Screenshots or screen recordings

No screenshots

How to set up and validate locally

  1. Use a root level namespace with custom statuses.

    1. If you don't have one set up, go to the settings page, select "Issues" and "Edit statuses" in the statuses section and change the name of a status. Now you have custom statuses
  2. Add a two new statuses in an "open" category.

  3. Create an issue and directly assign the first created status.

  4. Go to the console and select the lifecycle and the two statuses:

    lifecycle = ::WorkItems::Statuses::Custom::Lifecycle.last
    old_status, new_status = WorkItems::Statuses::Custom::Status.last(2)
    # Normally a mapping would be put into place when we delete the status from the lifecycle
    # For easy test setup, keeping the status in the lifecycle also works.
  5. Add a mapping from the set status to the newly added status

    lifecycle.work_item_types.each do |wit|
      WorkItems::Statuses::Custom::Mapping.create!(
        namespace_id: lifecycle.namespace_id, old_status_id: old_status.id, new_status_id: new_status.id, work_item_type: wit
      )
    end
    # If you want to, play with the valid_from and valid_until dates. If non is set it's always valid.
  6. Reload the work item/work item list and see the displayed status is now the newly added status

Added DB query

Fetching the mappings for a given namespace (cached using optimized request store with O(1) lookup):

SELECT "work_item_custom_status_mappings".* FROM "work_item_custom_status_mappings"
WHERE "work_item_custom_status_mappings"."namespace_id" = 22 

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 Marc Saleiko

Merge request reports

Loading