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

feat: update how we check immutability #3188

Conversation

JulissaDantes
Copy link
Contributor

Description

We used the payload data to determine if an immutable field was being altered, but this caused 2 problems:

  • Not optimal developer experience when running a mutation including an immutable field but not mutating it.
  • Databases built on top of js-ceramic using an upsert command will always throw if creating a new record for a model with an immutable field. e.g. ComposeDB

@JulissaDantes JulissaDantes requested a review from PaulLeCam March 19, 2024 14:10
Copy link

linear bot commented Mar 19, 2024

Copy link
Contributor

@stbrody stbrody left a comment

Choose a reason for hiding this comment

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

Is there a test that reproduces the issue you are trying to solve here, using the standard ModelInstanceDocument.replace method? That method already constructs the json-patch to only include fields that actually changed, so I'm not sure how this could ever be a problem in practice.

@JulissaDantes
Copy link
Contributor Author

Is there a test that reproduces the issue you are trying to solve here, using the standard ModelInstanceDocument.replace method? That method already constructs the json-patch to only include fields that actually changed, so I'm not sure how this could ever be a problem in practice.

Yes regarding the test, I changed the model for the set test to include an immutable field. The jsonpatch construction is not the problem, its how we validate immutability on locked fields, thats why we now will compare the previous value with the value post jsonpatch.

Also this is a problem we are currently having, you can check the linear task for a step by step reproduction, those steps will trigger the ModelInstanceDocument.replace method.

@JulissaDantes JulissaDantes requested a review from stbrody March 19, 2024 14:48
Copy link
Contributor

@PaulLeCam PaulLeCam left a comment

Choose a reason for hiding this comment

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

I think the logic works but could be simplified, seems to me the immutable fields check can simply be bypassed when the current state content is null, no?

const modelStream = await context.loadStream<Model>(metadata.model)
await this._validateContent(context, modelStream, newContent, false, payload)
await this._validateContent(context, modelStream, newContent, false, payload, oldContent)
Copy link
Contributor

Choose a reason for hiding this comment

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

Couldn't state.content be passed directly here, having the logic handle if it's null?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes it could, but the oldContent line already handles if state.content its null, what would be the benefit of doing that here?

Copy link
Contributor

@PaulLeCam PaulLeCam Mar 20, 2024

Choose a reason for hiding this comment

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

I just think the null value should be provided directly, no need to provide an empty object as fallback, so the following logic can do the null check.
Basically, having an empty object doesn't guaranty that the content wasn't set in the immutable fields check.

Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than relying on the content being null, which feels like an indirect check of what we want and maybe not entirely future-proof (what if stream content could be explicitly set to null in the future?), could we instead check that the stream has a set account relation and that this is the first data commit? That feels like the actual rule that should allow content to be set for the first time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

you mean checking the state.log and confirm this is the first data commit? or do you mean something else?

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah exactly. Will also need to check the Model this MID belongs to and see if it's using set or single account relations (also I just remembered single account relation likely has the exact same problem, so we should probably add a test for it also)

Copy link
Contributor

@stbrody stbrody left a comment

Choose a reason for hiding this comment

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

I think things are correct now, but this approach introduces a lot of extra clones of the content which is not ideal. Could we go back to the original approach of checking the jsonPatch for if it touches any of the immutable fields, but just add an explicit exception for if the stream has the SET account relation and the commit being applied is the very first data event?

Copy link
Contributor

@stbrody stbrody left a comment

Choose a reason for hiding this comment

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

a few small nitpick suggestions. Main comment is to avoid the now-unnecessary extra clone of the content in the commit handler.

@JulissaDantes JulissaDantes enabled auto-merge (squash) March 21, 2024 16:52
@JulissaDantes JulissaDantes requested a review from stbrody March 21, 2024 16:52
@JulissaDantes JulissaDantes requested a review from stbrody March 21, 2024 19:18
Copy link
Contributor

@stbrody stbrody left a comment

Choose a reason for hiding this comment

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

LGTM

@JulissaDantes JulissaDantes merged commit 102d357 into develop Mar 21, 2024
7 checks passed
@JulissaDantes JulissaDantes deleted the feature/ws2-3139-models-with-set-relation-and-immutable-fields branch March 21, 2024 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants