Skip to content

Feature/73081 backlog buckets in backlog and sprints view#22839

Merged
toy merged 15 commits intodevfrom
feature/73081-backlog-buckets-in-backlog-and-sprints-view-base
Apr 22, 2026
Merged

Feature/73081 backlog buckets in backlog and sprints view#22839
toy merged 15 commits intodevfrom
feature/73081-backlog-buckets-in-backlog-and-sprints-view-base

Conversation

@toy
Copy link
Copy Markdown
Contributor

@toy toy commented Apr 20, 2026

Ticket

https://community.openproject.org/wp/73081

What are you trying to accomplish?

backlog buckets

What approach did you choose and why?

model, contact and services part

Merge checklist

  • Added/updated tests
  • Added/updated documentation in Lookbook (patterns, previews, etc)
  • Tested major browsers (Chrome, Firefox, Edge, ...)

@toy toy force-pushed the feature/73081-backlog-buckets-in-backlog-and-sprints-view-base branch from bf5c5d6 to 703c795 Compare April 20, 2026 19:47
@toy toy requested a review from Copilot April 21, 2026 09:29
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds the backend groundwork for “backlog buckets” in the Backlogs module by introducing a new Agile::BacklogBucket model, persisting the association on work packages, and providing the supporting contracts/services/specs.

Changes:

  • Introduce Agile::BacklogBucket model with project + work package associations and project-scoped retrieval (.for_project incl. an “inbox” bucket).
  • Persist backlog bucket assignment on work packages (incl. journaling column) and enforce “either sprint OR backlog bucket” via model validation + DB check constraint.
  • Add BacklogBuckets contracts/services plus factories and specs.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
modules/backlogs/app/models/agile/backlog_bucket.rb New BacklogBucket model, associations, and query helpers (order_alphabetically, for_project).
modules/backlogs/app/contracts/backlog_buckets/base_contract.rb Base contract for backlog buckets with authorization + declared attributes.
modules/backlogs/app/contracts/backlog_buckets/create_contract.rb Create contract inheriting backlog bucket base contract.
modules/backlogs/app/contracts/backlog_buckets/update_contract.rb Update contract inheriting backlog bucket base contract.
modules/backlogs/app/services/backlog_buckets/create_service.rb BaseServices create wrapper for backlog buckets.
modules/backlogs/app/services/backlog_buckets/update_service.rb BaseServices update wrapper for backlog buckets.
modules/backlogs/app/services/backlog_buckets/set_attributes_service.rb BaseServices set-attributes wrapper for backlog buckets.
modules/backlogs/lib/open_project/backlogs/patches/work_package_patch.rb Adds backlog_bucket association + validations to WorkPackage.
modules/backlogs/lib/open_project/backlogs/patches/project_patch.rb Adds has_many :backlog_buckets association on Project.
modules/backlogs/db/migrate/20260415182824_create_backlog_buckets.rb Creates backlog_buckets table.
modules/backlogs/db/migrate/20260415211819_add_backlog_bucket_id_to_work_packages.rb Adds backlog_bucket_id to work packages with FK.
modules/backlogs/db/migrate/20260415211844_add_backlog_bucket_id_to_work_package_journals.rb Adds backlog_bucket_id to work package journals with FK.
modules/backlogs/db/migrate/20260416213200_add_backlog_bucket_xor_sprint_constraint_to_work_packages.rb DB-level check constraint preventing sprint + backlog bucket simultaneously.
modules/backlogs/config/locales/en.yml Adds attribute label and validation error messages for backlog bucket behavior.
modules/backlogs/spec/factories/sprint_factory.rb Ensures sprint factory always has a project.
modules/backlogs/spec/factories/backlog_bucket_factory.rb New factory for backlog buckets.
modules/backlogs/spec/models/work_package_spec.rb Adds validation + constraint coverage for sprint vs backlog bucket exclusivity and project consistency.
modules/backlogs/spec/models/agile/backlog_bucket_spec.rb New model spec for backlog bucket validations/associations/scopes/for_project.
modules/backlogs/spec/contracts/backlog_buckets/shared_contract_examples.rb Shared contract examples for backlog bucket contracts.
modules/backlogs/spec/contracts/backlog_buckets/create_contract_spec.rb Contract spec for creating backlog buckets.
modules/backlogs/spec/contracts/backlog_buckets/update_contract_spec.rb Contract spec for updating backlog buckets.
modules/backlogs/spec/services/backlog_buckets/create_service_spec.rb BaseServices create service shared-example coverage.
modules/backlogs/spec/services/backlog_buckets/update_service_spec.rb BaseServices update service shared-example coverage.
modules/backlogs/spec/services/backlog_buckets/set_attributes_service_spec.rb Set-attributes service spec coverage (currently with some copy/paste wording).

