Bug/COMMS-890: Claim description image uploads on new work packages when the attachments list is hidden - #25118
Conversation
A new work package created with `_links.attachments: []` but a description embedding an uploaded image left that attachment uncontainered, so the cleanup job deleted it. Uncontainered attachments of the current user that the description references are now claimed alongside any explicit list.
… list The store-to-resource sync lived only in op-attachments, so with the attachments list hidden a CKEditor upload on a new work package never reached the create payload.
Both work package descriptions and comments now resolve claimable attachments through Attachments::ClaimableIdsFromText, which also picks up markdown image references the CSS selector missed.
Feature spec for the ticket flow: attachments list deactivated, image uploaded through CKEditor on a new work package, attachment claimed on save.
|
Warning Flaky specs
🤖 Ask Copilot to investigateCopy the prompt below into a new comment on this PR to delegate the investigation to GitHub Copilot. It will look into the flakiness and open a separate pull request with you as reviewer. |
There was a problem hiding this comment.
🟢 Approval recommended
The changes are targeted, enforce correct claiming constraints (author + uncontainered/own-container), and are well-covered by service, request, and feature specs including the reported regression path.
Pull request overview
Fixes a regression where image uploads performed in the work package description on new work packages were not claimed (and later cleaned up) when the attachments list UI was not rendered. The change makes claiming robust across UI variants and also covers API clients that send an empty attachments list.
Changes:
- Frontend: after uploading attachments for a new HAL resource, mirror the uploaded attachment links back into the resource payload even if the attachments list component is not present.
- Backend: on create, additionally claim any uncontainered attachments referenced from the description text (while still enforcing “only author’s uncontainered attachments”).
- Tests: add unit/request/feature specs covering description-referenced attachment claiming and the “attachments list hidden” regression.
File summaries
| File | Description |
|---|---|
| spec/services/work_packages/set_attributes_service_description_attachment_claims_spec.rb | Covers claiming behavior in WorkPackages::SetAttributesService for new vs persisted work packages and explicit vs description-referenced attachments. |
| spec/services/attachments/claimable_ids_from_text_spec.rb | Unit tests for extracting and filtering claimable attachment IDs from text with/without container context. |
| spec/requests/api/v3/work_packages/create_resource_spec.rb | Regression coverage for API create when _links.attachments is empty but description references an upload. |
| spec/features/work_packages/attachments/attachment_upload_spec.rb | End-to-end regression coverage for CKEditor upload when attachments list is hidden. |
| frontend/src/app/core/state/attachments/attachments.service.ts | Mirrors uploads into the “new resource” attachments links after upload completes. |
| frontend/src/app/core/state/attachments/attachments.service.spec.ts | Verifies attachFiles mirrors new-resource attachments and leaves persisted-resource links unchanged. |
| app/services/work_packages/set_attributes_service.rb | Claims attachments referenced in description during create by unioning with explicit attachment_ids. |
| app/services/work_packages/activities_tab/comment_attachments_claims/set_attributes_service.rb | Reuses the shared text-scanning logic for comment attachment claiming. |
| app/services/attachments/claimable_ids_from_text.rb | Adds shared implementation for extracting referenced attachment IDs and filtering to claimable ones. |
Review details
- Files reviewed: 9/9 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
https://community.openproject.org/wp/COMMS-890
With "Show attachments in the work packages files tab" switched off, the new work package form never renders the attachments list, and that component was the only place syncing CKEditor uploads into the create payload. The request went out with an empty attachment list, so the uploaded image stayed uncontainered until the cleanup job deleted it.
The frontend now mirrors uploads into the new resource whether or not the list is rendered, and the backend additionally claims any of the author's uncontainered attachments referenced from the description on create, so the same upload also survives when it arrives from the Primer create dialog or from an API client that sends an empty list.