[#73798] Remove scrum_projects feature flag from Backlogs#22740
[#73798] Remove scrum_projects feature flag from Backlogs#22740
scrum_projects feature flag from Backlogs#22740Conversation
There was a problem hiding this comment.
Pull request overview
Removes the scrum_projects feature decision from the Backlogs module and makes the sprint-based Backlogs (Agile::Sprint) behavior the default across UI routes, controllers, helpers, and API endpoints, with corresponding spec updates.
Changes:
- Removed
scrum_projectsfeature decision registration and deleted feature-flag-dependent branches across Backlogs routes/controllers/API. - Made sprint-based Backlogs behavior the default (Agile::Sprint), including routing and representer/schema exposure.
- Updated Backlogs and PDF export specs to align with the permanent sprint model and adjusted position/reordering behavior.
Reviewed changes
Copilot reviewed 60 out of 60 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb | Updates PDF export expectations (adds Story Points/Position/Sprint handling). |
| modules/backlogs/spec/services/work_packages/update_service_sprint_preservation_spec.rb | Removes feature-flag gating from sprint-preservation service specs. |
| modules/backlogs/spec/services/sprints/finish_service_spec.rb | Removes feature-flag gating from sprint finish service specs. |
| modules/backlogs/spec/routing/rb_stories_routing_spec.rb | Makes sprint story move route always available (no flag split). |
| modules/backlogs/spec/routing/rb_sprints_routing_spec.rb | Makes sprint dialog/start/finish routes always available (no flag split). |
| modules/backlogs/spec/routing/projects/settings/backlog_sharings_routing_spec.rb | Makes backlog sharing settings routes always available (no flag split). |
| modules/backlogs/spec/routing/inbox_routing_spec.rb | Removes feature-flag gating from inbox routing spec. |
| modules/backlogs/spec/requests/rb_master_backlogs_spec.rb | Aligns master backlogs request behavior with permanent backlog action and turbo-frame src params. |
| modules/backlogs/spec/requests/api/v3/sprints/show_resource_spec.rb | Removes API v3 sprints show feature-flag guard coverage. |
| modules/backlogs/spec/requests/api/v3/sprints/project_index_resource_spec.rb | Removes API v3 project sprints index feature-flag guard coverage. |
| modules/backlogs/spec/requests/api/v3/sprints/index_resource_spec.rb | Removes API v3 sprints index feature-flag guard coverage. |
| modules/backlogs/spec/models/work_packages/position_spec.rb | Removes feature-flag gating from position behavior specs. |
| modules/backlogs/spec/models/queries/work_packages/filter/sprint_filter_spec.rb | Updates sprint filter availability specs to no longer depend on flag state. |
| modules/backlogs/spec/lib/open_project/backlogs/permissions_spec.rb | Makes sprint-related permissions visible unconditionally (no flag split). |
| modules/backlogs/spec/lib/api/v3/work_packages/work_package_representer_rendering_spec.rb | Removes flag-dependent representer behavior branches for sprint/storyPoints/position. |
| modules/backlogs/spec/lib/api/v3/work_packages/schema/work_package_schema_representer_spec.rb | Removes flag-dependent schema branches for storyPoints/position/sprint. |
| modules/backlogs/spec/features/work_packages/sprints_on_wp_view_spec.rb | Removes feature-flag “off” scenario and makes sprint attribute always expected (subject to permissions). |
| modules/backlogs/spec/features/work_packages/filter_spec.rb | Removes sprint filtering feature-flag gating. |
| modules/backlogs/spec/features/work_packages/drag_in_sprint_spec.rb | Removes feature-flag gating from sprint drag/drop feature spec. |
| modules/backlogs/spec/features/work_packages/drag_in_inbox_spec.rb | Removes feature-flag gating from inbox drag/drop feature spec. |
| modules/backlogs/spec/features/work_packages/create_work_package_spec.rb | Removes feature-flag gating from create-in-sprint feature spec. |
| modules/backlogs/spec/features/projects/settings/backlog_sharing_settings_spec.rb | Removes feature-flag “tab hidden” scenario; sharing tab now depends on permission only. |
| modules/backlogs/spec/features/inbox_column_spec.rb | Removes feature-flag gating from inbox column feature spec. |
| modules/backlogs/spec/features/burndown/show_spec.rb | Removes feature-flag gating from burndown chart feature spec. |
| modules/backlogs/spec/features/backlogs/start_finish_spec.rb | Removes feature-flag gating from start/finish sprint feature spec. |
| modules/backlogs/spec/features/backlogs/sprint_list_spec.rb | Removes feature-flag gating from sprint list feature spec. |
| modules/backlogs/spec/features/backlogs/edit_spec.rb | Renames context and removes feature-flag gating in edit sprint planning spec. |
| modules/backlogs/spec/features/backlogs/create_spec.rb | Renames context and removes feature-flag “inactive” scenario in create spec. |
| modules/backlogs/spec/features/admin/backlogs_settings_spec.rb | Removes legacy admin configuration scenarios; asserts blankslate instead. |
| modules/backlogs/spec/controllers/rb_taskboards_controller_spec.rb | Removes flag split and consolidates taskboard controller expectations. |
| modules/backlogs/spec/controllers/rb_stories_controller_spec.rb | Removes flag split and keeps both Agile::Sprint and version Sprint behaviors covered. |
| modules/backlogs/spec/controllers/rb_sprints_controller_spec.rb | Removes flag gating for sprint dialogs/create/update/start/finish and adds refresh_form edit-mode case. |
| modules/backlogs/spec/controllers/projects/settings/backlog_sharings_controller_spec.rb | Removes feature-flag gating from backlog sharings controller spec. |
| modules/backlogs/spec/controllers/inbox_controller_spec.rb | Removes feature-flag gating from inbox controller spec. |
| modules/backlogs/lib/open_project/backlogs/work_package_filter.rb | Disables legacy backlogs-type filter availability by hard-coding configuration false. |
| modules/backlogs/lib/open_project/backlogs/patches/work_package_patch.rb | Removes legacy story/task/backlogs-type classification by hard-coding methods to empty/false; keeps sprint association/list behavior. |
| modules/backlogs/lib/open_project/backlogs/patches/versions/row_component_patch.rb | Removes backlogs-specific edit link injection; defers to upstream button links. |
| modules/backlogs/lib/open_project/backlogs/patches/type_patch.rb | Hard-codes Type#story?/task? to false (legacy classification removed). |
| modules/backlogs/lib/open_project/backlogs/patches/set_attributes_service_patch.rb | Always nullifies sprint when moved to a project without sprint visibility; removes legacy version inheritance logic. |
| modules/backlogs/lib/open_project/backlogs/patches/api/work_package_schema_representer.rb | Removes scrum feature decision from sprint schema visibility conditions. |
| modules/backlogs/lib/open_project/backlogs/patches/api/work_package_representer.rb | Removes scrum feature decision from sprint link/embed visibility conditions. |
| modules/backlogs/lib/open_project/backlogs/list.rb | Makes acts_as_list scoping consistently project+sprint and simplifies scope-change handling; uses rebuild service in nil-position edge case. |
| modules/backlogs/lib/open_project/backlogs/engine.rb | Makes sprint-related permissions and project menu entries always visible when module enabled; simplifies attribute constraints. |
| modules/backlogs/lib/api/v3/sprints/sprints_by_project_api.rb | Removes feature-flag guard from project sprints API. |
| modules/backlogs/lib/api/v3/sprints/sprints_api.rb | Removes feature-flag guard from global sprints API. |
| modules/backlogs/config/routes.rb | Removes feature-flag route constraints so Agile::Sprint routes are always mounted. |
| modules/backlogs/app/views/backlogs_settings/show.html.erb | Always renders Backlogs administration blankslate (legacy config form removed). |
| modules/backlogs/app/models/queries/work_packages/filter/sprint_filter.rb | Makes sprint filter availability depend only on permission (no feature decision). |
| modules/backlogs/app/helpers/rb_common_helper.rb | Removes scrum feature decision checks; disables legacy type lists and standardizes sprint board label. |
| modules/backlogs/app/forms/my/backlogs_form.rb | Removes legacy task color preference field gated by feature decision. |
| modules/backlogs/app/controllers/rb_taskboards_controller.rb | Switches “new vs legacy” behavior based on sprint class (Agile::Sprint vs Sprint). |
| modules/backlogs/app/controllers/rb_stories_controller.rb | Switches story loading behavior based on sprint class (Agile::Sprint vs Sprint). |
| modules/backlogs/app/controllers/rb_master_backlogs_controller.rb | Makes backlog view the default for index/details and always loads Agile::Sprint-based data. |
| modules/backlogs/app/controllers/rb_burndown_charts_controller.rb | Switches burndown creation based on sprint class (Agile::Sprint vs Sprint). |
| modules/backlogs/app/controllers/rb_application_controller.rb | Removes legacy “plugin configured” check and uses Agile::Sprint-first sprint loading with fallback to legacy Sprint. |
| modules/backlogs/app/controllers/projects/settings/backlogs_controller.rb | Always rebuilds positions via WorkPackages::RebuildPositionsService. |
| modules/backlogs/app/controllers/inbox_controller.rb | Removes feature-flag authorization gate for inbox actions. |
| modules/backlogs/app/components/projects/settings/backlogs/settings_header_component.html.erb | Shows sharing tab based on permission only (no feature decision). |
| config/initializers/feature_decisions.rb | Removes scrum_projects feature decision registration. |
| app/forms/versions/form.rb | Disables legacy version backlog settings UI by hard-coding backlogs_enabled? to false. |
Comments suppressed due to low confidence (1)
modules/backlogs/lib/open_project/backlogs/work_package_filter.rb:88
backlogs_configured?is now hard-coded tofalse, which makes this filter permanently unavailable (available?will always be false when backlogs is enabled). Since the filter still contains SQL logic for story/task/impediment, this looks like dead/stranded code. Consider removing the filter (and any API/schema exposure) entirely if it’s no longer part of the sprint-based Backlogs model, or update it to reflect the new model so it remains usable.
def backlogs_configured?
false
end
def backlogs_enabled?
project.nil? || project.module_enabled?(:backlogs)
end
8f370d4 to
f39b8b9
Compare
f39b8b9 to
d4064f4
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 137 out of 137 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
modules/backlogs/app/services/work_packages/rebuild_positions_service.rb:55
- When
@projectis provided, the UPDATE is filtered, but themappingsubquery still computesROW_NUMBER()over the entirework_packagestable. On large instances this can be unnecessarily expensive. Consider applying the same project condition inside the subquery (e.g., in theFROM work_packagespart) so the window function only scans rows for the target project when@projectis set.
|
@myabc copied from our chat:
The blankslate should be kept. The idea was to keep the route alive even though all the options were removed in 17.3, because new settings will be added soon.
I assume you are referring to the removal of the
It should definitely be removed ASAP. We don't rely on it any more. Whether the removal is part of this PR or the next, I don't care.
The change I could spot was adding the |
EinLama
left a comment
There was a problem hiding this comment.
This looks good to me, great job! I could not provoke new bugs or issues on my machine. All code removals and small adjustments seem sane 👍 From my perspective, this is good to go! It's great that we can get rid of so much complexity at once.
Due to the sheer size of this PR, we should wait for additional feedback. I tried to be thorough, but I might have missed something.
| #++ | ||
|
|
||
| module RbCommonHelper | ||
| def format_date_range(dates) |
There was a problem hiding this comment.
It might make sense to move this to redmine/i18n.rb. Not necessarily in this PR.
| sprint1_wp3.subject => 2, | ||
| sprint1_wp4.subject => 3, | ||
| sprint1_wp4.subject => 2, | ||
| sprint1_wp3.subject => 3, |
There was a problem hiding this comment.
The intend of the setup was for sprint1_wp3 and sprint1_wp4 to have the same position so that running the service can fix that conflict.
I propose adding something like
sprint1_wp3.update_column(:position, 2)
To the shared_let of sprint1_wp4. Might not be super clean but will recreate the intended setup.
With that in, the other changes in this file can be reverted.
I also briefly checked and I don't think that adding the id to the SQL of the RebuildPositionsService is really required. It will not hurt but I don't think it is necessary. Or am I missing something?
Add `clear_filter_value` to clear an ng-select filter's current selection without removing the filter row, allowing a new value to be set in place. Refactor `insert_autocomplete_item` to accept a filter `id` string rather than a pre-captured element, so the ng-select node is re-queried on each call. This avoids stale element references after `clear_filter_value` causes the DOM to re-render.
Make Backlogs use the sprint-based behavior unconditionally and remove the old feature-flagged branches from controllers, routes, representers, and supporting helpers. Update the affected Backlogs specs and PDF export expectations to match the permanent sprint model and keep list reordering stable when moving work packages between backlog and sprint scopes. https://community.openproject.org/wp/73798
ed8f0d1 to
b24d229
Compare
Restore the minimal admin settings blankslate so the admin menu route remains valid after the sprint-based cleanup. Remove the remaining settings-driven story/task classification code, dead models and services, and the obsolete filter and spec setup that depended on it.
Strips all scopes and methods from `Sprint < Version`, including wiki page helpers, leaving a bare class shell. `Agile::Sprint` is the active model going forward. Removes `Story.types` (settings-driven type list), `Story#tasks`, and `Story#set_points`. Removes `VersionSetting` display predicates and setters (constants retained), and dead `Backlog` instance methods (`updated_at`, `owner_backlog?`, `sprint_backlog?`). Slims `VersionPatch` to just the `has_many :version_settings` association. Simplifies `Burndown#make_date_series` to the `Agile::Sprint` path only. Removes the dead locale key and stale engine permission stubs.
Restore `#backlog` as the canonical Backlogs route by redirecting all `#index` requests to it.
Deletes the jQuery Taskboard Sass and JS chain. Keeps the Backlogs task board route and links redirecting into Boards unchanged.
Update the Backlogs-related type form expectations so reset and empty-state coverage matches the current Position-in-Other behavior.
Stabilize shared ng-select interactions for Cuprite and reuse open dropdowns safely in modal-based flows. Also keep filter clearing safe when no value is selected and refresh the My Page drop target after drag-induced DOM updates.
b24d229 to
712fdbc
Compare
dombesz
left a comment
There was a problem hiding this comment.
Tremendous work, well done Alex! 👏
I have left a few comments, but that is expected for a PR this size.
| cached_representer key_parts: %i[project type], | ||
| dependencies: -> { | ||
| all_permissions_granted_to_user_under_project + [Setting.work_package_done_ratio, | ||
| Setting.plugin_openproject_backlogs] |
There was a problem hiding this comment.
I wonder if it's ok to remove this?
There was a problem hiding this comment.
I left this removed. The schema cache no longer depends on Setting.plugin_openproject_backlogs; schema visibility is now driven by project permissions and the type attribute constraints. Keeping the plugin setting in the cache dependencies would only add invalidations without changing the result.
| form do |f| | ||
| f.fieldset_group(title: helpers.t("backlogs.user_preference.header_backlogs"), mt: 4) do |fg| | ||
| unless OpenProject::FeatureDecisions.scrum_projects_active? | ||
| fg.text_field name: :backlogs_task_color, |
There was a problem hiding this comment.
Can we also remove this?
openproject/modules/backlogs/lib/open_project/backlogs/engine.rb
Lines 182 to 185 in 8590c07
There was a problem hiding this comment.
I’m keeping that API mount for now. project_sprints is still used by the sprint filter dependency representer and the Backlogs schema/API specs, so removing the endpoint in this PR would strand live callers.
@ulferts thoughts?
Drop a few dead Backlogs remnants that are no longer needed after the feature-flag removal. Reuse WorkPackage.order_by_position for inbox ordering, remove the dead Status patch, simplify burndown collection to Agile::Sprint only, and remove the unused blocks_ids locale label.
Drop the unused `show_actions` and `show_drag_handle` parameters from Backlogs::StoryComponent now that all call sites use the default behavior.
Ticket
https://community.openproject.org/wp/73798
https://community.openproject.org/wp/71269
What are you trying to accomplish?
Remove the
scrum_projectsfeature flag from Backlogs and make the sprint-based implementation permanent.What approach did you choose and why?
The flag was already permanently active ("forced"), so the old branches were dead code. This PR:
scrum_projectsfeature registration and the remaining flag checksImpedimentmodel, services, controller (rb_impediments_controller), views, and all associated specsTaskandStorymodels to bare STI stubs (all dead methods removed)rb_wikis_controllerand its routing specstype_patch.rb,versions/row_component_patch.rb,work_package_filter.rbwork_package_patch.rband slimsversion_patch.rbto just thehas_many :version_settingsassociationSprint < Version(now a bare shell;Agile::Sprintis the active model)rb_taskboardsredirect endpoint so sprint links continue to resolve to the linked boardImportant
This Pull Request also updates shared feature-spec helpers because removing
scrum_projectsmakes the old Backlogs-enabled inline-edit path always active in feature specs. That exposes pre-existing Cuprite interaction issues outside the Backlogs specs themselves: ng-select fields may already have an open dropdown when the helper tries to click again, and multi-value chip removal can be overlapped by the option panel. The helper now reuses an already-open dropdown before clicking, targets the actual ng-select input, and keeps the Cuprite-specific fallback limited to the chip-removal path that still needs it. It also refreshes My Page drag targets after CDK drag updates the DOM.Remaining cleanup (follow-up PRs)
The following items were identified during review but are out of scope for this PR:
TaskandStorySTI stub models (depends on confirming no DB-level STI rows remain)backlogs_settings_formbacklogs/patches/status_patch.rbbacklogs/mixins/prevent_issue_sti.rbonce Task/Story stubs are goneBacklog,Story, andTasktype referencesVersions::BaseContractPatch,VersionSetting, and the legacySprint < VersionpathBacklog.inbox_forto aWorkPackagescope and delete theBacklogclassformat_date_rangeintoredmine/i18n.rbrebuild_positionscontroller action once positions are stableScreenshots
No visual changes
Merge checklist