Comment thread modules/backlogs/lib/open_project/backlogs/patches/work_package_patch.rb Outdated
Comment thread modules/backlogs/spec/services/backlog_buckets/set_attributes_service_spec.rb Outdated
Comment thread modules/backlogs/spec/services/backlog_buckets/set_attributes_service_spec.rb Outdated
Comment thread modules/backlogs/spec/models/agile/backlog_bucket_spec.rb
Comment thread modules/backlogs/spec/factories/backlog_bucket_factory.rb
@toy toy force-pushed the feature/73081-backlog-buckets-in-backlog-and-sprints-view-base branch 3 times, most recently from 56286fc to 147cef4 Compare April 21, 2026 12:40
@opf opf deleted a comment from github-actions Bot Apr 21, 2026
Copy link
Copy Markdown
Contributor

@ulferts ulferts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obviously, I didn't check it out in the application but the structure looks already solid. Have a couple of remarks, though.

Comment thread modules/backlogs/app/models/agile/backlog_bucket.rb
)

buckets + [inbox]
end
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to be representation logic more than model logic. I'd place it in a helper or better, a component. But I haven't read through the whole PR yet.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is about fetching data, so feels like should not be in view

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess what irritates me the most is the addition of the inbox-logic in the method. The usage of .for_project seems to be out of scope for this PR which makes judging rather hard.

From what you can see, @toy, does it make sense to simply turn the inbox into an unpersisted backlog bucket for the sake of code cleanliness? The code here suggests this.

If that is the case we could turn the method into a proper scope (AR::Relation) which fetches all backlog buckets including the unpersisted "inbox".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


class AddBacklogBucketIdToWorkPackages < ActiveRecord::Migration[8.0]
def change
add_reference :work_packages, :backlog_bucket, foreign_key: { on_delete: :nullify }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about having the backlog_bucket in the journal? Excluded for time reasons?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread modules/backlogs/db/migrate/20260415182824_create_backlog_buckets.rb Outdated
Comment thread modules/backlogs/lib/open_project/backlogs/patches/work_package_patch.rb Outdated
Comment thread modules/backlogs/spec/contracts/backlog_buckets/update_contract_spec.rb Outdated
Comment thread modules/backlogs/spec/contracts/backlog_buckets/create_contract_spec.rb Outdated
Comment thread modules/backlogs/spec/models/agile/backlog_bucket_spec.rb
@toy toy force-pushed the feature/73081-backlog-buckets-in-backlog-and-sprints-view-base branch 3 times, most recently from 3886739 to d5d705b Compare April 21, 2026 15:54
@toy toy requested review from Copilot and ulferts April 21, 2026 19:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces “backlog buckets” to the Backlogs module by adding a new Agile::BacklogBucket model and wiring it into work packages (including contracts, services, and database constraints) so work packages can be assigned to either a sprint or a backlog bucket.

Changes:

  • Add Agile::BacklogBucket model with project/work package associations and helper scopes.
  • Add database support (backlog_buckets table, work_packages.backlog_bucket_id, XOR check constraint) plus contract validations to enforce “bucket XOR sprint”.
  • Add BacklogBuckets CRUD contracts/services and expand Backlogs patches/tests to cover backlog bucket authorization and behavior (including nullification on project move).

