Hmm yes, that security rule is definitely obscure. Perhaps a good idea for the idea forum.
One other design would be to use a helper or staging entity to store the “draft” data, and then save that into a persisted, read-only record when it’s saved. Then you get clean security rules, but at the cost of maintaining an extra entity.
Nice! Learned something again: in the Access rules, the Create-rights don't check the XPath constraints.
Setting the constraint to "[false()]” does get you the behavior you want, but I agree that it is ugly in the sense that I need some extra explanation whenever I stumble upon code like that. I am pretty sure that there is no best practice for it. The best alternative I can think of is adding a false string-comparison that explains its purpose:
['This entity is creatable but once created, it ' = ' not modifiable.']
I consider this still ugly, but I would need no further explanation.
Another approach I have seen other developers doing is, have an attribute in the entity itself called ‘isNew’ which is set to true when object is created. And set to false when object is committed. This ‘isNew’ will be more inline with isNew check that Mendix offers as well. With this, we might also have a cleaner Access rules based on this boolean.
May be we can also try to capture the details with NPE and clone it to Persistable entity. This way, the persistable entity always have one Read only access rule and NPE can be delegated for create purposes.