-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Feature/59178 journalize changes to project stages and gates #17595
base: dev
Are you sure you want to change the base?
Feature/59178 journalize changes to project stages and gates #17595
Conversation
cc2df36
to
663575a
Compare
1e77315
to
f6f3d25
Compare
fc26427
to
60fdb61
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found a few minor issues and left comments about them. Notably the N+1 issues would require attention, and the scenario below also produces interesting results:
- Enable a stage
- Set the date interval
- Disable the stage
Result: The activities show only the date interval update from step 2. The activation and deactivation does not show up as they cancel each other out.
This looks misleading as the value can only be updated if the step is activated, and the logs show nothing about the field being active. One would assume the field was activated in a previous activity, but that is incorrect.
I propose to update the def aggregatable?
method, so that journals are not aggregated when a field is activated (I think deactivation can be aggregated).
We do a similar journal split in case there are multiple notes ("comments") on the same journal. The aggregation is skipped when the user makes multiple comments within the aggregation window.
On a side note, I would rather have the PR unrelated changes in separate PR's in the future, because it makes reviewing a lot easier.
Overall it's a terrific job, thanks @toy 👏
@@ -187,6 +187,7 @@ def event_params(event_data) | |||
params | |||
rescue StandardError => e | |||
Rails.logger.error "Failed to deduce event params for #{event_data.inspect}: #{e}" | |||
{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this a bug?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was intentional, but I'm not sure if there is much sense in it. Normally the method returns a Hash
, but in case of exception it logs it and returns true
from Rails.logger.error
which is unexpected by the only use in fill_events
. So returning empty Hash
prevents rescuing one exception to cause another. And I am not sure about it all, as this just hides the exception, and I don't know if there are maybe legacy cases for errors that should be hidden. So maybe the correct way is just to remove rescue and logging altogether.
case scope | ||
when :all | ||
@scope = event_types | ||
when :all, false, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure about these values, should we also include other possible values, like true
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This handles the case when scope is falsey from options[:scope] || :all
alias_attribute :date, :start_date | ||
|
||
def date_range | ||
start_date..end_date if start_date || end_date |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a typo, should it be if start_date && end_date
? This will generate open ended ranges.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was intended, maybe not really warranted, but I'm trying to prevent hiding data if in some conditions only one of dates is assigned
delegate :sanitize, | ||
to: ::OpenProject::SqlSanitization | ||
|
||
def journable_id = journable.id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems quite arbitrary to move the journable_id
into the helper and not move the journable_type
method.
I found a few more methods that could also be part of the helper: data_sink_columns
, data_source_columns
, journable_data_sql_addition
, text_column_names
, journable_timestamp
, journable_type
, journable_table_name
, data_table_name
, cause_sql
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I extracted only methods that needed to be shared between classes handling associations sql and CreateService
, but looking again it will be cleaner if delegation is used
step = Project::LifeCycleStep.find(key[/\d+/]) | ||
|
||
name = step.definition.name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These will create 2 * M * N + 1 queries. I would suggest taking a look at the JournalFormatterCache and perhaps at the JournalFormatter::NamedAssociation to eliminate it.
end | ||
|
||
describe "requesting single value change" do | ||
let(:multiple_values) { false } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The let(:multiple_values) { true }
case does not seem to be covered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I skipped that combination, as it is not used and supposedly doesn't need to be used.
The :joined
is reproducing the behaviour before this PR which is used by all other formatters, where expectation is that all values are strings and multiple and joined with comma. So I added a way to not convert dates to string only to parse them back. But from what I saw multiple values are only needed when getting single attribute for custom fields, so I skipped it for multiple_attributes_changes
tests.
Caution The provided work package version does not match the core version Details:
Please make sure that:
|
8483e3c
to
03f1328
Compare
@dombesz Thank you for thorough review |
15949ac
to
9d4a5a5
Compare
9d4a5a5
to
a31bd23
Compare
Ticket
OP#59178
What are you trying to accomplish?
What approach did you choose and why?
project_attributes
toproject_details
, as project attributes is the name for project custom fields. Nameproject_details
is also used in few migrations, but that is much less then usage ofproject_attributes
. Created a compatibility alias for users that saved the link or have event types stored in session. OP#61285 to cleanup.Merge checklist