Reviewed changes

Copilot reviewed 34 out of 34 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
modules/backlogs/app/models/agile/backlog_bucket.rb New model for backlog buckets, including for_project and ordering.
modules/backlogs/app/services/backlog_buckets/create_service.rb Create service wrapper for backlog buckets.
modules/backlogs/app/services/backlog_buckets/update_service.rb Update service wrapper for backlog buckets.
modules/backlogs/app/services/backlog_buckets/delete_service.rb Delete service wrapper for backlog buckets.
modules/backlogs/app/services/backlog_buckets/set_attributes_service.rb SetAttributes service for backlog buckets.
modules/backlogs/app/contracts/backlog_buckets/base_contract.rb Base authorization + attribute validation for backlog buckets.
modules/backlogs/app/contracts/backlog_buckets/create_contract.rb Contract for creating buckets (adds project_id).
modules/backlogs/app/contracts/backlog_buckets/update_contract.rb Contract for updating buckets.
modules/backlogs/app/contracts/backlog_buckets/delete_contract.rb Contract for deleting buckets (permission-gated).
modules/backlogs/lib/open_project/backlogs/patches/work_package_patch.rb Adds belongs_to :backlog_bucket on work packages.
modules/backlogs/lib/open_project/backlogs/patches/project_patch.rb Adds has_many :backlog_buckets on projects.
modules/backlogs/lib/open_project/backlogs/patches/base_contract_patch.rb Adds backlog bucket attribute permissions + XOR/project validations on WPs.
modules/backlogs/lib/open_project/backlogs/patches/set_attributes_service_patch.rb Adds backlog bucket nullification when moving work packages across projects.
modules/backlogs/db/migrate/20260415182824_create_backlog_buckets.rb Creates backlog_buckets table.
modules/backlogs/db/migrate/20260415211819_add_backlog_bucket_id_to_work_packages.rb Adds backlog_bucket_id reference to work_packages.
modules/backlogs/db/migrate/20260416213200_add_backlog_bucket_xor_sprint_constraint_to_work_packages.rb Enforces DB-level XOR between backlog_bucket_id and sprint_id.
modules/backlogs/config/locales/en.yml Adds label + validation messages for backlog buckets.
modules/backlogs/spec/models/agile/backlog_bucket_spec.rb Model specs for validations/associations/scopes.
modules/backlogs/spec/factories/backlog_bucket_factory.rb Factory for backlog buckets.
modules/backlogs/spec/factories/sprint_factory.rb Ensures sprint factory always has a project.
modules/backlogs/spec/services/backlog_buckets/create_service_spec.rb BaseServices create service shared examples.
modules/backlogs/spec/services/backlog_buckets/update_service_spec.rb BaseServices update service shared examples.
modules/backlogs/spec/services/backlog_buckets/delete_service_spec.rb BaseServices delete service shared examples.
modules/backlogs/spec/services/backlog_buckets/set_attributes_service_spec.rb SetAttributes service spec for backlog buckets.
modules/backlogs/spec/services/work_packages/update_service_backlog_bucket_nullification_spec.rb Spec for backlog bucket nullification on project move.
modules/backlogs/spec/contracts/backlog_buckets/shared_contract_examples.rb Shared contract examples for backlog bucket contracts.
modules/backlogs/spec/contracts/backlog_buckets/create_contract_spec.rb Create contract spec.
modules/backlogs/spec/contracts/backlog_buckets/update_contract_spec.rb Update contract spec (project immutability).
modules/backlogs/spec/contracts/backlog_buckets/delete_contract_spec.rb Delete contract spec.
modules/backlogs/spec/contracts/work_packages/shared_contract_examples.rb Adds backlog bucket permission + XOR/project validation coverage.
modules/backlogs/spec/contracts/work_packages/update_contract_spec.rb Expands writable attribute expectations to include backlog buckets.
modules/backlogs/spec/contracts/sprints/shared_contract_examples.rb Refactors admin-without-permission case into unauthorized context.
modules/backlogs/spec/contracts/sprints/create_contract_spec.rb Removes redundant shared context require.
modules/backlogs/spec/contracts/sprints/update_contract_spec.rb Removes redundant shared context require.

