@objectstack/plugin-approvals 17.0.0 → 17.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +192 -0
- package/dist/index.d.mts +2775 -624
- package/dist/index.d.ts +2775 -624
- package/dist/index.js +215 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +215 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,197 @@
|
|
|
1
1
|
# @objectstack/plugin-approvals
|
|
2
2
|
|
|
3
|
+
## 17.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 08d6d3c: feat(approvals): read-only approval visibility for users who can read the target record, per object, default OFF (#8652)
|
|
8
|
+
|
|
9
|
+
A new `ApprovalsPluginOptions.recordReaderVisibleObjects` names the objects on
|
|
10
|
+
which **a user who can READ a business record may also see that record's
|
|
11
|
+
approval requests and full action history** — read-only. Omitted or empty (the
|
|
12
|
+
default) leaves visibility exactly as it is today, so an existing deployment
|
|
13
|
+
sees no behaviour change on upgrade. **This is not a no-op change**: on an
|
|
14
|
+
object you list, a population that could previously see nothing gains a real
|
|
15
|
+
read.
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
new ApprovalsServicePlugin({ recordReaderVisibleObjects: ['exam_sheet'] })
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Who gains visibility.** Until now the visible set was submitter ∪ current
|
|
22
|
+
approver ∪ historical actor, with a platform/tenant admin override as the only
|
|
23
|
+
bypass — so a ledger or supervisor role that holds full read on the record but
|
|
24
|
+
never appears in the approval itself received `200` with an empty list, and the
|
|
25
|
+
Console's approval tab never rendered. On an enabled object, that role now sees
|
|
26
|
+
the record's approvals.
|
|
27
|
+
|
|
28
|
+
**What becomes visible on an enabled object**, stated plainly because the switch
|
|
29
|
+
is an opt-in decision about confidentiality:
|
|
30
|
+
|
|
31
|
+
- the approval request row, including its `payload` snapshot of the record as it
|
|
32
|
+
stood at submission time;
|
|
33
|
+
- the full action history — each actor, their decision, the timestamp, **and the
|
|
34
|
+
action's comment text** (意见正文);
|
|
35
|
+
- decision attachments on those actions, which are gated on the same rule.
|
|
36
|
+
|
|
37
|
+
Enable it on objects whose approval commentary the record's readers are meant to
|
|
38
|
+
see; the comment text is often evaluative, and it is per object precisely so
|
|
39
|
+
that enabling it for a ledger object does not enable it for anything else.
|
|
40
|
+
|
|
41
|
+
**What does NOT change.**
|
|
42
|
+
|
|
43
|
+
- **Read-only.** No approval action is delivered through this tier. Approve,
|
|
44
|
+
reject, reassign, recall and comment keep authorizing exactly as before — on
|
|
45
|
+
the pending-approver slate, the submitter, or admin override — and a viewer
|
|
46
|
+
admitted by this tier gets `can_act: false`. Seeing a request confers nothing.
|
|
47
|
+
- **No new permission concept.** The tier is anchored on the existing
|
|
48
|
+
record-read permission: the service asks the engine to read the record **as
|
|
49
|
+
the caller**, so ordinary object CRUD and RLS decide. No new role, grant type
|
|
50
|
+
or policy, and no host-injected visibility hook — a security predicate the
|
|
51
|
+
platform can neither constrain nor audit was considered and rejected.
|
|
52
|
+
- **The inbox.** An untargeted list is unchanged. The rule is anchored on one
|
|
53
|
+
record, so it applies only where a record is named — a list filtered by
|
|
54
|
+
`object` + `recordId` (what a record page's approval tab sends), or a request
|
|
55
|
+
loaded by id. A work queue does not become a browse surface.
|
|
56
|
+
- **Tenant isolation, and everything else about the existing visible set.** The
|
|
57
|
+
tier only ever adds ids to the participant set; it can never return the "sees
|
|
58
|
+
everything" verdict and never relaxes an existing constraint.
|
|
59
|
+
|
|
60
|
+
### Patch Changes
|
|
61
|
+
|
|
62
|
+
- 66beee0: Guard every authored record-scoped action predicate for the sparse action face, so a list row that did not project the gated column no longer silently drops the button.
|
|
63
|
+
|
|
64
|
+
An action's `visible` / `disabled` predicate binds whatever record the client already fetched — a record-detail read, or a list row carrying only the view's `$select` projection. That binding stays sparse by decision (it is the one record binding the platform does not make total), and CEL aborts the whole expression at key resolution when a key is absent. The abort is fail-closed, so the button is simply not offered — indistinguishable to the user from the gate having said no, and reported nowhere.
|
|
65
|
+
|
|
66
|
+
Every authored predicate on `sys_user`, `sys_invitation`, `sys_member`, `sys_oauth_application` and `sys_approval_request` now opens each `record.*` read with `has()`. The guard is the minimal measured form per predicate, not one blanket rewrite: a bare equality against a literal needs `has()` alone, because CEL compares heterogeneously and answers `false` on a projected-null column rather than faulting.
|
|
67
|
+
|
|
68
|
+
Two predicates change what a user sees, both on `sys_oauth_application`, whose `disabled` column is nullable upstream and therefore null on every application nobody has ever toggled:
|
|
69
|
+
|
|
70
|
+
- `disable_oauth_application` was `!record.disabled`, which faulted on a projected-null row (`!` needs a bool) — so the Disable button was missing from every never-toggled application in the list. It is now `has(record.disabled) && record.disabled != true` and is offered.
|
|
71
|
+
- `enable_oauth_application` was `record.disabled`, which answered `null` rather than a boolean and left the decision to the renderer. It is now `has(record.disabled) && record.disabled == true`.
|
|
72
|
+
|
|
73
|
+
`sys_approval_request`'s decision levers gate on the attached `record.viewer` block and traverse, so they are guarded at the leaf (`has(record.viewer) && has(record.viewer.can_act) && record.viewer.can_act == true`). Measured, that is the minimal safe form for a nested read: the canonical `has(x) && x != null` conjunction still faults when the block is present but the flag is absent or null, while a leaf `has()` subsumes the parent `!= null` half. Their intended fail-closed behaviour is unchanged — it is now a real `false` instead of an evaluation fault.
|
|
74
|
+
- 7ff5aa2: `sys_automation_run` resolves its organization from the DECLARED `AutomationContext.tenantId` and from no other spelling (cloud#1395).
|
|
75
|
+
|
|
76
|
+
The suspended-run store read `context.organizationId ?? context.tenantId`. `AutomationContext` declares `tenantId` and not `organizationId`, and no producer writes the latter — `RecordChangeTrigger.buildContext` maps the hook session's organization onto `tenantId`, and the runtime's automation domain sets `tenantId` directly. The dead limb was not inert: the one test covering `sys_automation_run.organization_id` fed the phantom key, so the column's only coverage exercised a path production cannot reach and said nothing about the live one. The limb is removed, the fixture speaks the declared contract, and a test now asserts the absence so restoring the alias goes red.
|
|
77
|
+
|
|
78
|
+
Both `sys_approval_request.organization_id` and `sys_automation_run.organization_id` now document the measured attribution defect this uncovered and the negative control that makes it a defect: on a walled single-database boot these two tables stored customer activity with no organization (27/27 and 31/31) while `sys_audit_log` (1669 rows) was correctly attributed on the same boot, because the audit writer resolves the organization from the record the row is ABOUT rather than from the acting context. The write-side repair is not in this change — which column a side-table row should follow is an open contract question, since the audit resolver is scope-pinned to audit stamping by the #8778 ruling. The current behaviour is pinned by test so the fix must promote the assertion rather than quietly satisfy it.
|
|
79
|
+
- Updated dependencies [56656aa]
|
|
80
|
+
- Updated dependencies [c9f5950]
|
|
81
|
+
- Updated dependencies [d6e80b2]
|
|
82
|
+
- Updated dependencies [07e630e]
|
|
83
|
+
- Updated dependencies [66beee0]
|
|
84
|
+
- Updated dependencies [2f65b1b]
|
|
85
|
+
- Updated dependencies [720ee95]
|
|
86
|
+
- Updated dependencies [f287435]
|
|
87
|
+
- Updated dependencies [2782805]
|
|
88
|
+
- Updated dependencies [e43d63a]
|
|
89
|
+
- Updated dependencies [9aa8890]
|
|
90
|
+
- Updated dependencies [7c9c1dd]
|
|
91
|
+
- Updated dependencies [03520eb]
|
|
92
|
+
- Updated dependencies [75b7c24]
|
|
93
|
+
- Updated dependencies [d5552ca]
|
|
94
|
+
- Updated dependencies [d9813a9]
|
|
95
|
+
- Updated dependencies [8640fb2]
|
|
96
|
+
- Updated dependencies [2420641]
|
|
97
|
+
- Updated dependencies [2ad91c3]
|
|
98
|
+
- Updated dependencies [f57fb38]
|
|
99
|
+
- Updated dependencies [00777a0]
|
|
100
|
+
- Updated dependencies [d491625]
|
|
101
|
+
- Updated dependencies [2d0af57]
|
|
102
|
+
- Updated dependencies [420804d]
|
|
103
|
+
- Updated dependencies [716ac9b]
|
|
104
|
+
- Updated dependencies [a38408a]
|
|
105
|
+
- Updated dependencies [62b1427]
|
|
106
|
+
- Updated dependencies [7ea1372]
|
|
107
|
+
- Updated dependencies [23abe27]
|
|
108
|
+
- Updated dependencies [985a9cd]
|
|
109
|
+
- Updated dependencies [5f5e234]
|
|
110
|
+
- Updated dependencies [a8189ae]
|
|
111
|
+
- Updated dependencies [26e70fb]
|
|
112
|
+
- Updated dependencies [27a567d]
|
|
113
|
+
- Updated dependencies [42b05af]
|
|
114
|
+
- Updated dependencies [2b292ce]
|
|
115
|
+
- Updated dependencies [abcf853]
|
|
116
|
+
- Updated dependencies [8b9eba5]
|
|
117
|
+
- Updated dependencies [d575779]
|
|
118
|
+
- Updated dependencies [94f7ef8]
|
|
119
|
+
- Updated dependencies [c5ac5e4]
|
|
120
|
+
- Updated dependencies [a777944]
|
|
121
|
+
- Updated dependencies [dd88e1c]
|
|
122
|
+
- Updated dependencies [856527c]
|
|
123
|
+
- Updated dependencies [870f710]
|
|
124
|
+
- Updated dependencies [79c46da]
|
|
125
|
+
- Updated dependencies [7ff3975]
|
|
126
|
+
- Updated dependencies [29d055b]
|
|
127
|
+
- Updated dependencies [65589d6]
|
|
128
|
+
- Updated dependencies [2c86fe3]
|
|
129
|
+
- Updated dependencies [e196c6a]
|
|
130
|
+
- Updated dependencies [24173e9]
|
|
131
|
+
- Updated dependencies [4ab7523]
|
|
132
|
+
- Updated dependencies [19539b4]
|
|
133
|
+
- Updated dependencies [f8eb736]
|
|
134
|
+
- Updated dependencies [11b779e]
|
|
135
|
+
- Updated dependencies [739fe5b]
|
|
136
|
+
- Updated dependencies [4bfe1a5]
|
|
137
|
+
- Updated dependencies [2065e31]
|
|
138
|
+
- Updated dependencies [b69d0f5]
|
|
139
|
+
- Updated dependencies [4d47afe]
|
|
140
|
+
- Updated dependencies [e4e5c6e]
|
|
141
|
+
- Updated dependencies [9a56784]
|
|
142
|
+
- Updated dependencies [d00d2f6]
|
|
143
|
+
- Updated dependencies [df0c12d]
|
|
144
|
+
- Updated dependencies [d31785f]
|
|
145
|
+
- Updated dependencies [c308a4f]
|
|
146
|
+
- Updated dependencies [e2899f6]
|
|
147
|
+
- Updated dependencies [b6c7690]
|
|
148
|
+
- Updated dependencies [3851f87]
|
|
149
|
+
- Updated dependencies [845e164]
|
|
150
|
+
- Updated dependencies [2a29caa]
|
|
151
|
+
- Updated dependencies [09a6eee]
|
|
152
|
+
- Updated dependencies [1a7f907]
|
|
153
|
+
- Updated dependencies [cd455c8]
|
|
154
|
+
- Updated dependencies [e1bb0ca]
|
|
155
|
+
- Updated dependencies [30d3752]
|
|
156
|
+
- Updated dependencies [c80e7ae]
|
|
157
|
+
- Updated dependencies [09a9a8a]
|
|
158
|
+
- Updated dependencies [07026cf]
|
|
159
|
+
- Updated dependencies [5d4f3d5]
|
|
160
|
+
- Updated dependencies [4d80e8b]
|
|
161
|
+
- Updated dependencies [30b1c63]
|
|
162
|
+
- Updated dependencies [7fc01db]
|
|
163
|
+
- Updated dependencies [079b457]
|
|
164
|
+
- Updated dependencies [e43b211]
|
|
165
|
+
- Updated dependencies [890b38f]
|
|
166
|
+
- Updated dependencies [8bee54b]
|
|
167
|
+
- Updated dependencies [04f8fdb]
|
|
168
|
+
- Updated dependencies [7a537ce]
|
|
169
|
+
- Updated dependencies [593c4bf]
|
|
170
|
+
- Updated dependencies [6158146]
|
|
171
|
+
- Updated dependencies [84cb121]
|
|
172
|
+
- Updated dependencies [ca19ee8]
|
|
173
|
+
- Updated dependencies [a675b4d]
|
|
174
|
+
- Updated dependencies [b887013]
|
|
175
|
+
- Updated dependencies [ff08691]
|
|
176
|
+
- Updated dependencies [60e0f90]
|
|
177
|
+
- Updated dependencies [90c5285]
|
|
178
|
+
- Updated dependencies [402c125]
|
|
179
|
+
- Updated dependencies [7901b2d]
|
|
180
|
+
- Updated dependencies [56bca91]
|
|
181
|
+
- Updated dependencies [b3f9831]
|
|
182
|
+
- Updated dependencies [79394d7]
|
|
183
|
+
- Updated dependencies [730fd9a]
|
|
184
|
+
- Updated dependencies [44bc51d]
|
|
185
|
+
- Updated dependencies [bbbfcfc]
|
|
186
|
+
- Updated dependencies [73cfddf]
|
|
187
|
+
- Updated dependencies [d634e66]
|
|
188
|
+
- @objectstack/spec@17.1.0
|
|
189
|
+
- @objectstack/platform-objects@17.1.0
|
|
190
|
+
- @objectstack/types@17.1.0
|
|
191
|
+
- @objectstack/core@17.1.0
|
|
192
|
+
- @objectstack/metadata-core@17.1.0
|
|
193
|
+
- @objectstack/formula@17.1.0
|
|
194
|
+
|
|
3
195
|
## 17.0.0
|
|
4
196
|
|
|
5
197
|
### Minor Changes
|