|
| 1 | +--- |
| 2 | +"@objectstack/plugin-sharing": minor |
| 3 | +--- |
| 4 | + |
| 5 | +feat(plugin-sharing): the `field` sharing recipient is enforced — expanded once per matched record |
| 6 | + |
| 7 | +`ShareRecipientType` gained `field` on the spec side (#14103, maintainer ruling |
| 8 | +B): `sharedWith: { type: 'field', value: '<user-field-name>' }` shares each |
| 9 | +record the rule's criteria match with the user or users named by that column |
| 10 | +on the record. This is the executor half (#15072): |
| 11 | + |
| 12 | +- `SharingRuleService` reads the named user-typed column on each matched |
| 13 | + record. A `multiple: true` column shares with every user it names; a single- |
| 14 | + user column with the one it names. **Fail-closed on empty**: a null or empty |
| 15 | + column materialises no grant — never a match-all principal, never a fallback |
| 16 | + to the record owner. `field` is the only recipient resolved per record; every |
| 17 | + other kind (`user`, `team`, `position`, `business_unit`, |
| 18 | + `unit_and_subordinates`) still expands once per rule. |
| 19 | +- The grants re-materialise on the record's own write: the existing |
| 20 | + `afterUpdate` hook has no changed-field gating, so an update that touches only |
| 21 | + the recipient column re-runs the per-record reconcile, which revokes the |
| 22 | + stale grant and materialises the new one. No second trigger was added. |
| 23 | +- The whole-rule pass (`evaluateRule` — the background re-grant after an |
| 24 | + unbounded bulk write, the `kernel:bootstrapped` backfill and the REST evaluate |
| 25 | + endpoint) derives per-record (record, user) pairs for a `field` rule instead |
| 26 | + of a matched-records × recipients product, so the rule is as correct after a |
| 27 | + bulk write and a restart as it is inline. The recipient-axis revoke |
| 28 | + (`revokeRuleGrantsForRetiredRecipients`) declines `field` rules — they have no |
| 29 | + rule-wide recipient set to retire against. |
| 30 | +- The declared-rule bootstrap seeds `field` rules (previously skipped with a |
| 31 | + warning), the `sys_sharing_rule.recipient_type` select accepts `field`, and |
| 32 | + `defineRule` refuses a `field` recipient whose `recipientId` is not a field |
| 33 | + name (the same grammar the spec applies at parse). |
| 34 | +- An active `field` rule whose column the object does not declare as user-typed |
| 35 | + grants nobody and says so once per rule. |
| 36 | + |
| 37 | +There is no `manager` recipient: "the owner's manager" is a user field the |
| 38 | +application stores on the record, named by a `field` recipient. |
0 commit comments