Copy link
Copy Markdown
Contributor

@ulferts ulferts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy with what I see. The comments below are small so feel free to address/ignore as you see fit and merge at will.

def change
create_table :backlog_buckets do |t|
t.string :name, null: false
t.references :project, foreign_key: { on_delete: :cascade }, null: false
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think - does it make sense to have a spec to validate that backlog buckets are removed if a project is removed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the check for the presence of the relation, with that explicitly checking dependant deletion feels unnecessary

end

it_behaves_like "contract is invalid", backlog_bucket_id: :error_readonly
end
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading this uncovered a problem we have with sprints and backlogs. If the user only has "Manage sprint items" but lacks "Edit work packages", moving is not possible. I opened a bug for this

Comment thread modules/backlogs/app/models/agile/backlog_bucket.rb
)

buckets + [inbox]
end
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess what irritates me the most is the addition of the inbox-logic in the method. The usage of .for_project seems to be out of scope for this PR which makes judging rather hard.

From what you can see, @toy, does it make sense to simply turn the inbox into an unpersisted backlog bucket for the sake of code cleanliness? The code here suggests this.

If that is the case we could turn the method into a proper scope (AR::Relation) which fetches all backlog buckets including the unpersisted "inbox".

@toy toy force-pushed the feature/73081-backlog-buckets-in-backlog-and-sprints-view-base branch from 56bc67c to 6b50ccd Compare April 22, 2026 13:14
@toy toy force-pushed the feature/73081-backlog-buckets-in-backlog-and-sprints-view-base branch from 6b50ccd to 94303e3 Compare April 22, 2026 13:31
@toy toy requested a review from Copilot April 22, 2026 13:32
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds “backlog buckets” to the Backlogs module by introducing a new Agile::BacklogBucket model, wiring it into WorkPackages/contracts/services, and adding DB constraints/migrations plus supporting specs.

Changes:

  • Introduce Agile::BacklogBucket (model + factory) and project/work package associations.
  • Add CRUD contracts/services/specs for backlog buckets and extend work package contracts/validations (XOR with sprint, project-scoped).
  • Add DB migrations for backlog buckets table, work_packages.backlog_bucket_id, and a sprint XOR check constraint; update locales and specs.

Reviewed changes

