docs: document cds.drafts.enforceReadonly and the @readonly bypass hint - #2790
docs: document cds.drafts.enforceReadonly and the @readonly bypass hint#2790rjayasinghe wants to merge 3 commits into
Conversation
Explain that @readonly/@Core.Computed are enforced on drafts (during
DRAFT_NEW/DRAFT_PATCH) when cds.drafts.enforceReadonly is enabled, and
document the .hint("@readonly", false) statement hint to write such
fields from trusted custom code.
Closes cds-java/home#2828
|
Hey @mofterdinger Could you provide your feedback for this PR? Thank you :) |
|
|
||
| By default, `@readonly` and `@Core.Computed` fields are only enforced when a draft is activated, that means during the `CREATE` or `UPDATE` event on the active entity. Until then, such fields can still be changed on the draft, for example through an OData `PATCH` request. | ||
|
|
||
| To enforce these annotations on the draft already, during the `DRAFT_NEW` and `DRAFT_PATCH` events, set the [`cds.drafts.enforceReadonly`](./developing-applications/properties#cds-drafts-enforcereadonly) property (default `false`): |
There was a problem hiding this comment.
| To enforce these annotations on the draft already, during the `DRAFT_NEW` and `DRAFT_PATCH` events, set the [`cds.drafts.enforceReadonly`](./developing-applications/properties#cds-drafts-enforcereadonly) property (default `false`): | |
| To enforce these annotations on the draft even before activation, during the `DRAFT_NEW` and `DRAFT_PATCH` events, set the [`cds.drafts.enforceReadonly`](./developing-applications/properties#cds-drafts-enforcereadonly) property (default `false`): |
There was a problem hiding this comment.
Maybe it doesn't even need the "even" :)
| To enforce these annotations on the draft already, during the `DRAFT_NEW` and `DRAFT_PATCH` events, set the [`cds.drafts.enforceReadonly`](./developing-applications/properties#cds-drafts-enforcereadonly) property (default `false`): | |
| To enforce these annotations on the draft before activation, during the `DRAFT_NEW` and `DRAFT_PATCH` events, set the [`cds.drafts.enforceReadonly`](./developing-applications/properties#cds-drafts-enforcereadonly) property (default `false`): |
|
Hi, sorry, I can't provide any helpful review feedback, I wasn't involved in implementing this feature. Will remove my assignment. |
|
I guess @beckermarc is the better candidate. :) |
| During activation the draft data is deleted from the database. This happens before the active entity is created or updated within the same transaction. | ||
| In case the create or update operation raises an error, the transaction is rolled back and the draft data is restored. | ||
|
|
||
| ## Read-Only Fields in Drafts { #readonly-in-drafts } |
There was a problem hiding this comment.
We should also explain the effects for readonly elements calculated in code (determinations). In the default scenario determinations need to happen during draft activation on CREATE or UPDATE. They can optionally happen at draft edit time as well (to show the determined field on the UI already in that mode). If the determination is not fully deterministic (e.g. creating a random UUID) there is no guarantee that values created in draft mode and during activation are the same.
This can be solved by setting the enforceReadonly flag to false as well, as on that mode @readonly is no longer evaluated during activation, thus elements calculated in draft mode are taken over with the exact same value.
|
|
||
| ### Writing Read-Only Fields from Custom Code { #readonly-hint } | ||
|
|
||
| When `cds.drafts.enforceReadonly` is enabled, the read-only enforcement also applies to `Update` or `Insert` statements that your own event handlers run against the draft entity, for example in a determination. As a result, values for `@readonly` and `@Core.Computed` fields are removed from these statements as well. |
There was a problem hiding this comment.
We should mention here explicitly that this applies to statements run via the DraftService.
What
Adds prose documentation for the
cds.drafts.enforceReadonlyproperty injava/fiori-drafts.md(new Read-Only Fields in Drafts section):@readonly/@Core.Computedare enforced only at activation by default, and that settingcds.drafts.enforceReadonly: trueenforces them on the draft itself duringDRAFT_NEW/DRAFT_PATCH(so read-only fields can't be changed via ODataPATCHon the draft)..hint("@readonly", false)to intentionally write read-only / computed fields from trusted custom code (e.g. determinations), with a warning that managed (@cds.on.insert/@cds.on.update) and@Core.Immutablefields remain enforced regardless.Why
The property already appears in the generated properties table but had no prose explaining the custom-code implication or the bypass hint, which surfaced in a developer question.
Verification
npm run docs:buildpasses with no dead-link errors; the property cross-link anchor#cds-drafts-enforcereadonlymatches the generated id.ReadOnlyHandler).