@almadar/std 16.216.0 → 16.218.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.
@@ -0,0 +1,2229 @@
1
+ {
2
+ "description": "std-permission-matrix — role × module permission grant table / capability matrix admin surface. Use when a user voices that permissions must be managed per role and module (permission matrix, role permissions, capability matrix, permission grants, access matrix, who can see finance, hide margins, module-level permissions, admin permission screen, grant management, finance visibility by role, restrict modules by role). Persists PermissionGrant rows (workspaceId + role + module + capability flags canReadFinance / canSeeOthersHours / canSeeMargins) with full CRUD on an admin page mounted at /admin/permissions — create/edit forms are the std-modal ModalRecordModal substrate (the corpus's two-trait CRUD shape, mirroring std-list), persists live in a sibling coordinator trait, and adminRoles is ENFORCED at the persist boundary (a viewer whose role is not listed cannot fire a write, from the button or from the bus). Ships a query trait other traits consult event-wise: CHECK_GRANT { role, module } fetches the matching grant(s) and re-emits GRANT_RESOLVED { role, module, canReadFinance, canSeeOthersHours, canSeeMargins, found }. Grant SURFACE only — entity-layer @read/@update gate integration is a recorded core gap (gates are pure @entity/@user S-expressions and cannot consult another entity's rows), so enforcement stays with the consumer until that core lands.",
3
+ "ledger": {
4
+ "entries": {
5
+ "ent_01M2HEYQZMYFHR14P4RKB46K51": {
6
+ "bakedName": "PermissionGrant",
7
+ "curName": "PermissionGrant",
8
+ "id": "ent_01M2HEYQZMYFHR14P4RKB46K51",
9
+ "kind": "entity",
10
+ "owner": "workspace",
11
+ "renames": []
12
+ },
13
+ "evt_01M2HEYQZM24QM0A2ERYSYN7P1": {
14
+ "bakedName": "CHECK_GRANT",
15
+ "curName": "CHECK_GRANT",
16
+ "id": "evt_01M2HEYQZM24QM0A2ERYSYN7P1",
17
+ "kind": "event",
18
+ "owner": "workspace",
19
+ "parent": "trt_01M2HEYQZMAE7G04QDC54C9G1J",
20
+ "renames": []
21
+ },
22
+ "evt_01M2HEYQZM9DM2K7FGY74WKBBT": {
23
+ "bakedName": "PermissionGrantLoadFailed",
24
+ "curName": "PermissionGrantLoadFailed",
25
+ "id": "evt_01M2HEYQZM9DM2K7FGY74WKBBT",
26
+ "kind": "event",
27
+ "owner": "workspace",
28
+ "parent": "trt_01M2HEYQZMJ2XVG13CS09YSQZG",
29
+ "renames": []
30
+ },
31
+ "evt_01M2HEYQZMEN5KMN1S2P458NWV": {
32
+ "bakedName": "INIT",
33
+ "curName": "INIT",
34
+ "id": "evt_01M2HEYQZMEN5KMN1S2P458NWV",
35
+ "kind": "event",
36
+ "owner": "workspace",
37
+ "parent": "trt_01M2HEYQZMJ2XVG13CS09YSQZG",
38
+ "renames": []
39
+ },
40
+ "evt_01M2HEYQZMNXE0Q2CRE9GJDF8C": {
41
+ "bakedName": "NEW",
42
+ "curName": "NEW",
43
+ "id": "evt_01M2HEYQZMNXE0Q2CRE9GJDF8C",
44
+ "kind": "event",
45
+ "owner": "workspace",
46
+ "parent": "trt_01M2HEYQZMJ2XVG13CS09YSQZG",
47
+ "renames": []
48
+ },
49
+ "evt_01M2HEYQZMPARRK5AP79C66MS0": {
50
+ "bakedName": "GRANT_RESOLVED",
51
+ "curName": "GRANT_RESOLVED",
52
+ "id": "evt_01M2HEYQZMPARRK5AP79C66MS0",
53
+ "kind": "event",
54
+ "owner": "workspace",
55
+ "parent": "trt_01M2HEYQZMAE7G04QDC54C9G1J",
56
+ "renames": []
57
+ },
58
+ "evt_01M2HEYQZMT7BCD58DZH8CJCC4": {
59
+ "bakedName": "GrantCheckFailed",
60
+ "curName": "GrantCheckFailed",
61
+ "id": "evt_01M2HEYQZMT7BCD58DZH8CJCC4",
62
+ "kind": "event",
63
+ "owner": "workspace",
64
+ "parent": "trt_01M2HEYQZMAE7G04QDC54C9G1J",
65
+ "renames": []
66
+ },
67
+ "evt_01M2HEYQZMVNZ5YTXXR38WPM6R": {
68
+ "bakedName": "PermissionGrantLoaded",
69
+ "curName": "PermissionGrantLoaded",
70
+ "id": "evt_01M2HEYQZMVNZ5YTXXR38WPM6R",
71
+ "kind": "event",
72
+ "owner": "workspace",
73
+ "parent": "trt_01M2HEYQZMJ2XVG13CS09YSQZG",
74
+ "renames": []
75
+ },
76
+ "evt_01M2HEYQZMWK4TZVSSZS3093ZG": {
77
+ "bakedName": "DELETE",
78
+ "curName": "DELETE",
79
+ "id": "evt_01M2HEYQZMWK4TZVSSZS3093ZG",
80
+ "kind": "event",
81
+ "owner": "workspace",
82
+ "parent": "trt_01M2HEYQZMJ2XVG13CS09YSQZG",
83
+ "renames": []
84
+ },
85
+ "evt_01M2HEYQZMXWXQ5M0JAD911R8X": {
86
+ "bakedName": "EDIT",
87
+ "curName": "EDIT",
88
+ "id": "evt_01M2HEYQZMXWXQ5M0JAD911R8X",
89
+ "kind": "event",
90
+ "owner": "workspace",
91
+ "parent": "trt_01M2HEYQZMJ2XVG13CS09YSQZG",
92
+ "renames": []
93
+ },
94
+ "evt_01M2HEYQZMZJWHEXPD8YKCP48D": {
95
+ "bakedName": "GrantCheckLoaded",
96
+ "curName": "GrantCheckLoaded",
97
+ "id": "evt_01M2HEYQZMZJWHEXPD8YKCP48D",
98
+ "kind": "event",
99
+ "owner": "workspace",
100
+ "parent": "trt_01M2HEYQZMAE7G04QDC54C9G1J",
101
+ "renames": []
102
+ },
103
+ "evt_01M2JCDX8H82D6D1V7RTZ6CMY1": {
104
+ "bakedName": "PermissionGrantSaved",
105
+ "curName": "PermissionGrantSaved",
106
+ "id": "evt_01M2JCDX8H82D6D1V7RTZ6CMY1",
107
+ "kind": "event",
108
+ "owner": "workspace",
109
+ "parent": "trt_01M2JCDX8HJFRR69J2HRX0450S",
110
+ "renames": []
111
+ },
112
+ "evt_01M2JCDX8HDS4691JHRXJ401PT": {
113
+ "bakedName": "PermissionGrantDeleteFailed",
114
+ "curName": "PermissionGrantDeleteFailed",
115
+ "id": "evt_01M2JCDX8HDS4691JHRXJ401PT",
116
+ "kind": "event",
117
+ "owner": "workspace",
118
+ "parent": "trt_01M2JCDX8HJFRR69J2HRX0450S",
119
+ "renames": []
120
+ },
121
+ "evt_01M2JCDX8HFPEBTZF91HFFKT10": {
122
+ "bakedName": "PermissionGrantSaveFailed",
123
+ "curName": "PermissionGrantSaveFailed",
124
+ "id": "evt_01M2JCDX8HFPEBTZF91HFFKT10",
125
+ "kind": "event",
126
+ "owner": "workspace",
127
+ "parent": "trt_01M2JCDX8HJFRR69J2HRX0450S",
128
+ "renames": []
129
+ },
130
+ "evt_01M2JCDX8HG5S847YTMPZ2NMPN": {
131
+ "bakedName": "DO_UPDATE",
132
+ "curName": "DO_UPDATE",
133
+ "id": "evt_01M2JCDX8HG5S847YTMPZ2NMPN",
134
+ "kind": "event",
135
+ "owner": "workspace",
136
+ "parent": "trt_01M2JCDX8HJFRR69J2HRX0450S",
137
+ "renames": []
138
+ },
139
+ "evt_01M2JCDX8HH16NM9P3NDPX5Y31": {
140
+ "bakedName": "DO_DELETE",
141
+ "curName": "DO_DELETE",
142
+ "id": "evt_01M2JCDX8HH16NM9P3NDPX5Y31",
143
+ "kind": "event",
144
+ "owner": "workspace",
145
+ "parent": "trt_01M2JCDX8HJFRR69J2HRX0450S",
146
+ "renames": []
147
+ },
148
+ "evt_01M2JCDX8HSG3NXK4ECZY8FH33": {
149
+ "bakedName": "INIT",
150
+ "curName": "INIT",
151
+ "id": "evt_01M2JCDX8HSG3NXK4ECZY8FH33",
152
+ "kind": "event",
153
+ "owner": "workspace",
154
+ "parent": "trt_01M2JCDX8HJFRR69J2HRX0450S",
155
+ "renames": []
156
+ },
157
+ "evt_01M2JCDX8HSZYBRKTW58856G6X": {
158
+ "bakedName": "DO_CREATE",
159
+ "curName": "DO_CREATE",
160
+ "id": "evt_01M2JCDX8HSZYBRKTW58856G6X",
161
+ "kind": "event",
162
+ "owner": "workspace",
163
+ "parent": "trt_01M2JCDX8HJFRR69J2HRX0450S",
164
+ "renames": []
165
+ },
166
+ "evt_01M2JCDX8HYHAHKQHTFSBAF5MN": {
167
+ "bakedName": "PermissionGrantDeleted",
168
+ "curName": "PermissionGrantDeleted",
169
+ "id": "evt_01M2JCDX8HYHAHKQHTFSBAF5MN",
170
+ "kind": "event",
171
+ "owner": "workspace",
172
+ "parent": "trt_01M2JCDX8HJFRR69J2HRX0450S",
173
+ "renames": []
174
+ },
175
+ "orb_01M2HEYQZME0WVSVJ3G64KQBJF": {
176
+ "bakedName": "PermissionMatrixOrbital",
177
+ "curName": "PermissionMatrixOrbital",
178
+ "id": "orb_01M2HEYQZME0WVSVJ3G64KQBJF",
179
+ "kind": "orbital",
180
+ "owner": "workspace",
181
+ "renames": []
182
+ },
183
+ "pag_01M2HEYQZMA80XV7ZFHG4981XG": {
184
+ "bakedName": "PermissionMatrixPage",
185
+ "curName": "PermissionMatrixPage",
186
+ "id": "pag_01M2HEYQZMA80XV7ZFHG4981XG",
187
+ "kind": "page",
188
+ "owner": "workspace",
189
+ "renames": []
190
+ },
191
+ "trt_01M2HEYQZM136RV41RKCDE1XVT": {
192
+ "bakedName": "ErrorAlert",
193
+ "curName": "ErrorAlert",
194
+ "id": "trt_01M2HEYQZM136RV41RKCDE1XVT",
195
+ "kind": "trait",
196
+ "owner": "workspace",
197
+ "renames": []
198
+ },
199
+ "trt_01M2HEYQZM4C5E4AARRCTKK9GC": {
200
+ "bakedName": "ErrorSpinner",
201
+ "curName": "ErrorSpinner",
202
+ "id": "trt_01M2HEYQZM4C5E4AARRCTKK9GC",
203
+ "kind": "trait",
204
+ "owner": "workspace",
205
+ "renames": []
206
+ },
207
+ "trt_01M2HEYQZM938N2V00VDF2K0XJ": {
208
+ "bakedName": "GrantDivider",
209
+ "curName": "GrantDivider",
210
+ "id": "trt_01M2HEYQZM938N2V00VDF2K0XJ",
211
+ "kind": "trait",
212
+ "owner": "workspace",
213
+ "renames": []
214
+ },
215
+ "trt_01M2HEYQZMA43G4PA24BEP3K3A": {
216
+ "bakedName": "LoadingSpinner",
217
+ "curName": "LoadingSpinner",
218
+ "id": "trt_01M2HEYQZMA43G4PA24BEP3K3A",
219
+ "kind": "trait",
220
+ "owner": "workspace",
221
+ "renames": []
222
+ },
223
+ "trt_01M2HEYQZMAE7G04QDC54C9G1J": {
224
+ "bakedName": "PermissionGrantQuery",
225
+ "curName": "PermissionGrantQuery",
226
+ "id": "trt_01M2HEYQZMAE7G04QDC54C9G1J",
227
+ "kind": "trait",
228
+ "owner": "workspace",
229
+ "renames": []
230
+ },
231
+ "trt_01M2HEYQZMBC4GABK9BV5Z4PVH": {
232
+ "bakedName": "PermissionMatrixTitle",
233
+ "curName": "PermissionMatrixTitle",
234
+ "id": "trt_01M2HEYQZMBC4GABK9BV5Z4PVH",
235
+ "kind": "trait",
236
+ "owner": "workspace",
237
+ "renames": []
238
+ },
239
+ "trt_01M2HEYQZMD1A2NASDVFHAH83A": {
240
+ "bakedName": "ShieldCheckIcon",
241
+ "curName": "ShieldCheckIcon",
242
+ "id": "trt_01M2HEYQZMD1A2NASDVFHAH83A",
243
+ "kind": "trait",
244
+ "owner": "workspace",
245
+ "renames": []
246
+ },
247
+ "trt_01M2HEYQZMJ2XVG13CS09YSQZG": {
248
+ "bakedName": "PermissionMatrixAdmin",
249
+ "curName": "PermissionMatrixAdmin",
250
+ "id": "trt_01M2HEYQZMJ2XVG13CS09YSQZG",
251
+ "kind": "trait",
252
+ "owner": "workspace",
253
+ "renames": []
254
+ },
255
+ "trt_01M2HEYQZMVQRQFSVXKB1RVNR2": {
256
+ "bakedName": "LoadingText",
257
+ "curName": "LoadingText",
258
+ "id": "trt_01M2HEYQZMVQRQFSVXKB1RVNR2",
259
+ "kind": "trait",
260
+ "owner": "workspace",
261
+ "renames": []
262
+ },
263
+ "trt_01M2JCDX8HHAZN1S4Q1QYN78H5": {
264
+ "bakedName": "PermissionGrantEdit",
265
+ "curName": "PermissionGrantEdit",
266
+ "id": "trt_01M2JCDX8HHAZN1S4Q1QYN78H5",
267
+ "kind": "trait",
268
+ "owner": "workspace",
269
+ "renames": []
270
+ },
271
+ "trt_01M2JCDX8HJFRR69J2HRX0450S": {
272
+ "bakedName": "PermissionGrantPersistor",
273
+ "curName": "PermissionGrantPersistor",
274
+ "id": "trt_01M2JCDX8HJFRR69J2HRX0450S",
275
+ "kind": "trait",
276
+ "owner": "workspace",
277
+ "renames": []
278
+ },
279
+ "trt_01M2JCDX8HQFZ924VC3E15FY0J": {
280
+ "bakedName": "PermissionGrantCreate",
281
+ "curName": "PermissionGrantCreate",
282
+ "id": "trt_01M2JCDX8HQFZ924VC3E15FY0J",
283
+ "kind": "trait",
284
+ "owner": "workspace",
285
+ "renames": []
286
+ }
287
+ },
288
+ "schemaVersion": 1
289
+ },
290
+ "name": "std-permission-matrix",
291
+ "orbitals": [
292
+ {
293
+ "entity": {
294
+ "collection": "permission_grants",
295
+ "fields": [
296
+ {
297
+ "name": "id",
298
+ "required": true,
299
+ "type": "string"
300
+ },
301
+ {
302
+ "default": "",
303
+ "description": "Workspace the grant applies to; blank = applies to every workspace.",
304
+ "name": "workspaceId",
305
+ "synonyms": "workspace, tenant, org, organization",
306
+ "type": "string"
307
+ },
308
+ {
309
+ "description": "The role the grant applies to (e.g. admin, manager, contractor).",
310
+ "name": "role",
311
+ "required": true,
312
+ "synonyms": "user role, group, team role",
313
+ "type": "string"
314
+ },
315
+ {
316
+ "description": "The module or feature area the grant governs.",
317
+ "name": "module",
318
+ "required": true,
319
+ "synonyms": "feature, area, section, screen",
320
+ "type": "string"
321
+ },
322
+ {
323
+ "default": false,
324
+ "description": "Whether the role may read finance data in this module.",
325
+ "name": "canReadFinance",
326
+ "synonyms": "see finance, read financials, view finance, finance access",
327
+ "type": "boolean"
328
+ },
329
+ {
330
+ "default": false,
331
+ "description": "Whether the role may see other people's logged hours in this module.",
332
+ "name": "canSeeOthersHours",
333
+ "synonyms": "see others hours, view team hours, timesheet visibility, other people's time",
334
+ "type": "boolean"
335
+ },
336
+ {
337
+ "default": false,
338
+ "description": "Whether the role may see margin / profit figures in this module.",
339
+ "name": "canSeeMargins",
340
+ "synonyms": "see margins, view profit, margin visibility, profitability",
341
+ "type": "boolean"
342
+ },
343
+ {
344
+ "default": 0.0,
345
+ "description": "Timestamp indicating when the grant was created.",
346
+ "name": "createdAt",
347
+ "synonyms": "creation time, created, date added",
348
+ "type": "number"
349
+ }
350
+ ],
351
+ "id": "ent_01M2HEYQZMYFHR14P4RKB46K51",
352
+ "name": "PermissionGrant",
353
+ "persistence": "persistent"
354
+ },
355
+ "id": "orb_01M2HEYQZME0WVSVJ3G64KQBJF",
356
+ "name": "PermissionMatrixOrbital",
357
+ "pages": [
358
+ {
359
+ "id": "pag_01M2HEYQZMA80XV7ZFHG4981XG",
360
+ "name": "PermissionMatrixPage",
361
+ "path": "/admin/permissions",
362
+ "traits": [
363
+ {
364
+ "ref": "PermissionMatrixAdmin",
365
+ "refId": "trt_01M2HEYQZMJ2XVG13CS09YSQZG"
366
+ },
367
+ {
368
+ "ref": "PermissionGrantCreate",
369
+ "refId": "trt_01M2JCDX8HQFZ924VC3E15FY0J"
370
+ },
371
+ {
372
+ "ref": "PermissionGrantEdit",
373
+ "refId": "trt_01M2JCDX8HHAZN1S4Q1QYN78H5"
374
+ },
375
+ {
376
+ "ref": "PermissionGrantPersistor",
377
+ "refId": "trt_01M2JCDX8HJFRR69J2HRX0450S"
378
+ },
379
+ {
380
+ "ref": "PermissionGrantQuery",
381
+ "refId": "trt_01M2HEYQZMAE7G04QDC54C9G1J"
382
+ }
383
+ ]
384
+ }
385
+ ],
386
+ "traits": [
387
+ {
388
+ "id": "trt_01M2HEYQZMA43G4PA24BEP3K3A",
389
+ "linkedEntity": "PermissionGrant",
390
+ "linkedEntityId": "ent_01M2HEYQZMYFHR14P4RKB46K51",
391
+ "name": "LoadingSpinner",
392
+ "ref": "Spinner.traits.SpinnerRender"
393
+ },
394
+ {
395
+ "config": {
396
+ "size": {
397
+ "default": "sm",
398
+ "type": "unknown"
399
+ }
400
+ },
401
+ "id": "trt_01M2HEYQZM4C5E4AARRCTKK9GC",
402
+ "linkedEntity": "PermissionGrant",
403
+ "linkedEntityId": "ent_01M2HEYQZMYFHR14P4RKB46K51",
404
+ "name": "ErrorSpinner",
405
+ "ref": "Spinner.traits.SpinnerRender"
406
+ },
407
+ {
408
+ "config": {
409
+ "color": {
410
+ "default": "muted",
411
+ "type": "unknown"
412
+ },
413
+ "content": {
414
+ "default": "Loading permission grants…",
415
+ "type": "unknown"
416
+ },
417
+ "variant": {
418
+ "default": "caption",
419
+ "type": "unknown"
420
+ }
421
+ },
422
+ "id": "trt_01M2HEYQZMVQRQFSVXKB1RVNR2",
423
+ "linkedEntity": "PermissionGrant",
424
+ "linkedEntityId": "ent_01M2HEYQZMYFHR14P4RKB46K51",
425
+ "name": "LoadingText",
426
+ "ref": "Typography.traits.TypographyRender"
427
+ },
428
+ {
429
+ "config": {
430
+ "name": {
431
+ "default": "shield-check",
432
+ "type": "unknown"
433
+ }
434
+ },
435
+ "id": "trt_01M2HEYQZMD1A2NASDVFHAH83A",
436
+ "linkedEntity": "PermissionGrant",
437
+ "linkedEntityId": "ent_01M2HEYQZMYFHR14P4RKB46K51",
438
+ "name": "ShieldCheckIcon",
439
+ "ref": "Icon.traits.IconRender"
440
+ },
441
+ {
442
+ "config": {
443
+ "content": {
444
+ "default": "Permission matrix",
445
+ "type": "unknown"
446
+ },
447
+ "variant": {
448
+ "default": "h3",
449
+ "type": "unknown"
450
+ }
451
+ },
452
+ "id": "trt_01M2HEYQZMBC4GABK9BV5Z4PVH",
453
+ "linkedEntity": "PermissionGrant",
454
+ "linkedEntityId": "ent_01M2HEYQZMYFHR14P4RKB46K51",
455
+ "name": "PermissionMatrixTitle",
456
+ "ref": "Typography.traits.TypographyRender"
457
+ },
458
+ {
459
+ "id": "trt_01M2HEYQZM938N2V00VDF2K0XJ",
460
+ "linkedEntity": "PermissionGrant",
461
+ "linkedEntityId": "ent_01M2HEYQZMYFHR14P4RKB46K51",
462
+ "name": "GrantDivider",
463
+ "ref": "Divider.traits.DividerRender"
464
+ },
465
+ {
466
+ "config": {
467
+ "message": {
468
+ "default": "@payload.error",
469
+ "type": "unknown"
470
+ },
471
+ "variant": {
472
+ "default": "error",
473
+ "type": "unknown"
474
+ }
475
+ },
476
+ "id": "trt_01M2HEYQZM136RV41RKCDE1XVT",
477
+ "linkedEntity": "PermissionGrant",
478
+ "linkedEntityId": "ent_01M2HEYQZMYFHR14P4RKB46K51",
479
+ "name": "ErrorAlert",
480
+ "ref": "Alert.traits.AlertRender"
481
+ },
482
+ {
483
+ "capabilities": [
484
+ "access"
485
+ ],
486
+ "category": "interaction",
487
+ "effectRow": [
488
+ {
489
+ "kind": "fetch",
490
+ "resource": "PermissionGrant"
491
+ },
492
+ {
493
+ "kind": "render-ui",
494
+ "resource": "main"
495
+ }
496
+ ],
497
+ "emits": [
498
+ {
499
+ "description": "Requests the create-grant form (the create modal listens).",
500
+ "event": "NEW",
501
+ "eventId": "evt_01M2HEYQZMNXE0Q2CRE9GJDF8C",
502
+ "synonyms": "add grant, new permission, create grant",
503
+ "tier": "domain"
504
+ },
505
+ {
506
+ "description": "Requests the edit form for a grant row (the edit modal listens).",
507
+ "event": "EDIT",
508
+ "eventId": "evt_01M2HEYQZMXWXQ5M0JAD911R8X",
509
+ "payloadSchema": [
510
+ {
511
+ "name": "id",
512
+ "required": true,
513
+ "type": "string"
514
+ },
515
+ {
516
+ "entity": "PermissionGrant",
517
+ "name": "row",
518
+ "properties": [
519
+ {
520
+ "name": "id",
521
+ "required": true,
522
+ "type": "string"
523
+ },
524
+ {
525
+ "name": "workspaceId",
526
+ "type": "string"
527
+ },
528
+ {
529
+ "name": "role",
530
+ "required": true,
531
+ "type": "string"
532
+ },
533
+ {
534
+ "name": "module",
535
+ "required": true,
536
+ "type": "string"
537
+ },
538
+ {
539
+ "name": "canReadFinance",
540
+ "type": "boolean"
541
+ },
542
+ {
543
+ "name": "canSeeOthersHours",
544
+ "type": "boolean"
545
+ },
546
+ {
547
+ "name": "canSeeMargins",
548
+ "type": "boolean"
549
+ },
550
+ {
551
+ "name": "createdAt",
552
+ "type": "number"
553
+ }
554
+ ],
555
+ "type": "object"
556
+ }
557
+ ],
558
+ "synonyms": "modify grant, change permission, update grant",
559
+ "tier": "domain"
560
+ },
561
+ {
562
+ "description": "Requests deletion of a grant row (the persistor listens; adminRoles-guarded there).",
563
+ "event": "DELETE",
564
+ "eventId": "evt_01M2HEYQZMWK4TZVSSZS3093ZG",
565
+ "payloadSchema": [
566
+ {
567
+ "name": "id",
568
+ "required": true,
569
+ "type": "string"
570
+ },
571
+ {
572
+ "entity": "PermissionGrant",
573
+ "name": "row",
574
+ "properties": [
575
+ {
576
+ "name": "id",
577
+ "required": true,
578
+ "type": "string"
579
+ },
580
+ {
581
+ "name": "workspaceId",
582
+ "type": "string"
583
+ },
584
+ {
585
+ "name": "role",
586
+ "required": true,
587
+ "type": "string"
588
+ },
589
+ {
590
+ "name": "module",
591
+ "required": true,
592
+ "type": "string"
593
+ },
594
+ {
595
+ "name": "canReadFinance",
596
+ "type": "boolean"
597
+ },
598
+ {
599
+ "name": "canSeeOthersHours",
600
+ "type": "boolean"
601
+ },
602
+ {
603
+ "name": "canSeeMargins",
604
+ "type": "boolean"
605
+ },
606
+ {
607
+ "name": "createdAt",
608
+ "type": "number"
609
+ }
610
+ ],
611
+ "type": "object"
612
+ }
613
+ ],
614
+ "synonyms": "remove grant, revoke permission, delete grant",
615
+ "tier": "domain"
616
+ },
617
+ {
618
+ "description": "Indicates the permission-grant collection has been successfully loaded.",
619
+ "event": "PermissionGrantLoaded",
620
+ "eventId": "evt_01M2HEYQZMVNZ5YTXXR38WPM6R",
621
+ "payloadSchema": [
622
+ {
623
+ "entity": "PermissionGrant",
624
+ "name": "data",
625
+ "properties": [
626
+ {
627
+ "name": "id",
628
+ "required": true,
629
+ "type": "string"
630
+ },
631
+ {
632
+ "name": "workspaceId",
633
+ "type": "string"
634
+ },
635
+ {
636
+ "name": "role",
637
+ "required": true,
638
+ "type": "string"
639
+ },
640
+ {
641
+ "name": "module",
642
+ "required": true,
643
+ "type": "string"
644
+ },
645
+ {
646
+ "name": "canReadFinance",
647
+ "type": "boolean"
648
+ },
649
+ {
650
+ "name": "canSeeOthersHours",
651
+ "type": "boolean"
652
+ },
653
+ {
654
+ "name": "canSeeMargins",
655
+ "type": "boolean"
656
+ },
657
+ {
658
+ "name": "createdAt",
659
+ "type": "number"
660
+ }
661
+ ],
662
+ "type": "[object]"
663
+ }
664
+ ],
665
+ "synonyms": "loaded, fetched, retrieved",
666
+ "tier": "internal"
667
+ },
668
+ {
669
+ "description": "Indicates failure to load the permission-grant collection.",
670
+ "event": "PermissionGrantLoadFailed",
671
+ "eventId": "evt_01M2HEYQZM9DM2K7FGY74WKBBT",
672
+ "payloadSchema": [
673
+ {
674
+ "name": "error",
675
+ "type": "string"
676
+ },
677
+ {
678
+ "name": "code",
679
+ "type": "string"
680
+ }
681
+ ],
682
+ "synonyms": "load error, failed load, request failure",
683
+ "tier": "internal"
684
+ }
685
+ ],
686
+ "entityContract": {
687
+ "provides": [],
688
+ "requires": []
689
+ },
690
+ "entityRebindable": true,
691
+ "entityRefIds": {
692
+ "PermissionGrant": "ent_01M2HEYQZMYFHR14P4RKB46K51"
693
+ },
694
+ "id": "trt_01M2HEYQZMJ2XVG13CS09YSQZG",
695
+ "linkedEntity": "PermissionGrant",
696
+ "linkedEntityId": "ent_01M2HEYQZMYFHR14P4RKB46K51",
697
+ "listens": [
698
+ {
699
+ "event": "PermissionGrantSaved",
700
+ "eventId": "evt_01M2JCDX8H82D6D1V7RTZ6CMY1",
701
+ "source": {
702
+ "kind": "trait",
703
+ "trait": "PermissionGrantPersistor",
704
+ "traitId": "trt_01M2JCDX8HJFRR69J2HRX0450S"
705
+ },
706
+ "triggers": "INIT",
707
+ "triggersId": "evt_01M2HEYQZMEN5KMN1S2P458NWV"
708
+ },
709
+ {
710
+ "event": "PermissionGrantDeleted",
711
+ "eventId": "evt_01M2JCDX8HYHAHKQHTFSBAF5MN",
712
+ "source": {
713
+ "kind": "trait",
714
+ "trait": "PermissionGrantPersistor",
715
+ "traitId": "trt_01M2JCDX8HJFRR69J2HRX0450S"
716
+ },
717
+ "triggers": "INIT",
718
+ "triggersId": "evt_01M2HEYQZMEN5KMN1S2P458NWV"
719
+ }
720
+ ],
721
+ "name": "PermissionMatrixAdmin",
722
+ "scope": "collection",
723
+ "stateMachine": {
724
+ "events": [
725
+ {
726
+ "id": "evt_01M2HEYQZMEN5KMN1S2P458NWV",
727
+ "key": "INIT",
728
+ "name": "Initialize"
729
+ },
730
+ {
731
+ "description": "Indicates the permission-grant collection has been successfully loaded.",
732
+ "id": "evt_01M2HEYQZMVNZ5YTXXR38WPM6R",
733
+ "key": "PermissionGrantLoaded",
734
+ "name": "PermissionGrant loaded",
735
+ "payloadSchema": [
736
+ {
737
+ "entity": "PermissionGrant",
738
+ "name": "data",
739
+ "properties": [
740
+ {
741
+ "name": "id",
742
+ "required": true,
743
+ "type": "string"
744
+ },
745
+ {
746
+ "name": "workspaceId",
747
+ "type": "string"
748
+ },
749
+ {
750
+ "name": "role",
751
+ "required": true,
752
+ "type": "string"
753
+ },
754
+ {
755
+ "name": "module",
756
+ "required": true,
757
+ "type": "string"
758
+ },
759
+ {
760
+ "name": "canReadFinance",
761
+ "type": "boolean"
762
+ },
763
+ {
764
+ "name": "canSeeOthersHours",
765
+ "type": "boolean"
766
+ },
767
+ {
768
+ "name": "canSeeMargins",
769
+ "type": "boolean"
770
+ },
771
+ {
772
+ "name": "createdAt",
773
+ "type": "number"
774
+ }
775
+ ],
776
+ "type": "[object]"
777
+ }
778
+ ],
779
+ "synonyms": "loaded, fetched, retrieved",
780
+ "tier": "internal"
781
+ },
782
+ {
783
+ "description": "Indicates failure to load the permission-grant collection.",
784
+ "id": "evt_01M2HEYQZM9DM2K7FGY74WKBBT",
785
+ "key": "PermissionGrantLoadFailed",
786
+ "name": "PermissionGrant load failed",
787
+ "payloadSchema": [
788
+ {
789
+ "name": "error",
790
+ "type": "string"
791
+ },
792
+ {
793
+ "name": "code",
794
+ "type": "string"
795
+ }
796
+ ],
797
+ "synonyms": "load error, failed load, request failure",
798
+ "tier": "internal"
799
+ },
800
+ {
801
+ "description": "Requests the create-grant form (the create modal listens).",
802
+ "id": "evt_01M2HEYQZMNXE0Q2CRE9GJDF8C",
803
+ "key": "NEW",
804
+ "name": "New",
805
+ "synonyms": "add grant, new permission, create grant",
806
+ "tier": "domain"
807
+ },
808
+ {
809
+ "description": "Requests the edit form for a grant row (the edit modal listens).",
810
+ "id": "evt_01M2HEYQZMXWXQ5M0JAD911R8X",
811
+ "key": "EDIT",
812
+ "name": "Edit",
813
+ "payloadSchema": [
814
+ {
815
+ "name": "id",
816
+ "required": true,
817
+ "type": "string"
818
+ },
819
+ {
820
+ "entity": "PermissionGrant",
821
+ "name": "row",
822
+ "properties": [
823
+ {
824
+ "name": "id",
825
+ "required": true,
826
+ "type": "string"
827
+ },
828
+ {
829
+ "name": "workspaceId",
830
+ "type": "string"
831
+ },
832
+ {
833
+ "name": "role",
834
+ "required": true,
835
+ "type": "string"
836
+ },
837
+ {
838
+ "name": "module",
839
+ "required": true,
840
+ "type": "string"
841
+ },
842
+ {
843
+ "name": "canReadFinance",
844
+ "type": "boolean"
845
+ },
846
+ {
847
+ "name": "canSeeOthersHours",
848
+ "type": "boolean"
849
+ },
850
+ {
851
+ "name": "canSeeMargins",
852
+ "type": "boolean"
853
+ },
854
+ {
855
+ "name": "createdAt",
856
+ "type": "number"
857
+ }
858
+ ],
859
+ "type": "object"
860
+ }
861
+ ],
862
+ "synonyms": "modify grant, change permission, update grant",
863
+ "tier": "domain"
864
+ },
865
+ {
866
+ "description": "Requests deletion of a grant row (the persistor listens; adminRoles-guarded there).",
867
+ "id": "evt_01M2HEYQZMWK4TZVSSZS3093ZG",
868
+ "key": "DELETE",
869
+ "name": "Delete",
870
+ "payloadSchema": [
871
+ {
872
+ "name": "id",
873
+ "required": true,
874
+ "type": "string"
875
+ },
876
+ {
877
+ "entity": "PermissionGrant",
878
+ "name": "row",
879
+ "properties": [
880
+ {
881
+ "name": "id",
882
+ "required": true,
883
+ "type": "string"
884
+ },
885
+ {
886
+ "name": "workspaceId",
887
+ "type": "string"
888
+ },
889
+ {
890
+ "name": "role",
891
+ "required": true,
892
+ "type": "string"
893
+ },
894
+ {
895
+ "name": "module",
896
+ "required": true,
897
+ "type": "string"
898
+ },
899
+ {
900
+ "name": "canReadFinance",
901
+ "type": "boolean"
902
+ },
903
+ {
904
+ "name": "canSeeOthersHours",
905
+ "type": "boolean"
906
+ },
907
+ {
908
+ "name": "canSeeMargins",
909
+ "type": "boolean"
910
+ },
911
+ {
912
+ "name": "createdAt",
913
+ "type": "number"
914
+ }
915
+ ],
916
+ "type": "object"
917
+ }
918
+ ],
919
+ "synonyms": "remove grant, revoke permission, delete grant",
920
+ "tier": "domain"
921
+ }
922
+ ],
923
+ "states": [
924
+ {
925
+ "isInitial": true,
926
+ "name": "loading"
927
+ },
928
+ {
929
+ "name": "listing"
930
+ },
931
+ {
932
+ "name": "error"
933
+ }
934
+ ],
935
+ "transitions": [
936
+ {
937
+ "effects": [
938
+ [
939
+ "fetch",
940
+ "PermissionGrant",
941
+ {
942
+ "emit": {
943
+ "failure": "PermissionGrantLoadFailed",
944
+ "success": "PermissionGrantLoaded"
945
+ }
946
+ }
947
+ ],
948
+ [
949
+ "render-ui",
950
+ "main",
951
+ {
952
+ "align": "center",
953
+ "children": [
954
+ "@trait.LoadingSpinner",
955
+ "@trait.LoadingText"
956
+ ],
957
+ "className": "py-12",
958
+ "direction": "vertical",
959
+ "gap": "md",
960
+ "type": "stack"
961
+ }
962
+ ]
963
+ ],
964
+ "event": "INIT",
965
+ "eventId": "evt_01M2HEYQZMEN5KMN1S2P458NWV",
966
+ "from": "loading",
967
+ "to": "loading"
968
+ },
969
+ {
970
+ "effects": [
971
+ [
972
+ "render-ui",
973
+ "main",
974
+ {
975
+ "children": [
976
+ {
977
+ "align": "center",
978
+ "children": [
979
+ {
980
+ "align": "center",
981
+ "children": [
982
+ "@trait.ShieldCheckIcon",
983
+ "@trait.PermissionMatrixTitle"
984
+ ],
985
+ "direction": "horizontal",
986
+ "gap": "sm",
987
+ "type": "stack"
988
+ },
989
+ {
990
+ "action": "NEW",
991
+ "icon": "plus",
992
+ "label": "New grant",
993
+ "type": "button",
994
+ "variant": "primary"
995
+ }
996
+ ],
997
+ "direction": "horizontal",
998
+ "gap": "sm",
999
+ "justify": "between",
1000
+ "type": "stack"
1001
+ },
1002
+ "@trait.GrantDivider",
1003
+ {
1004
+ "cols": 1.0,
1005
+ "entity": "@payload.data",
1006
+ "fields": [
1007
+ {
1008
+ "label": "Role",
1009
+ "name": "role",
1010
+ "variant": "h4"
1011
+ },
1012
+ {
1013
+ "label": "Module",
1014
+ "name": "module",
1015
+ "variant": "badge"
1016
+ },
1017
+ {
1018
+ "label": "Workspace",
1019
+ "name": "workspaceId",
1020
+ "variant": "caption"
1021
+ },
1022
+ {
1023
+ "format": "boolean",
1024
+ "label": "Read finance",
1025
+ "name": "canReadFinance",
1026
+ "variant": "caption"
1027
+ },
1028
+ {
1029
+ "format": "boolean",
1030
+ "label": "Others' hours",
1031
+ "name": "canSeeOthersHours",
1032
+ "variant": "caption"
1033
+ },
1034
+ {
1035
+ "format": "boolean",
1036
+ "label": "Margins",
1037
+ "name": "canSeeMargins",
1038
+ "variant": "caption"
1039
+ }
1040
+ ],
1041
+ "gap": "sm",
1042
+ "itemActions": [
1043
+ {
1044
+ "event": "EDIT",
1045
+ "icon": "pencil",
1046
+ "label": "Edit",
1047
+ "variant": "ghost"
1048
+ },
1049
+ {
1050
+ "event": "DELETE",
1051
+ "icon": "trash",
1052
+ "label": "Delete",
1053
+ "variant": "danger"
1054
+ }
1055
+ ],
1056
+ "type": "data-grid"
1057
+ }
1058
+ ],
1059
+ "direction": "vertical",
1060
+ "gap": "md",
1061
+ "type": "stack"
1062
+ }
1063
+ ]
1064
+ ],
1065
+ "event": "PermissionGrantLoaded",
1066
+ "eventId": "evt_01M2HEYQZMVNZ5YTXXR38WPM6R",
1067
+ "from": "loading",
1068
+ "to": "listing"
1069
+ },
1070
+ {
1071
+ "effects": [
1072
+ [
1073
+ "render-ui",
1074
+ "main",
1075
+ {
1076
+ "children": [
1077
+ "@trait.ErrorAlert"
1078
+ ],
1079
+ "type": "stack"
1080
+ }
1081
+ ]
1082
+ ],
1083
+ "event": "PermissionGrantLoadFailed",
1084
+ "eventId": "evt_01M2HEYQZM9DM2K7FGY74WKBBT",
1085
+ "from": "loading",
1086
+ "to": "error"
1087
+ },
1088
+ {
1089
+ "effects": [
1090
+ [
1091
+ "fetch",
1092
+ "PermissionGrant",
1093
+ {
1094
+ "emit": {
1095
+ "failure": "PermissionGrantLoadFailed",
1096
+ "success": "PermissionGrantLoaded"
1097
+ }
1098
+ }
1099
+ ]
1100
+ ],
1101
+ "event": "INIT",
1102
+ "eventId": "evt_01M2HEYQZMEN5KMN1S2P458NWV",
1103
+ "from": "listing",
1104
+ "to": "loading"
1105
+ },
1106
+ {
1107
+ "effects": [
1108
+ [
1109
+ "fetch",
1110
+ "PermissionGrant",
1111
+ {
1112
+ "emit": {
1113
+ "failure": "PermissionGrantLoadFailed",
1114
+ "success": "PermissionGrantLoaded"
1115
+ }
1116
+ }
1117
+ ],
1118
+ [
1119
+ "render-ui",
1120
+ "main",
1121
+ {
1122
+ "align": "center",
1123
+ "children": [
1124
+ "@trait.ErrorSpinner"
1125
+ ],
1126
+ "type": "stack"
1127
+ }
1128
+ ]
1129
+ ],
1130
+ "event": "INIT",
1131
+ "eventId": "evt_01M2HEYQZMEN5KMN1S2P458NWV",
1132
+ "from": "error",
1133
+ "to": "loading"
1134
+ }
1135
+ ]
1136
+ },
1137
+ "traitEmbedIds": {
1138
+ "ErrorAlert": "trt_01M2HEYQZM136RV41RKCDE1XVT",
1139
+ "ErrorSpinner": "trt_01M2HEYQZM4C5E4AARRCTKK9GC",
1140
+ "GrantDivider": "trt_01M2HEYQZM938N2V00VDF2K0XJ",
1141
+ "LoadingSpinner": "trt_01M2HEYQZMA43G4PA24BEP3K3A",
1142
+ "LoadingText": "trt_01M2HEYQZMVQRQFSVXKB1RVNR2",
1143
+ "PermissionMatrixTitle": "trt_01M2HEYQZMBC4GABK9BV5Z4PVH",
1144
+ "ShieldCheckIcon": "trt_01M2HEYQZMD1A2NASDVFHAH83A"
1145
+ }
1146
+ },
1147
+ {
1148
+ "config": {
1149
+ "fields": {
1150
+ "default": [
1151
+ "workspaceId",
1152
+ "role",
1153
+ "module",
1154
+ "canReadFinance",
1155
+ "canSeeOthersHours",
1156
+ "canSeeMargins"
1157
+ ],
1158
+ "type": "unknown"
1159
+ },
1160
+ "icon": {
1161
+ "default": "plus-circle",
1162
+ "type": "unknown"
1163
+ },
1164
+ "mode": {
1165
+ "default": "create",
1166
+ "type": "unknown"
1167
+ },
1168
+ "title": {
1169
+ "default": "Create grant",
1170
+ "type": "unknown"
1171
+ }
1172
+ },
1173
+ "events": {
1174
+ "OPEN": "NEW",
1175
+ "SAVE": "GRANT_CREATED"
1176
+ },
1177
+ "id": "trt_01M2JCDX8HQFZ924VC3E15FY0J",
1178
+ "linkedEntity": "PermissionGrant",
1179
+ "linkedEntityId": "ent_01M2HEYQZMYFHR14P4RKB46K51",
1180
+ "listens": [
1181
+ {
1182
+ "event": "NEW",
1183
+ "source": {
1184
+ "kind": "trait",
1185
+ "trait": "PermissionMatrixAdmin"
1186
+ },
1187
+ "triggers": "NEW"
1188
+ }
1189
+ ],
1190
+ "name": "PermissionGrantCreate",
1191
+ "ref": "Modal.traits.ModalRecordModal"
1192
+ },
1193
+ {
1194
+ "config": {
1195
+ "fields": {
1196
+ "default": [
1197
+ "workspaceId",
1198
+ "role",
1199
+ "module",
1200
+ "canReadFinance",
1201
+ "canSeeOthersHours",
1202
+ "canSeeMargins"
1203
+ ],
1204
+ "type": "unknown"
1205
+ },
1206
+ "icon": {
1207
+ "default": "pencil",
1208
+ "type": "unknown"
1209
+ },
1210
+ "mode": {
1211
+ "default": "edit",
1212
+ "type": "unknown"
1213
+ },
1214
+ "title": {
1215
+ "default": "Edit grant",
1216
+ "type": "unknown"
1217
+ }
1218
+ },
1219
+ "events": {
1220
+ "OPEN": "EDIT",
1221
+ "SAVE": "GRANT_UPDATED"
1222
+ },
1223
+ "id": "trt_01M2JCDX8HHAZN1S4Q1QYN78H5",
1224
+ "linkedEntity": "PermissionGrant",
1225
+ "linkedEntityId": "ent_01M2HEYQZMYFHR14P4RKB46K51",
1226
+ "listens": [
1227
+ {
1228
+ "event": "EDIT",
1229
+ "source": {
1230
+ "kind": "trait",
1231
+ "trait": "PermissionMatrixAdmin"
1232
+ },
1233
+ "triggers": "EDIT"
1234
+ }
1235
+ ],
1236
+ "name": "PermissionGrantEdit",
1237
+ "ref": "Modal.traits.ModalRecordModal"
1238
+ },
1239
+ {
1240
+ "capabilities": [
1241
+ "access"
1242
+ ],
1243
+ "category": "lifecycle",
1244
+ "config": {
1245
+ "adminRoles": {
1246
+ "default": [],
1247
+ "description": "Roles eligible to create, edit, or delete grants. ENFORCED by the DO_CREATE/DO_UPDATE/DO_DELETE transition guards: a viewer whose @user.role is not listed cannot fire a write, from the form submit or from the bus. Empty = every signed-in viewer may manage grants (ungated). Mounting the page is the opt-in — there is deliberately no separate enable flag (a default-off flag made the whole page's affordances dead on a fresh mount).",
1248
+ "items": {
1249
+ "type": "string"
1250
+ },
1251
+ "label": "Who can manage grants?",
1252
+ "synonyms": "admin roles, permission managers, who edits permissions, grant admins, permission matrix, role permissions, capability matrix, permission grants, access matrix, manage permissions",
1253
+ "tier": "policy",
1254
+ "type": "[string]"
1255
+ }
1256
+ },
1257
+ "effectRow": [
1258
+ {
1259
+ "kind": "persist",
1260
+ "resource": "PermissionGrant"
1261
+ },
1262
+ {
1263
+ "kind": "render-ui",
1264
+ "resource": "toast"
1265
+ }
1266
+ ],
1267
+ "emits": [
1268
+ {
1269
+ "description": "Signals that a permission grant has been persisted (create / update); carries the persisted row's id.",
1270
+ "event": "PermissionGrantSaved",
1271
+ "eventId": "evt_01M2JCDX8H82D6D1V7RTZ6CMY1",
1272
+ "payloadSchema": [
1273
+ {
1274
+ "name": "id",
1275
+ "required": true,
1276
+ "type": "string"
1277
+ }
1278
+ ],
1279
+ "scope": "external",
1280
+ "synonyms": "saved, created, updated, persisted",
1281
+ "tier": "domain"
1282
+ },
1283
+ {
1284
+ "description": "Indicates a failure to persist a permission grant.",
1285
+ "event": "PermissionGrantSaveFailed",
1286
+ "eventId": "evt_01M2JCDX8HFPEBTZF91HFFKT10",
1287
+ "payloadSchema": [
1288
+ {
1289
+ "name": "error",
1290
+ "type": "string"
1291
+ },
1292
+ {
1293
+ "name": "code",
1294
+ "type": "string"
1295
+ }
1296
+ ],
1297
+ "scope": "external",
1298
+ "synonyms": "save error, failed save, persist failure",
1299
+ "tier": "internal"
1300
+ },
1301
+ {
1302
+ "description": "Signals that a permission grant has been deleted.",
1303
+ "event": "PermissionGrantDeleted",
1304
+ "eventId": "evt_01M2JCDX8HYHAHKQHTFSBAF5MN",
1305
+ "payloadSchema": [
1306
+ {
1307
+ "name": "id",
1308
+ "type": "string"
1309
+ },
1310
+ {
1311
+ "name": "deleted",
1312
+ "type": "boolean"
1313
+ }
1314
+ ],
1315
+ "scope": "external",
1316
+ "synonyms": "deleted, removed, revoked",
1317
+ "tier": "domain"
1318
+ },
1319
+ {
1320
+ "description": "Indicates a failure to delete a permission grant.",
1321
+ "event": "PermissionGrantDeleteFailed",
1322
+ "eventId": "evt_01M2JCDX8HDS4691JHRXJ401PT",
1323
+ "payloadSchema": [
1324
+ {
1325
+ "name": "error",
1326
+ "type": "string"
1327
+ },
1328
+ {
1329
+ "name": "code",
1330
+ "type": "string"
1331
+ }
1332
+ ],
1333
+ "scope": "external",
1334
+ "synonyms": "delete error, failed delete",
1335
+ "tier": "internal"
1336
+ }
1337
+ ],
1338
+ "entityRefIds": {
1339
+ "PermissionGrant": "ent_01M2HEYQZMYFHR14P4RKB46K51"
1340
+ },
1341
+ "id": "trt_01M2JCDX8HJFRR69J2HRX0450S",
1342
+ "linkedEntity": "PermissionGrant",
1343
+ "linkedEntityId": "ent_01M2HEYQZMYFHR14P4RKB46K51",
1344
+ "listens": [
1345
+ {
1346
+ "event": "GRANT_CREATED",
1347
+ "source": {
1348
+ "kind": "trait",
1349
+ "trait": "PermissionGrantCreate",
1350
+ "traitId": "trt_01M2JCDX8HQFZ924VC3E15FY0J"
1351
+ },
1352
+ "triggers": "DO_CREATE",
1353
+ "triggersId": "evt_01M2JCDX8HSZYBRKTW58856G6X"
1354
+ },
1355
+ {
1356
+ "event": "GRANT_UPDATED",
1357
+ "source": {
1358
+ "kind": "trait",
1359
+ "trait": "PermissionGrantEdit",
1360
+ "traitId": "trt_01M2JCDX8HHAZN1S4Q1QYN78H5"
1361
+ },
1362
+ "triggers": "DO_UPDATE",
1363
+ "triggersId": "evt_01M2JCDX8HG5S847YTMPZ2NMPN"
1364
+ },
1365
+ {
1366
+ "event": "DELETE",
1367
+ "eventId": "evt_01M2HEYQZMWK4TZVSSZS3093ZG",
1368
+ "source": {
1369
+ "kind": "trait",
1370
+ "trait": "PermissionMatrixAdmin",
1371
+ "traitId": "trt_01M2HEYQZMJ2XVG13CS09YSQZG"
1372
+ },
1373
+ "triggers": "DO_DELETE",
1374
+ "triggersId": "evt_01M2JCDX8HH16NM9P3NDPX5Y31"
1375
+ }
1376
+ ],
1377
+ "name": "PermissionGrantPersistor",
1378
+ "scope": "instance",
1379
+ "stateMachine": {
1380
+ "events": [
1381
+ {
1382
+ "id": "evt_01M2JCDX8HSG3NXK4ECZY8FH33",
1383
+ "key": "INIT",
1384
+ "name": "Initialize"
1385
+ },
1386
+ {
1387
+ "description": "Indicates a request to create a grant row.",
1388
+ "id": "evt_01M2JCDX8HSZYBRKTW58856G6X",
1389
+ "key": "DO_CREATE",
1390
+ "name": "Do Create",
1391
+ "payloadSchema": [
1392
+ {
1393
+ "entity": "PermissionGrant",
1394
+ "name": "data",
1395
+ "properties": [
1396
+ {
1397
+ "name": "id",
1398
+ "required": true,
1399
+ "type": "string"
1400
+ },
1401
+ {
1402
+ "name": "workspaceId",
1403
+ "type": "string"
1404
+ },
1405
+ {
1406
+ "name": "role",
1407
+ "required": true,
1408
+ "type": "string"
1409
+ },
1410
+ {
1411
+ "name": "module",
1412
+ "required": true,
1413
+ "type": "string"
1414
+ },
1415
+ {
1416
+ "name": "canReadFinance",
1417
+ "type": "boolean"
1418
+ },
1419
+ {
1420
+ "name": "canSeeOthersHours",
1421
+ "type": "boolean"
1422
+ },
1423
+ {
1424
+ "name": "canSeeMargins",
1425
+ "type": "boolean"
1426
+ },
1427
+ {
1428
+ "name": "createdAt",
1429
+ "type": "number"
1430
+ }
1431
+ ],
1432
+ "required": true,
1433
+ "type": "object"
1434
+ }
1435
+ ],
1436
+ "synonyms": "add, new, insert",
1437
+ "tier": "domain"
1438
+ },
1439
+ {
1440
+ "description": "Indicates a grant row has been modified.",
1441
+ "id": "evt_01M2JCDX8HG5S847YTMPZ2NMPN",
1442
+ "key": "DO_UPDATE",
1443
+ "name": "Do Update",
1444
+ "payloadSchema": [
1445
+ {
1446
+ "entity": "PermissionGrant",
1447
+ "name": "data",
1448
+ "properties": [
1449
+ {
1450
+ "name": "id",
1451
+ "required": true,
1452
+ "type": "string"
1453
+ },
1454
+ {
1455
+ "name": "workspaceId",
1456
+ "type": "string"
1457
+ },
1458
+ {
1459
+ "name": "role",
1460
+ "required": true,
1461
+ "type": "string"
1462
+ },
1463
+ {
1464
+ "name": "module",
1465
+ "required": true,
1466
+ "type": "string"
1467
+ },
1468
+ {
1469
+ "name": "canReadFinance",
1470
+ "type": "boolean"
1471
+ },
1472
+ {
1473
+ "name": "canSeeOthersHours",
1474
+ "type": "boolean"
1475
+ },
1476
+ {
1477
+ "name": "canSeeMargins",
1478
+ "type": "boolean"
1479
+ },
1480
+ {
1481
+ "name": "createdAt",
1482
+ "type": "number"
1483
+ }
1484
+ ],
1485
+ "required": true,
1486
+ "type": "object"
1487
+ }
1488
+ ],
1489
+ "synonyms": "modify, update, change",
1490
+ "tier": "domain"
1491
+ },
1492
+ {
1493
+ "description": "Indicates a request to delete a grant row.",
1494
+ "id": "evt_01M2JCDX8HH16NM9P3NDPX5Y31",
1495
+ "key": "DO_DELETE",
1496
+ "name": "Do Delete",
1497
+ "payloadSchema": [
1498
+ {
1499
+ "name": "id",
1500
+ "required": true,
1501
+ "type": "string"
1502
+ }
1503
+ ],
1504
+ "synonyms": "remove, discard, erase",
1505
+ "tier": "domain"
1506
+ },
1507
+ {
1508
+ "description": "Indicates a failure to persist a permission grant.",
1509
+ "id": "evt_01M2JCDX8HFPEBTZF91HFFKT10",
1510
+ "key": "PermissionGrantSaveFailed",
1511
+ "name": "PermissionGrant save failed",
1512
+ "payloadSchema": [
1513
+ {
1514
+ "name": "error",
1515
+ "type": "string"
1516
+ },
1517
+ {
1518
+ "name": "code",
1519
+ "type": "string"
1520
+ }
1521
+ ],
1522
+ "synonyms": "save error, failed save, persist failure",
1523
+ "tier": "internal"
1524
+ },
1525
+ {
1526
+ "description": "Indicates a failure to delete a permission grant.",
1527
+ "id": "evt_01M2JCDX8HDS4691JHRXJ401PT",
1528
+ "key": "PermissionGrantDeleteFailed",
1529
+ "name": "PermissionGrant delete failed",
1530
+ "payloadSchema": [
1531
+ {
1532
+ "name": "error",
1533
+ "type": "string"
1534
+ },
1535
+ {
1536
+ "name": "code",
1537
+ "type": "string"
1538
+ }
1539
+ ],
1540
+ "synonyms": "delete error, failed delete",
1541
+ "tier": "internal"
1542
+ },
1543
+ {
1544
+ "description": "Signals that a permission grant has been persisted (create / update); carries the persisted row's id.",
1545
+ "id": "evt_01M2JCDX8H82D6D1V7RTZ6CMY1",
1546
+ "key": "PermissionGrantSaved",
1547
+ "name": "PermissionGrant saved",
1548
+ "payloadSchema": [
1549
+ {
1550
+ "name": "id",
1551
+ "required": true,
1552
+ "type": "string"
1553
+ }
1554
+ ],
1555
+ "synonyms": "saved, created, updated, persisted",
1556
+ "tier": "domain"
1557
+ },
1558
+ {
1559
+ "description": "Signals that a permission grant has been deleted.",
1560
+ "id": "evt_01M2JCDX8HYHAHKQHTFSBAF5MN",
1561
+ "key": "PermissionGrantDeleted",
1562
+ "name": "PermissionGrant deleted",
1563
+ "payloadSchema": [
1564
+ {
1565
+ "name": "id",
1566
+ "type": "string"
1567
+ },
1568
+ {
1569
+ "name": "deleted",
1570
+ "type": "boolean"
1571
+ }
1572
+ ],
1573
+ "synonyms": "deleted, removed, revoked",
1574
+ "tier": "domain"
1575
+ }
1576
+ ],
1577
+ "states": [
1578
+ {
1579
+ "isInitial": true,
1580
+ "name": "idle"
1581
+ }
1582
+ ],
1583
+ "transitions": [
1584
+ {
1585
+ "event": "INIT",
1586
+ "eventId": "evt_01M2JCDX8HSG3NXK4ECZY8FH33",
1587
+ "from": "idle",
1588
+ "to": "idle"
1589
+ },
1590
+ {
1591
+ "effects": [
1592
+ [
1593
+ "persist",
1594
+ "create",
1595
+ "PermissionGrant",
1596
+ "@payload.data",
1597
+ {
1598
+ "emit": {
1599
+ "failure": "PermissionGrantSaveFailed",
1600
+ "success": "PermissionGrantSaved"
1601
+ }
1602
+ }
1603
+ ]
1604
+ ],
1605
+ "event": "DO_CREATE",
1606
+ "eventId": "evt_01M2JCDX8HSZYBRKTW58856G6X",
1607
+ "from": "idle",
1608
+ "guard": [
1609
+ "or",
1610
+ [
1611
+ "=",
1612
+ [
1613
+ "array/len",
1614
+ "@config.adminRoles"
1615
+ ],
1616
+ 0.0
1617
+ ],
1618
+ [
1619
+ "array/includes",
1620
+ "@config.adminRoles",
1621
+ "@user.role"
1622
+ ]
1623
+ ],
1624
+ "to": "idle"
1625
+ },
1626
+ {
1627
+ "effects": [
1628
+ [
1629
+ "persist",
1630
+ "update",
1631
+ "PermissionGrant",
1632
+ "@payload.data",
1633
+ {
1634
+ "emit": {
1635
+ "failure": "PermissionGrantSaveFailed",
1636
+ "success": "PermissionGrantSaved"
1637
+ }
1638
+ }
1639
+ ]
1640
+ ],
1641
+ "event": "DO_UPDATE",
1642
+ "eventId": "evt_01M2JCDX8HG5S847YTMPZ2NMPN",
1643
+ "from": "idle",
1644
+ "guard": [
1645
+ "or",
1646
+ [
1647
+ "=",
1648
+ [
1649
+ "array/len",
1650
+ "@config.adminRoles"
1651
+ ],
1652
+ 0.0
1653
+ ],
1654
+ [
1655
+ "array/includes",
1656
+ "@config.adminRoles",
1657
+ "@user.role"
1658
+ ]
1659
+ ],
1660
+ "to": "idle"
1661
+ },
1662
+ {
1663
+ "effects": [
1664
+ [
1665
+ "persist",
1666
+ "delete",
1667
+ "PermissionGrant",
1668
+ "@payload.id",
1669
+ {
1670
+ "emit": {
1671
+ "failure": "PermissionGrantDeleteFailed",
1672
+ "success": "PermissionGrantDeleted"
1673
+ }
1674
+ }
1675
+ ]
1676
+ ],
1677
+ "event": "DO_DELETE",
1678
+ "eventId": "evt_01M2JCDX8HH16NM9P3NDPX5Y31",
1679
+ "from": "idle",
1680
+ "guard": [
1681
+ "or",
1682
+ [
1683
+ "=",
1684
+ [
1685
+ "array/len",
1686
+ "@config.adminRoles"
1687
+ ],
1688
+ 0.0
1689
+ ],
1690
+ [
1691
+ "array/includes",
1692
+ "@config.adminRoles",
1693
+ "@user.role"
1694
+ ]
1695
+ ],
1696
+ "to": "idle"
1697
+ },
1698
+ {
1699
+ "effects": [
1700
+ [
1701
+ "render-ui",
1702
+ "toast",
1703
+ {
1704
+ "dismissible": true,
1705
+ "message": [
1706
+ "str/concat",
1707
+ "Couldn't save the permission grant — ",
1708
+ "@payload.error"
1709
+ ],
1710
+ "type": "alert",
1711
+ "variant": "error"
1712
+ }
1713
+ ]
1714
+ ],
1715
+ "event": "PermissionGrantSaveFailed",
1716
+ "eventId": "evt_01M2JCDX8HFPEBTZF91HFFKT10",
1717
+ "from": "idle",
1718
+ "to": "idle"
1719
+ },
1720
+ {
1721
+ "effects": [
1722
+ [
1723
+ "render-ui",
1724
+ "toast",
1725
+ {
1726
+ "dismissible": true,
1727
+ "message": [
1728
+ "str/concat",
1729
+ "Couldn't delete the permission grant — ",
1730
+ "@payload.error"
1731
+ ],
1732
+ "type": "alert",
1733
+ "variant": "error"
1734
+ }
1735
+ ]
1736
+ ],
1737
+ "event": "PermissionGrantDeleteFailed",
1738
+ "eventId": "evt_01M2JCDX8HDS4691JHRXJ401PT",
1739
+ "from": "idle",
1740
+ "to": "idle"
1741
+ }
1742
+ ]
1743
+ }
1744
+ },
1745
+ {
1746
+ "capabilities": [
1747
+ "access"
1748
+ ],
1749
+ "category": "lifecycle",
1750
+ "config": {
1751
+ "enabled": {
1752
+ "default": false,
1753
+ "description": "Answer CHECK_GRANT lookups with GRANT_RESOLVED from the persisted grant table. Off by default.",
1754
+ "label": "Answer permission lookups",
1755
+ "synonyms": "enable, turn on, activate, permission lookup, grant query, resolve capabilities",
1756
+ "tier": "policy",
1757
+ "type": "boolean"
1758
+ }
1759
+ },
1760
+ "effectRow": [
1761
+ {
1762
+ "kind": "emit",
1763
+ "resource": "GRANT_RESOLVED"
1764
+ },
1765
+ {
1766
+ "kind": "fetch",
1767
+ "resource": "PermissionGrant"
1768
+ },
1769
+ {
1770
+ "kind": "render-ui",
1771
+ "resource": "toast"
1772
+ },
1773
+ {
1774
+ "kind": "set",
1775
+ "resource": "@entity.module"
1776
+ },
1777
+ {
1778
+ "kind": "set",
1779
+ "resource": "@entity.role"
1780
+ }
1781
+ ],
1782
+ "emits": [
1783
+ {
1784
+ "description": "Answers a CHECK_GRANT: the capability flags of the first matching grant row, with found=false (and all flags false) when no row matches. Rename to wire the downstream listener; default-deny on found=false is the consumer's choice.",
1785
+ "event": "GRANT_RESOLVED",
1786
+ "eventId": "evt_01M2HEYQZMPARRK5AP79C66MS0",
1787
+ "payloadSchema": [
1788
+ {
1789
+ "name": "role",
1790
+ "type": "string"
1791
+ },
1792
+ {
1793
+ "name": "module",
1794
+ "type": "string"
1795
+ },
1796
+ {
1797
+ "name": "canReadFinance",
1798
+ "type": "boolean"
1799
+ },
1800
+ {
1801
+ "name": "canSeeOthersHours",
1802
+ "type": "boolean"
1803
+ },
1804
+ {
1805
+ "name": "canSeeMargins",
1806
+ "type": "boolean"
1807
+ },
1808
+ {
1809
+ "name": "found",
1810
+ "type": "boolean"
1811
+ }
1812
+ ],
1813
+ "scope": "external",
1814
+ "synonyms": "grant resolved, permission answer, capabilities returned, access decision data",
1815
+ "tier": "domain"
1816
+ },
1817
+ {
1818
+ "description": "Indicates the grant lookup for a CHECK_GRANT has been successfully loaded.",
1819
+ "event": "GrantCheckLoaded",
1820
+ "eventId": "evt_01M2HEYQZMZJWHEXPD8YKCP48D",
1821
+ "payloadSchema": [
1822
+ {
1823
+ "entity": "PermissionGrant",
1824
+ "name": "data",
1825
+ "properties": [
1826
+ {
1827
+ "name": "id",
1828
+ "required": true,
1829
+ "type": "string"
1830
+ },
1831
+ {
1832
+ "name": "workspaceId",
1833
+ "type": "string"
1834
+ },
1835
+ {
1836
+ "name": "role",
1837
+ "required": true,
1838
+ "type": "string"
1839
+ },
1840
+ {
1841
+ "name": "module",
1842
+ "required": true,
1843
+ "type": "string"
1844
+ },
1845
+ {
1846
+ "name": "canReadFinance",
1847
+ "type": "boolean"
1848
+ },
1849
+ {
1850
+ "name": "canSeeOthersHours",
1851
+ "type": "boolean"
1852
+ },
1853
+ {
1854
+ "name": "canSeeMargins",
1855
+ "type": "boolean"
1856
+ },
1857
+ {
1858
+ "name": "createdAt",
1859
+ "type": "number"
1860
+ }
1861
+ ],
1862
+ "type": "[object]"
1863
+ }
1864
+ ],
1865
+ "synonyms": "loaded, fetched, retrieved",
1866
+ "tier": "internal"
1867
+ },
1868
+ {
1869
+ "description": "Indicates the grant lookup for a CHECK_GRANT failed.",
1870
+ "event": "GrantCheckFailed",
1871
+ "eventId": "evt_01M2HEYQZMT7BCD58DZH8CJCC4",
1872
+ "payloadSchema": [
1873
+ {
1874
+ "name": "error",
1875
+ "type": "string"
1876
+ },
1877
+ {
1878
+ "name": "code",
1879
+ "type": "string"
1880
+ }
1881
+ ],
1882
+ "synonyms": "lookup error, failed lookup, request failure",
1883
+ "tier": "internal"
1884
+ }
1885
+ ],
1886
+ "entityContract": {
1887
+ "provides": [
1888
+ "module",
1889
+ "role"
1890
+ ],
1891
+ "requires": []
1892
+ },
1893
+ "entityRebindable": true,
1894
+ "entityRefIds": {
1895
+ "PermissionGrant": "ent_01M2HEYQZMYFHR14P4RKB46K51"
1896
+ },
1897
+ "id": "trt_01M2HEYQZMAE7G04QDC54C9G1J",
1898
+ "linkedEntity": "PermissionGrant",
1899
+ "linkedEntityId": "ent_01M2HEYQZMYFHR14P4RKB46K51",
1900
+ "name": "PermissionGrantQuery",
1901
+ "scope": "instance",
1902
+ "stateMachine": {
1903
+ "events": [
1904
+ {
1905
+ "description": "Asks which capabilities a role holds in a module; the answer arrives as GRANT_RESOLVED (asynchronous — correlate by the echoed role/module).",
1906
+ "id": "evt_01M2HEYQZM24QM0A2ERYSYN7P1",
1907
+ "key": "CHECK_GRANT",
1908
+ "name": "Check Grant",
1909
+ "payloadSchema": [
1910
+ {
1911
+ "name": "role",
1912
+ "required": true,
1913
+ "type": "string"
1914
+ },
1915
+ {
1916
+ "name": "module",
1917
+ "required": true,
1918
+ "type": "string"
1919
+ }
1920
+ ],
1921
+ "synonyms": "check grant, lookup permission, resolve capabilities, can this role see",
1922
+ "tier": "domain"
1923
+ },
1924
+ {
1925
+ "description": "Indicates the grant lookup for a CHECK_GRANT has been successfully loaded.",
1926
+ "id": "evt_01M2HEYQZMZJWHEXPD8YKCP48D",
1927
+ "key": "GrantCheckLoaded",
1928
+ "name": "Grant check loaded",
1929
+ "payloadSchema": [
1930
+ {
1931
+ "entity": "PermissionGrant",
1932
+ "name": "data",
1933
+ "properties": [
1934
+ {
1935
+ "name": "id",
1936
+ "required": true,
1937
+ "type": "string"
1938
+ },
1939
+ {
1940
+ "name": "workspaceId",
1941
+ "type": "string"
1942
+ },
1943
+ {
1944
+ "name": "role",
1945
+ "required": true,
1946
+ "type": "string"
1947
+ },
1948
+ {
1949
+ "name": "module",
1950
+ "required": true,
1951
+ "type": "string"
1952
+ },
1953
+ {
1954
+ "name": "canReadFinance",
1955
+ "type": "boolean"
1956
+ },
1957
+ {
1958
+ "name": "canSeeOthersHours",
1959
+ "type": "boolean"
1960
+ },
1961
+ {
1962
+ "name": "canSeeMargins",
1963
+ "type": "boolean"
1964
+ },
1965
+ {
1966
+ "name": "createdAt",
1967
+ "type": "number"
1968
+ }
1969
+ ],
1970
+ "type": "[object]"
1971
+ }
1972
+ ],
1973
+ "synonyms": "loaded, fetched, retrieved",
1974
+ "tier": "internal"
1975
+ },
1976
+ {
1977
+ "description": "Indicates the grant lookup for a CHECK_GRANT failed.",
1978
+ "id": "evt_01M2HEYQZMT7BCD58DZH8CJCC4",
1979
+ "key": "GrantCheckFailed",
1980
+ "name": "Grant check failed",
1981
+ "payloadSchema": [
1982
+ {
1983
+ "name": "error",
1984
+ "type": "string"
1985
+ },
1986
+ {
1987
+ "name": "code",
1988
+ "type": "string"
1989
+ }
1990
+ ],
1991
+ "synonyms": "lookup error, failed lookup, request failure",
1992
+ "tier": "internal"
1993
+ },
1994
+ {
1995
+ "description": "Answers a CHECK_GRANT: the capability flags of the first matching grant row, with found=false (and all flags false) when no row matches. Rename to wire the downstream listener; default-deny on found=false is the consumer's choice.",
1996
+ "id": "evt_01M2HEYQZMPARRK5AP79C66MS0",
1997
+ "key": "GRANT_RESOLVED",
1998
+ "name": "Grant Resolved",
1999
+ "payloadSchema": [
2000
+ {
2001
+ "name": "role",
2002
+ "type": "string"
2003
+ },
2004
+ {
2005
+ "name": "module",
2006
+ "type": "string"
2007
+ },
2008
+ {
2009
+ "name": "canReadFinance",
2010
+ "type": "boolean"
2011
+ },
2012
+ {
2013
+ "name": "canSeeOthersHours",
2014
+ "type": "boolean"
2015
+ },
2016
+ {
2017
+ "name": "canSeeMargins",
2018
+ "type": "boolean"
2019
+ },
2020
+ {
2021
+ "name": "found",
2022
+ "type": "boolean"
2023
+ }
2024
+ ],
2025
+ "synonyms": "grant resolved, permission answer, capabilities returned, access decision data",
2026
+ "tier": "domain"
2027
+ }
2028
+ ],
2029
+ "states": [
2030
+ {
2031
+ "isInitial": true,
2032
+ "name": "idle"
2033
+ }
2034
+ ],
2035
+ "transitions": [
2036
+ {
2037
+ "effects": [
2038
+ [
2039
+ "set",
2040
+ "@entity.role",
2041
+ "@payload.role"
2042
+ ],
2043
+ [
2044
+ "set",
2045
+ "@entity.module",
2046
+ "@payload.module"
2047
+ ],
2048
+ [
2049
+ "fetch",
2050
+ "PermissionGrant",
2051
+ {
2052
+ "emit": {
2053
+ "failure": "GrantCheckFailed",
2054
+ "success": "GrantCheckLoaded"
2055
+ },
2056
+ "filter": [
2057
+ "and",
2058
+ [
2059
+ "=",
2060
+ [
2061
+ "object/get",
2062
+ "@entity",
2063
+ "role"
2064
+ ],
2065
+ "@payload.role"
2066
+ ],
2067
+ [
2068
+ "=",
2069
+ [
2070
+ "object/get",
2071
+ "@entity",
2072
+ "module"
2073
+ ],
2074
+ "@payload.module"
2075
+ ]
2076
+ ]
2077
+ }
2078
+ ]
2079
+ ],
2080
+ "event": "CHECK_GRANT",
2081
+ "eventId": "evt_01M2HEYQZM24QM0A2ERYSYN7P1",
2082
+ "from": "idle",
2083
+ "guard": "@config.enabled",
2084
+ "to": "idle"
2085
+ },
2086
+ {
2087
+ "effects": [
2088
+ [
2089
+ "emit",
2090
+ "GRANT_RESOLVED",
2091
+ {
2092
+ "canReadFinance": [
2093
+ "if",
2094
+ [
2095
+ ">",
2096
+ [
2097
+ "array/len",
2098
+ "@payload.data"
2099
+ ],
2100
+ 0.0
2101
+ ],
2102
+ [
2103
+ "object/get",
2104
+ [
2105
+ "array/first",
2106
+ "@payload.data"
2107
+ ],
2108
+ "canReadFinance",
2109
+ false
2110
+ ],
2111
+ false
2112
+ ],
2113
+ "canSeeMargins": [
2114
+ "if",
2115
+ [
2116
+ ">",
2117
+ [
2118
+ "array/len",
2119
+ "@payload.data"
2120
+ ],
2121
+ 0.0
2122
+ ],
2123
+ [
2124
+ "object/get",
2125
+ [
2126
+ "array/first",
2127
+ "@payload.data"
2128
+ ],
2129
+ "canSeeMargins",
2130
+ false
2131
+ ],
2132
+ false
2133
+ ],
2134
+ "canSeeOthersHours": [
2135
+ "if",
2136
+ [
2137
+ ">",
2138
+ [
2139
+ "array/len",
2140
+ "@payload.data"
2141
+ ],
2142
+ 0.0
2143
+ ],
2144
+ [
2145
+ "object/get",
2146
+ [
2147
+ "array/first",
2148
+ "@payload.data"
2149
+ ],
2150
+ "canSeeOthersHours",
2151
+ false
2152
+ ],
2153
+ false
2154
+ ],
2155
+ "found": [
2156
+ ">",
2157
+ [
2158
+ "array/len",
2159
+ "@payload.data"
2160
+ ],
2161
+ 0.0
2162
+ ],
2163
+ "module": "@entity.module",
2164
+ "role": "@entity.role"
2165
+ }
2166
+ ]
2167
+ ],
2168
+ "event": "GrantCheckLoaded",
2169
+ "eventId": "evt_01M2HEYQZMZJWHEXPD8YKCP48D",
2170
+ "from": "idle",
2171
+ "to": "idle"
2172
+ },
2173
+ {
2174
+ "effects": [
2175
+ [
2176
+ "render-ui",
2177
+ "toast",
2178
+ {
2179
+ "dismissible": true,
2180
+ "message": [
2181
+ "str/concat",
2182
+ "Couldn't resolve the permission grant — ",
2183
+ "@payload.error"
2184
+ ],
2185
+ "type": "alert",
2186
+ "variant": "error"
2187
+ }
2188
+ ]
2189
+ ],
2190
+ "event": "GrantCheckFailed",
2191
+ "eventId": "evt_01M2HEYQZMT7BCD58DZH8CJCC4",
2192
+ "from": "idle",
2193
+ "to": "idle"
2194
+ }
2195
+ ]
2196
+ }
2197
+ }
2198
+ ],
2199
+ "uses": [
2200
+ {
2201
+ "as": "Modal",
2202
+ "from": "std/behaviors/std-modal"
2203
+ },
2204
+ {
2205
+ "as": "Spinner",
2206
+ "from": "std/behaviors/ui-spinner"
2207
+ },
2208
+ {
2209
+ "as": "Typography",
2210
+ "from": "std/behaviors/ui-typography"
2211
+ },
2212
+ {
2213
+ "as": "Icon",
2214
+ "from": "std/behaviors/ui-icon"
2215
+ },
2216
+ {
2217
+ "as": "Divider",
2218
+ "from": "std/behaviors/ui-divider"
2219
+ },
2220
+ {
2221
+ "as": "Alert",
2222
+ "from": "std/behaviors/ui-alert"
2223
+ }
2224
+ ]
2225
+ }
2226
+ ],
2227
+ "schemaVersion": 1,
2228
+ "version": "1.0.0"
2229
+ }