Content
View differences
Updated by Kabiru Mwenja 1 day ago
Deleting a label in Administration > Labels removes it from every work package without a trace in the activity. Each affected work package should record the removal.
**Acceptance criteria**
* When an admin deletes a label that work packages carry, every affected work package gets an activity entry authored by that admin: "**Label removed:** 'Frontend' removed** because the label '<name>' was deleted".
* Several labels deleted by deleted", together with the same admin within the journal aggregation window show as one entry: "**Label removed:** 'Frontend', 'Backend', 'Middleware' were deleted".
* The entry does not show a "Labels changed" line; the removed labels are named in the cause. detail ("Labels: A, (deleted label)" to "A").
* The entries are written by a background job after the deletion; the admin is not kept waiting. Re-running the job adds no duplicate entries.
* Labels nobody uses (including the never-used inline labels removed nightly by COMMS-1050) produce no entries.
**Technical notes**
* Journal New journal cause `label_deleted` (`Journal::CausedByLabelDeletion`) carrying `label_ids` `label_id` and `label_names`, `label_name`, since the label rows are row is gone when the journal is written; rendered through `OpenProject::JournalFormatter::Cause` with pluralisation. `OpenProject::JournalFormatter::Cause`.
* `Journals::CreateService` aggregates a cause into the predecessor's journal when the cause declares `aggregatable_with?` / `aggregate_with` (no-op defaults on `CauseOfChange::Base`); the label deletion cause merges the lists.
* `Labels::DeleteService` collects the work package ids before destroying the label and enqueues `Labels::JournalizeDeletionJob`, which calls `Journals::CreateService` per work package under the work package mutex (no notifications).
* The activities tab hides the labels detail on entries with this cause; API details are unchanged.
* Depends on label journaling (COMMS-1022, PR #25320). Sibling of COMMS-1050 (PR #26187).
**Acceptance criteria**
* When an admin deletes a label that work packages carry, every affected work package gets an activity entry authored by that admin: "**Label removed:** 'Frontend'
* Several labels deleted by
* The entry does not show a "Labels changed" line; the removed labels are named in the cause.
* The entries are written by a background job after the deletion; the admin is not kept waiting. Re-running the job adds no duplicate entries.
* Labels nobody uses (including the never-used inline labels removed nightly by COMMS-1050) produce no entries.
**Technical notes**
* Journal
* `Journals::CreateService` aggregates a cause into the predecessor's journal when the cause declares `aggregatable_with?` / `aggregate_with` (no-op defaults on `CauseOfChange::Base`); the label deletion cause merges the lists.
* `Labels::DeleteService` collects the work package ids before destroying the label and enqueues `Labels::JournalizeDeletionJob`, which calls `Journals::CreateService` per work package under the work package mutex (no notifications).
* The activities tab hides the labels detail on entries with this cause; API details are unchanged.
* Depends on label journaling (COMMS-1022, PR #25320). Sibling of COMMS-1050 (PR #26187).