Content
View differences
Updated by Kabiru Mwenja 11 months ago
## ADR: Extracting Journal#notes to Comments
<img class="op-uc-image op-uc-image_inline" src="/api/v3/attachments/703564/content">
## Context
**What is the issue that is motivating this decision or change?**
See #62381
Currently, work package activity comments are stored as `Journal#notes`. The `Journals` model is designed to capture data snapshots/changes for any "Journable" object, providing a historical timeline of changes. For example, in a `WorkPackage`, it allows tracking attribute changes such as "Assignee was changed from UserA to UserB".
However, there are several nuances to this model that do not align well with the intended behavior of a standalone "Comments" model:
* **Data footprint:** Every time a new journal is logged, a full snapshot of the "Journable" (e.g., `WorkPackage`) is stored, regardless of whether the change is comment-related.
* **Aggregation Complexity:** Journals support a configurable aggregation validity period, allowing changes within a certain time frame to be merged into a single journal. This introduces complexity, such as virtual sequencing when rendering activities so they are numbered sequentially (1..n).
* **Unnecessary Snapshots for Comments:** Each new comment results in a full data snapshot, overriding the aggregation period if subsequent journals with notes (comments) are added.
* **Complex Features:** Journals power features such as [baseline comparison](https://www.openproject.org/docs/user-guide/work-packages/baseline-comparison/), which are data and performance-intensive.
* **Overloaded Concepts:** The idea of "internal comments" is superimposed onto the `Journals` table, even though it's not relevant to all Journables.
* **Irrelevant Relations:** Relations such as `EmojiReaction` and `Attachment` are imposed on the Journal model, even when not all Journables need them.
📖 See the [Journals::CreateService](https://github.com/opf/openproject/blob/258af380b4401de54b917aeffa125e60e6b35ae7/app/services/journals/create_service.rb#L105-L196) for more details on the inner workings.
## Decision
**What change are we proposing or making?**
* Extract `Journal#notes` into a dedicated `Comments` model.
* Define an "Events" SQL view that joins Journals and Comments into a unified, chronological timeline.
## Data Migration
Journals represent one of the largest datasets in the system, so migrating data may be time-intensive. Extensive tests should be conducted during implementation. If necessary, consider performing the data migration via background jobs, though this adds complexity (see #65240).
## Consequences
**What becomes easier or more difficult as a result of this change?**
**Pros:**
* **Separation of Concerns:** Comments can be managed as a standalone entity, reducing the risk of unintended Journal side-effects.
* **Data Reduction:** A full Journable snapshot will no longer be created for every comment, and comment creation will not override aggregation.
**Cons:**
* **Long-running Data Migration:** Due to the size of the Journals dataset, migration may take significant time. Adequate testing and possibly background jobs will be required.
* **Dynamic Sorting & Indexing (TBD):** Serving activities from an SQL view will require runtime sorting and possibly indexing for performance.
##### Open Points:
1. ###65250 We included the restricted/internal flag on Journals. If we move comments away, that flag becomes essentially unused. Should we consider removing it?
###
###
### Related topics
* **Authorization and Auditing:** Ensure Comments have clear ownership and audit trails, just as Journals do.
* **Future-proofing:** Design the Comments model to be extensible for features like rich-text support or threading.
* **API Consistency:** Update APIs to support the new Comments model, ensuring backward compatibility where needed.
* **Archival Strategy:** Plan for efficient archival and purging of legacy Journals once migration is complete.
* **Testing:** Develop comprehensive migration and regression tests to ensure data integrity and application stability throughout the transition.
##### Regression Checks:
We should review things we tackled during the internal comments implementation like:
* ###65251 Permissions
* Activities Tab
* Rendering
* Quoting
* Global/Project/User activity
* Exports like PDF and CSV (IIRC nothing to be done here, but worth double checking)
* Notifications
* APIs
<img class="op-uc-image op-uc-image_inline" src="/api/v3/attachments/703564/content">
## Context
**What is the issue that is motivating this decision or change?**
See #62381
Currently, work package activity comments are stored as `Journal#notes`. The `Journals` model is designed to capture data snapshots/changes for any "Journable" object, providing a historical timeline of changes. For example, in a `WorkPackage`, it allows tracking attribute changes such as "Assignee was changed from UserA to UserB".
However, there are several nuances to this model that do not align well with the intended behavior of a standalone "Comments" model:
* **Data footprint:** Every time a new journal is logged, a full snapshot of the "Journable" (e.g., `WorkPackage`) is stored, regardless of whether the change is comment-related.
* **Aggregation Complexity:** Journals support a configurable aggregation validity period, allowing changes within a certain time frame to be merged into a single journal. This introduces complexity, such as virtual sequencing when rendering activities so they are numbered sequentially (1..n).
* **Unnecessary Snapshots for Comments:** Each new comment results in a full data snapshot, overriding the aggregation period if subsequent journals with notes (comments) are added.
* **Complex Features:** Journals power features such as [baseline comparison](https://www.openproject.org/docs/user-guide/work-packages/baseline-comparison/), which are data and performance-intensive.
* **Overloaded Concepts:** The idea of "internal comments" is superimposed onto the `Journals` table, even though it's not relevant to all Journables.
* **Irrelevant Relations:** Relations such as `EmojiReaction` and `Attachment` are imposed on the Journal model, even when not all Journables need them.
📖 See the [Journals::CreateService](https://github.com/opf/openproject/blob/258af380b4401de54b917aeffa125e60e6b35ae7/app/services/journals/create_service.rb#L105-L196) for more details on the inner workings.
## Decision
**What change are we proposing or making?**
* Extract `Journal#notes` into a dedicated `Comments` model.
* Define an "Events" SQL view that joins Journals and Comments into a unified, chronological timeline.
## Data Migration
Journals represent one of the largest datasets in the system, so migrating data may be time-intensive. Extensive tests should be conducted during implementation. If necessary, consider performing the data migration via background jobs, though this adds complexity (see #65240).
## Consequences
**What becomes easier or more difficult as a result of this change?**
**Pros:**
* **Separation of Concerns:** Comments can be managed as a standalone entity, reducing the risk of unintended Journal side-effects.
* **Data Reduction:** A full Journable snapshot will no longer be created for every comment, and comment creation will not override aggregation.
**Cons:**
* **Long-running Data Migration:** Due to the size of the Journals dataset, migration may take significant time. Adequate testing and possibly background jobs will be required.
* **Dynamic Sorting & Indexing (TBD):** Serving activities from an SQL view will require runtime sorting and possibly indexing for performance.
##### Open Points:
1. ###65250
###
###
### Related topics
* **Authorization and Auditing:** Ensure Comments have clear ownership and audit trails, just as Journals do.
* **Future-proofing:** Design the Comments model to be extensible for features like rich-text support or threading.
* **API Consistency:** Update APIs to support the new Comments model, ensuring backward compatibility where needed.
* **Archival Strategy:** Plan for efficient archival and purging of legacy Journals once migration is complete.
* **Testing:** Develop comprehensive migration and regression tests to ensure data integrity and application stability throughout the transition.
##### Regression Checks:
We should review things we tackled during the internal comments implementation like:
* ###65251
* Activities Tab
* Rendering
* Quoting
* Global/Project/User activity
* Exports like PDF and CSV (IIRC nothing to be done here, but worth double checking)
* Notifications
* APIs