Feature/73081 backlog buckets in backlog and sprints view#22839
Conversation
bf5c5d6 to
703c795
Compare
There was a problem hiding this comment.
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::BacklogBucketmodel with project + work package associations and project-scoped retrieval (.for_projectincl. 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). |
56286fc to
147cef4
Compare
ulferts
left a comment
There was a problem hiding this comment.
Obviously, I didn't check it out in the application but the structure looks already solid. Have a couple of remarks, though.
| ) | ||
|
|
||
| buckets + [inbox] | ||
| end |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
It is about fetching data, so feels like should not be in view
There was a problem hiding this comment.
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".
There was a problem hiding this comment.
|
|
||
| class AddBacklogBucketIdToWorkPackages < ActiveRecord::Migration[8.0] | ||
| def change | ||
| add_reference :work_packages, :backlog_bucket, foreign_key: { on_delete: :nullify } |
There was a problem hiding this comment.
What about having the backlog_bucket in the journal? Excluded for time reasons?
There was a problem hiding this comment.
Yup, I did first step, but than moved it to https://github.com/opf/openproject/tree/feature/73081-backlog-buckets-in-backlog-and-sprints-view-journaling
3886739 to
d5d705b
Compare
There was a problem hiding this comment.
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::BacklogBucketmodel with project/work package associations and helper scopes. - Add database support (
backlog_bucketstable,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. |
ulferts
left a comment
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
What do you think - does it make sense to have a spec to validate that backlog buckets are removed if a project is removed?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
| ) | ||
|
|
||
| buckets + [inbox] | ||
| end |
There was a problem hiding this comment.
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".
56bc67c to
6b50ccd
Compare
6b50ccd to
94303e3
Compare
There was a problem hiding this comment.
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. |
94303e3 to
e6d629f
Compare
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