Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Journal the addition and removal of File Links on Work Packages #13157

Merged
merged 12 commits into from
Jul 24, 2023

Conversation

mereghost
Copy link
Contributor

@mereghost mereghost commented Jul 18, 2023

Original ticket: https://community.openproject.org/projects/openproject/work_packages/42368
Disclaimer: This feature send me on multiple wild goose chases with a lot of dead ends, which was fun. xD

Activities ☑️

With the context from the issue, first question is: what constitutes an Activity? Any changes of the state to the object of interest. A file added, an assignee added, the creation of the object itself from the aether.

How does it work? ⚙️

Internally, every activity is an entry in the Journal model. Every new object there, has a version attached to it and we compare different versions against each other to create the activities. Each of these changes are a detail in Journal parlance.

The actual mechanism of the comparison is kinda cool, but I'll leave you to explore that.

So, for WorkPackages (or for any journalized model) every time changes happen and are saved to the database, a new Journal entry is created that points to the specialized Journal model for that object. The specialized Journal (Journal::WorkPackageJournal in this case) it snapshots the model at the time of saving.

When a journalized record is removed, so are all its journal entries.

Attachments 📋

Attachments aren't properly an attribute of WorkPackage but an associated model. Also, if when you destroy an object, the journal entries go with it, so how does it show the added and removed files on screen (or via the API)?

For those there's a couple of tricks. The Journals::CreateService instead of relying on the Journal::AttachmentJournal it creates a special type of journal called Journal::AttachableJournal that points to an Attachment and version of the Journal that itself points to the Journal::WorkPackageJournal.

When you remove the Attachment another WorkPackageJournalis added without the AttachableJournal, thus making the diff between the records show that the previous file was missing.

All this behaviour is dealt with within the Journal::CreateService massive SQL.

The Solution 🧪

I've tried to mimic the behaviour already existing by introducing the Journal::StorableJournal (yeah, I'm terrible at naming) that will behave exactly as the Journal::AttachableJournal. This meant editing the SQL inside the Journal::CreateService and adding the necessary queries.

Besides this, I had to add calls to the Journal::CreateService on both of our ...FileLink::CreateService and ...FileLink::DeleteService. The code is identical, but it felt like overkill to just create another abstraction for it (cue in Sandy Metz "the wrong abstraction is worse than repetition").

I also needed to add a formatter for our file_links on the Journal. This will allow us to change the rendered templates easily if needed. Besides this there was only a couple of touch-ups on other files to eager-load the new records.

@mereghost mereghost self-assigned this Jul 18, 2023
@mereghost mereghost requested review from ulferts and removed request for ulferts July 18, 2023 16:04
@mereghost mereghost force-pushed the feature/add_file_link_events_to_activities branch from ef2b6db to 6b48768 Compare July 19, 2023 07:49
@mereghost mereghost marked this pull request as ready for review July 19, 2023 09:32
@mereghost mereghost force-pushed the feature/add_file_link_events_to_activities branch from f0994f5 to ce0400a Compare July 19, 2023 09:32
@mereghost mereghost requested review from ulferts and a team July 19, 2023 09:38
Copy link
Member

@akabiru akabiru left a comment

Choose a reason for hiding this comment

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

Top work! 🏆 The detailed PR description is a really nice touch 👍🏾

*I don't have enough context here so will leave the end approval to Jens :)

Copy link
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.

The change is good and follows along the established patterns. Nothing in here surprised me in a bad way so the change itself is on a good track. I added some remarks but it should be easy to address.

What I have been wondering for some time is how to turn the Journals::CreateService to become more flexible so that it is easier to journalize associations and to only do the journalization of e.g. custom_values where it is necessary. But this part does not need to be addressed within this PR.

I haven't tested the code myself as don't have the env set up for it. I'll see how much of a hassle it turns out to be. If I don't manage to do it, somebody else would have to cover that part.

lib/open_project/journal/attachment_helper.rb Outdated Show resolved Hide resolved
lib/open_project/object_linking.rb Outdated Show resolved Hide resolved
@mereghost mereghost requested a review from ulferts July 19, 2023 16:08
Copy link
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.

Amends look good. So from my side, this is good to merge at will.

@mereghost mereghost force-pushed the feature/add_file_link_events_to_activities branch from c71fb03 to f0626a7 Compare July 24, 2023 11:38
@mereghost mereghost merged commit bba0905 into dev Jul 24, 2023
10 checks passed
@mereghost mereghost deleted the feature/add_file_link_events_to_activities branch July 24, 2023 12:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

4 participants