Copilot reviewed 37 out of 37 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
modules/backlogs/spec/services/work_packages/update_service_backlog_bucket_nullification_spec.rb Verifies backlog bucket is nulled when moving a work package across projects.
modules/backlogs/spec/services/sprints/set_attributes_service_spec.rb Minor expectation ordering tweak in sprint SetAttributesService spec.
modules/backlogs/spec/services/backlog_buckets/update_service_spec.rb Adds shared update-service behavior coverage for backlog buckets.
modules/backlogs/spec/services/backlog_buckets/set_attributes_service_spec.rb Adds SetAttributesService spec coverage for backlog buckets.
modules/backlogs/spec/services/backlog_buckets/delete_service_spec.rb Adds shared delete-service behavior coverage for backlog buckets.
modules/backlogs/spec/services/backlog_buckets/create_service_spec.rb Adds shared create-service behavior coverage for backlog buckets.
modules/backlogs/spec/models/work_package_spec.rb Adds association expectations for backlog_bucket (and sprint).
modules/backlogs/spec/models/project_spec.rb Adds association expectation for project backlog_buckets.
modules/backlogs/spec/models/agile/backlog_bucket_spec.rb Adds model validation/association/scope behavior specs for backlog buckets.
modules/backlogs/spec/factories/sprint_factory.rb Ensures sprint factory always has an associated project.
modules/backlogs/spec/factories/backlog_bucket_factory.rb Adds factory for creating backlog buckets.
modules/backlogs/spec/contracts/work_packages/update_contract_spec.rb Extends writable attributes expectations to include backlog_bucket.
modules/backlogs/spec/contracts/work_packages/shared_contract_examples.rb Adds permission + XOR + project-scoping contract examples for backlog buckets.
modules/backlogs/spec/contracts/sprints/update_contract_spec.rb Removes redundant shared context require.
modules/backlogs/spec/contracts/sprints/shared_contract_examples.rb Adjusts admin-without-permissions validation placement.
modules/backlogs/spec/contracts/sprints/create_contract_spec.rb Removes redundant shared context require.
modules/backlogs/spec/contracts/backlog_buckets/update_contract_spec.rb Adds update-contract coverage, including project immutability checks.
modules/backlogs/spec/contracts/backlog_buckets/shared_contract_examples.rb Shared contract examples for backlog bucket authorization/validation.
modules/backlogs/spec/contracts/backlog_buckets/delete_contract_spec.rb Adds delete-contract authorization coverage for backlog buckets.
modules/backlogs/spec/contracts/backlog_buckets/create_contract_spec.rb Adds create-contract coverage for backlog buckets.
modules/backlogs/lib/open_project/backlogs/patches/work_package_patch.rb Adds belongs_to :backlog_bucket on WorkPackage.
modules/backlogs/lib/open_project/backlogs/patches/set_attributes_service_patch.rb Adds system nullification of backlog bucket on project move; refactors project-move detection helper.
modules/backlogs/lib/open_project/backlogs/patches/project_patch.rb Adds has_many :backlog_buckets to Project.
modules/backlogs/lib/open_project/backlogs/patches/base_contract_patch.rb Adds backlog bucket attribute permissions and XOR/project validations in work package contract patch.
modules/backlogs/db/migrate/20260416213200_add_backlog_bucket_xor_sprint_constraint_to_work_packages.rb Adds DB check constraint enforcing bucket XOR sprint.
modules/backlogs/db/migrate/20260415211819_add_backlog_bucket_id_to_work_packages.rb Adds backlog_bucket_id reference on work packages with FK nullify.
modules/backlogs/db/migrate/20260415182824_create_backlog_buckets.rb Creates backlog_buckets table (project-scoped).
modules/backlogs/config/locales/en.yml Adds labels and validation messages for backlog buckets and XOR error.
modules/backlogs/app/services/backlog_buckets/update_service.rb Adds update service for backlog buckets.
modules/backlogs/app/services/backlog_buckets/set_attributes_service.rb Adds SetAttributesService for backlog buckets.
modules/backlogs/app/services/backlog_buckets/delete_service.rb Adds delete service for backlog buckets.
modules/backlogs/app/services/backlog_buckets/create_service.rb Adds create service for backlog buckets.
modules/backlogs/app/models/agile/backlog_bucket.rb Introduces BacklogBucket model + scopes + for_project helper building an inbox bucket.
modules/backlogs/app/contracts/backlog_buckets/update_contract.rb Adds update contract for backlog buckets.
modules/backlogs/app/contracts/backlog_buckets/delete_contract.rb Adds delete contract with create_sprints delete permission.
modules/backlogs/app/contracts/backlog_buckets/create_contract.rb Adds create contract exposing project_id attribute.
modules/backlogs/app/contracts/backlog_buckets/base_contract.rb Adds base contract enforcing create_sprints authorization and name attribute.

Comment thread modules/backlogs/app/models/agile/backlog_bucket.rb
@toy toy force-pushed the feature/73081-backlog-buckets-in-backlog-and-sprints-view-base branch from 94303e3 to e6d629f Compare April 22, 2026 13:57
@toy toy merged commit ac392d0 into dev Apr 22, 2026
17 checks passed
@toy toy deleted the feature/73081-backlog-buckets-in-backlog-and-sprints-view-base branch April 22, 2026 14:17
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 22, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants