@jmruthers/pace-core 0.5.165 → 0.5.166

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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  useCan,
3
3
  useResolvedScope
4
- } from "./chunk-GFSYFEVZ.js";
4
+ } from "./chunk-BPIFVNEO.js";
5
5
  import {
6
6
  toast,
7
7
  useDataTablePerformance
@@ -12726,4 +12726,4 @@ lodash/lodash.js:
12726
12726
  * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
12727
12727
  *)
12728
12728
  */
12729
- //# sourceMappingURL=chunk-23YYDN24.js.map
12729
+ //# sourceMappingURL=chunk-SVMR7EVX.js.map
@@ -57,7 +57,7 @@ import {
57
57
  useFileReferenceForRecord,
58
58
  useFilesByCategory,
59
59
  usePublicPageContext as usePublicPageContext2
60
- } from "./chunk-Q4NUEMNV.js";
60
+ } from "./chunk-JIRBF5HR.js";
61
61
  import {
62
62
  Alert,
63
63
  AlertDescription,
@@ -98,8 +98,8 @@ import {
98
98
  TooltipProvider,
99
99
  TooltipRoot,
100
100
  TooltipTrigger
101
- } from "./chunk-23YYDN24.js";
102
- import "./chunk-GFSYFEVZ.js";
101
+ } from "./chunk-SVMR7EVX.js";
102
+ import "./chunk-BPIFVNEO.js";
103
103
  import "./chunk-BVYWGZVV.js";
104
104
  import "./chunk-SBVILCCA.js";
105
105
  import {
package/dist/index.js CHANGED
@@ -30,7 +30,7 @@ import {
30
30
  withAccessLevelGuard,
31
31
  withPermissionGuard,
32
32
  withRoleGuard
33
- } from "./chunk-DDB2M4XO.js";
33
+ } from "./chunk-5PH366QI.js";
34
34
  import {
35
35
  init_useInactivityTracker,
36
36
  useInactivityTracker
@@ -96,7 +96,7 @@ import {
96
96
  useFileReferenceForRecord,
97
97
  useFilesByCategory,
98
98
  usePublicPageContext as usePublicPageContext2
99
- } from "./chunk-Q4NUEMNV.js";
99
+ } from "./chunk-JIRBF5HR.js";
100
100
  import {
101
101
  Alert,
102
102
  AlertDescription,
@@ -146,7 +146,7 @@ import {
146
146
  max,
147
147
  min,
148
148
  sum
149
- } from "./chunk-23YYDN24.js";
149
+ } from "./chunk-SVMR7EVX.js";
150
150
  import {
151
151
  useAccessLevel,
152
152
  useCachedPermissions,
@@ -159,7 +159,7 @@ import {
159
159
  useResolvedScope,
160
160
  useResourcePermissions,
161
161
  useRoleManagement
162
- } from "./chunk-GFSYFEVZ.js";
162
+ } from "./chunk-BPIFVNEO.js";
163
163
  import {
164
164
  CACHE_PATTERNS,
165
165
  RBACCache,
@@ -1286,13 +1286,20 @@ declare function useResourcePermissions(resource: string, options?: UseResourceP
1286
1286
  * Hook to get user's permissions in a scope
1287
1287
  *
1288
1288
  * @param userId - User ID
1289
- * @param scope - Scope for permission checking
1289
+ * @param organisationId - Organisation ID
1290
+ * @param eventId - Event ID (optional)
1291
+ * @param appId - Application ID (optional)
1290
1292
  * @returns Permission state and methods
1291
1293
  *
1292
1294
  * @example
1293
1295
  * ```tsx
1294
1296
  * function MyComponent() {
1295
- * const { permissions, isLoading, error } = usePermissions(userId, scope);
1297
+ * const { permissions, isLoading, error } = usePermissions(
1298
+ * userId,
1299
+ * organisationId,
1300
+ * eventId,
1301
+ * appId
1302
+ * );
1296
1303
  *
1297
1304
  * if (isLoading) return <div>Loading...</div>;
1298
1305
  * if (error) return <div>Error: {error.message}</div>;
@@ -1306,7 +1313,7 @@ declare function useResourcePermissions(resource: string, options?: UseResourceP
1306
1313
  * }
1307
1314
  * ```
1308
1315
  */
1309
- declare function usePermissions(userId: UUID, scope: Scope): {
1316
+ declare function usePermissions(userId: UUID, organisationId: string | undefined, eventId: string | undefined, appId: string | undefined): {
1310
1317
  permissions: PermissionMap;
1311
1318
  isLoading: boolean;
1312
1319
  error: Error | null;
@@ -30,7 +30,7 @@ import {
30
30
  withAccessLevelGuard,
31
31
  withPermissionGuard,
32
32
  withRoleGuard
33
- } from "../chunk-DDB2M4XO.js";
33
+ } from "../chunk-5PH366QI.js";
34
34
  import {
35
35
  useAccessLevel,
36
36
  useCachedPermissions,
@@ -43,7 +43,7 @@ import {
43
43
  useResolvedScope,
44
44
  useResourcePermissions,
45
45
  useRoleManagement
46
- } from "../chunk-GFSYFEVZ.js";
46
+ } from "../chunk-BPIFVNEO.js";
47
47
  import {
48
48
  CACHE_PATTERNS,
49
49
  RBACCache,
package/dist/utils.js CHANGED
@@ -614,7 +614,7 @@ function createLazyComponent(importFn, componentName, options = {}) {
614
614
  return WrappedComponent;
615
615
  }
616
616
  var LazyDataTable = createLazyComponent(
617
- () => import("./DataTable-HAATGNJY.js").then((module) => ({ default: module.DataTable })),
617
+ () => import("./DataTable-Z6IYTME3.js").then((module) => ({ default: module.DataTable })),
618
618
  "DataTable"
619
619
  );
620
620
 
@@ -6578,7 +6578,7 @@ ___
6578
6578
 
6579
6579
  ### usePermissions
6580
6580
 
6581
- ▸ **usePermissions**(`userId`, `scope`): `Object`
6581
+ ▸ **usePermissions**(`userId`, `organisationId`, `eventId`, `appId`): `Object`
6582
6582
 
6583
6583
  Hook to get user's permissions in a scope
6584
6584
 
@@ -6587,7 +6587,9 @@ Hook to get user's permissions in a scope
6587
6587
  | Name | Type | Description |
6588
6588
  | :------ | :------ | :------ |
6589
6589
  | `userId` | `string` | User ID |
6590
- | `scope` | [`Scope`](modules.md#scope) | Scope for permission checking |
6590
+ | `organisationId` | `undefined` \| `string` | Organisation ID |
6591
+ | `eventId` | `undefined` \| `string` | Event ID (optional) |
6592
+ | `appId` | `undefined` \| `string` | Application ID (optional) |
6591
6593
 
6592
6594
  #### Returns
6593
6595
 
@@ -6609,7 +6611,12 @@ Permission state and methods
6609
6611
 
6610
6612
  ```tsx
6611
6613
  function MyComponent() {
6612
- const { permissions, isLoading, error } = usePermissions(userId, scope);
6614
+ const { permissions, isLoading, error } = usePermissions(
6615
+ userId,
6616
+ organisationId,
6617
+ eventId,
6618
+ appId
6619
+ );
6613
6620
 
6614
6621
  if (isLoading) return <div>Loading...</div>;
6615
6622
  if (error) return <div>Error: {error.message}</div>;
@@ -6625,7 +6632,7 @@ function MyComponent() {
6625
6632
 
6626
6633
  #### Defined in
6627
6634
 
6628
- [packages/core/src/rbac/hooks/usePermissions.ts:50](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L50)
6635
+ [packages/core/src/rbac/hooks/usePermissions.ts:57](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L57)
6629
6636
 
6630
6637
  ___
6631
6638
 
@@ -6673,7 +6680,7 @@ function MyComponent() {
6673
6680
 
6674
6681
  #### Defined in
6675
6682
 
6676
- [packages/core/src/rbac/hooks/usePermissions.ts:315](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L315)
6683
+ [packages/core/src/rbac/hooks/usePermissions.ts:328](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L328)
6677
6684
 
6678
6685
  ___
6679
6686
 
@@ -6723,7 +6730,7 @@ function MyComponent() {
6723
6730
 
6724
6731
  #### Defined in
6725
6732
 
6726
- [packages/core/src/rbac/hooks/usePermissions.ts:511](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L511)
6733
+ [packages/core/src/rbac/hooks/usePermissions.ts:524](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L524)
6727
6734
 
6728
6735
  ___
6729
6736
 
@@ -6780,7 +6787,7 @@ function MyComponent() {
6780
6787
 
6781
6788
  #### Defined in
6782
6789
 
6783
- [packages/core/src/rbac/hooks/usePermissions.ts:586](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L586)
6790
+ [packages/core/src/rbac/hooks/usePermissions.ts:599](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L599)
6784
6791
 
6785
6792
  ___
6786
6793
 
@@ -6831,7 +6838,7 @@ function MyComponent() {
6831
6838
 
6832
6839
  #### Defined in
6833
6840
 
6834
- [packages/core/src/rbac/hooks/usePermissions.ts:669](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L669)
6841
+ [packages/core/src/rbac/hooks/usePermissions.ts:682](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L682)
6835
6842
 
6836
6843
  ___
6837
6844
 
@@ -6882,7 +6889,7 @@ function MyComponent() {
6882
6889
 
6883
6890
  #### Defined in
6884
6891
 
6885
- [packages/core/src/rbac/hooks/usePermissions.ts:755](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L755)
6892
+ [packages/core/src/rbac/hooks/usePermissions.ts:768](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L768)
6886
6893
 
6887
6894
  ___
6888
6895
 
@@ -6933,7 +6940,7 @@ function MyComponent() {
6933
6940
 
6934
6941
  #### Defined in
6935
6942
 
6936
- [packages/core/src/rbac/hooks/usePermissions.ts:840](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L840)
6943
+ [packages/core/src/rbac/hooks/usePermissions.ts:853](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L853)
6937
6944
 
6938
6945
  ___
6939
6946
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jmruthers/pace-core",
3
- "version": "0.5.165",
3
+ "version": "0.5.166",
4
4
  "description": "Clean, modern React component library with Tailwind v4 styling and native utilities",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -29,10 +29,13 @@ const mockIsPermittedCached = vi.mocked(isPermittedCached);
29
29
 
30
30
  describe('usePermissions Hook Stability', () => {
31
31
  const mockUserId = 'user-123';
32
+ const mockOrgId = 'org-123';
33
+ const mockEventId = 'event-123';
34
+ const mockAppId = 'app-123';
32
35
  const mockScope = {
33
- organisationId: 'org-123',
34
- eventId: 'event-123',
35
- appId: 'app-123'
36
+ organisationId: mockOrgId,
37
+ eventId: mockEventId,
38
+ appId: mockAppId
36
39
  };
37
40
 
38
41
  beforeEach(() => {
@@ -49,7 +52,7 @@ describe('usePermissions Hook Stability', () => {
49
52
  mockGetPermissionMap.mockResolvedValue(mockPermissions);
50
53
 
51
54
  const { result, rerender } = renderHook(() =>
52
- usePermissions(mockUserId, mockScope)
55
+ usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId)
53
56
  );
54
57
 
55
58
  // Wait for initial load
@@ -122,7 +125,7 @@ describe('usePermissions Hook Stability', () => {
122
125
 
123
126
  const { result } = renderHook(() => {
124
127
  renderCount++;
125
- return usePermissions(mockUserId, mockScope);
128
+ return usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId);
126
129
  });
127
130
 
128
131
  // Wait for initial load
@@ -215,7 +218,7 @@ describe('usePermissions Hook Stability', () => {
215
218
  mockGetPermissionMap.mockResolvedValue({ 'read:users': true });
216
219
 
217
220
  const { result, rerender } = renderHook(
218
- ({ userId }) => usePermissions(userId, mockScope),
221
+ ({ userId }) => usePermissions(userId, mockOrgId, mockEventId, mockAppId),
219
222
  { initialProps: { userId: 'user-1' } }
220
223
  );
221
224
 
@@ -243,8 +246,8 @@ describe('usePermissions Hook Stability', () => {
243
246
  mockGetPermissionMap.mockResolvedValue({ 'read:users': true });
244
247
 
245
248
  const { result, rerender } = renderHook(
246
- ({ scope }) => usePermissions(mockUserId, scope),
247
- { initialProps: { scope: { ...mockScope, organisationId: 'org-1' } } }
249
+ ({ orgId }) => usePermissions(mockUserId, orgId, mockEventId, mockAppId),
250
+ { initialProps: { orgId: 'org-1' } }
248
251
  );
249
252
 
250
253
  await act(async () => {
@@ -252,7 +255,7 @@ describe('usePermissions Hook Stability', () => {
252
255
  });
253
256
 
254
257
  // Change scope
255
- rerender({ scope: { ...mockScope, organisationId: 'org-2' } });
258
+ rerender({ orgId: 'org-2' });
256
259
 
257
260
  await act(async () => {
258
261
  await new Promise(resolve => setTimeout(resolve, 0));
@@ -594,30 +594,12 @@ export const NavigationMenu = React.forwardRef<
594
594
  }
595
595
  }, [filterByPermissions, stableScope.organisationId, stableScope.eventId, stableScope.appId, userId]);
596
596
 
597
- // Create a stable scope reference that React can properly track
598
- // CRITICAL: Use stableScope properties DIRECTLY in dependencies, not extracted values
599
- // React needs to see the actual property changes to trigger re-memoization
600
- const stableScopeForPermissions = React.useMemo(() => {
601
- const scope = {
602
- organisationId: stableScope.organisationId || '',
603
- eventId: stableScope.eventId,
604
- appId: stableScope.appId
605
- };
606
- // Log when scope changes to verify React detects the change
607
- if (filterByPermissions && scope.organisationId) {
608
- logger.warn('NavigationMenu', 'stableScopeForPermissions created', {
609
- organisationId: scope.organisationId,
610
- eventId: scope.eventId,
611
- appId: scope.appId,
612
- hasAppId: !!scope.appId
613
- });
614
- }
615
- return scope;
616
- }, [filterByPermissions, stableScope.organisationId, stableScope.eventId, stableScope.appId]);
617
-
597
+ // Call usePermissions with primitive parameters for reliable React dependency tracking
618
598
  const { permissions: permissionMap, hasAnyPermission, isLoading: permissionsLoading, error: permissionsError } = usePermissions(
619
599
  userId as any,
620
- stableScopeForPermissions as any
600
+ stableScope.organisationId,
601
+ stableScope.eventId,
602
+ stableScope.appId
621
603
  );
622
604
 
623
605
  // Debug logging for permission map state
@@ -332,7 +332,7 @@ describe('Service Hooks', () => {
332
332
 
333
333
  mockUseContext.mockReturnValue({ rbacService: mockService });
334
334
 
335
- const { result } = renderHook(() => usePermissions('user-1', { organisationId: 'org-1', eventId: 'event-1', appId: 'test-app' }), { wrapper });
335
+ const { result } = renderHook(() => usePermissions('user-1', 'org-1', 'event-1', 'test-app'), { wrapper });
336
336
 
337
337
  expect(result.current.permissions).toEqual({ 'events:read': true });
338
338
  expect(result.current.roles).toEqual(['admin']);
@@ -535,7 +535,7 @@ describe('Service Hooks', () => {
535
535
  const { result: authResult } = renderHook(() => useAuth(), { wrapper });
536
536
 
537
537
  mockUseContext.mockReturnValue({ rbacService: mockRBACService });
538
- const { result: permissionsResult } = renderHook(() => usePermissions('user-1', { organisationId: 'org-1', eventId: 'event-1', appId: 'test-app' }), { wrapper });
538
+ const { result: permissionsResult } = renderHook(() => usePermissions('user-1', 'org-1', 'event-1', 'test-app'), { wrapper });
539
539
 
540
540
  mockUseContext.mockReturnValue({ organisationService: mockOrganisationService });
541
541
  const { result: organisationResult } = renderHook(() => useCurrentOrganisation(), { wrapper });
@@ -27,9 +27,13 @@ vi.mock('../../api', () => ({
27
27
  import { getPermissionMap } from '../../api';
28
28
 
29
29
  const mockUserId = 'user-123';
30
+ const mockOrgId = 'org-123';
31
+ const mockEventId = 'event-123';
32
+ const mockAppId = 'app-123';
30
33
  const mockScope = {
31
- organisationId: 'org-123',
32
- eventId: 'event-123'
34
+ organisationId: mockOrgId,
35
+ eventId: mockEventId,
36
+ appId: mockAppId
33
37
  };
34
38
 
35
39
  const mockPermissionMap = {
@@ -54,9 +58,9 @@ describe('usePermissions Integration Tests', () => {
54
58
  describe('Cache Behavior', () => {
55
59
  it('fetches permissions only once for same dependencies', async () => {
56
60
  const { result, rerender } = renderHook(
57
- ({ userId, scope }) => usePermissions(userId, scope),
61
+ ({ userId, orgId, eventId, appId }) => usePermissions(userId, orgId, eventId, appId),
58
62
  {
59
- initialProps: { userId: mockUserId, scope: mockScope }
63
+ initialProps: { userId: mockUserId, orgId: mockOrgId, eventId: mockEventId, appId: mockAppId }
60
64
  }
61
65
  );
62
66
 
@@ -75,9 +79,9 @@ describe('usePermissions Integration Tests', () => {
75
79
 
76
80
  it('refetches when organisationId changes', async () => {
77
81
  const { result, rerender } = renderHook(
78
- ({ userId, scope }) => usePermissions(userId, scope),
82
+ ({ userId, orgId, eventId, appId }) => usePermissions(userId, orgId, eventId, appId),
79
83
  {
80
- initialProps: { userId: mockUserId, scope: mockScope }
84
+ initialProps: { userId: mockUserId, orgId: mockOrgId, eventId: mockEventId, appId: mockAppId }
81
85
  }
82
86
  );
83
87
 
@@ -95,9 +99,9 @@ describe('usePermissions Integration Tests', () => {
95
99
 
96
100
  it('refetches when eventId changes', async () => {
97
101
  const { result, rerender } = renderHook(
98
- ({ userId, scope }) => usePermissions(userId, scope),
102
+ ({ userId, orgId, eventId, appId }) => usePermissions(userId, orgId, eventId, appId),
99
103
  {
100
- initialProps: { userId: mockUserId, scope: mockScope }
104
+ initialProps: { userId: mockUserId, orgId: mockOrgId, eventId: mockEventId, appId: mockAppId }
101
105
  }
102
106
  );
103
107
 
@@ -114,11 +118,10 @@ describe('usePermissions Integration Tests', () => {
114
118
  });
115
119
 
116
120
  it('refetches when appId changes', async () => {
117
- const scopeWithApp = { ...mockScope, appId: 'app-1' };
118
121
  const { result, rerender } = renderHook(
119
- ({ userId, scope }) => usePermissions(userId, scope),
122
+ ({ userId, orgId, eventId, appId }) => usePermissions(userId, orgId, eventId, appId),
120
123
  {
121
- initialProps: { userId: mockUserId, scope: scopeWithApp }
124
+ initialProps: { userId: mockUserId, orgId: mockOrgId, eventId: mockEventId, appId: 'app-1' }
122
125
  }
123
126
  );
124
127
 
@@ -137,7 +140,7 @@ describe('usePermissions Integration Tests', () => {
137
140
 
138
141
  describe('Refetch Scenarios', () => {
139
142
  it('refetch updates permissions after external change', async () => {
140
- const { result } = renderHook(() => usePermissions(mockUserId, mockScope));
143
+ const { result } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
141
144
 
142
145
  await waitFor(() => {
143
146
  expect(result.current.isLoading).toBe(false);
@@ -159,7 +162,7 @@ describe('usePermissions Integration Tests', () => {
159
162
  it('refetch clears error state', async () => {
160
163
  // First render with error
161
164
  mockGetPermissionMap.mockRejectedValueOnce(new Error('Network error'));
162
- const { result } = renderHook(() => usePermissions(mockUserId, mockScope));
165
+ const { result } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
163
166
 
164
167
  await waitFor(() => {
165
168
  expect(result.current.error).toBeDefined();
@@ -176,7 +179,7 @@ describe('usePermissions Integration Tests', () => {
176
179
  });
177
180
 
178
181
  it('refetch triggers API call', async () => {
179
- const { result } = renderHook(() => usePermissions(mockUserId, mockScope));
182
+ const { result } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
180
183
 
181
184
  await waitFor(() => {
182
185
  expect(result.current.isLoading).toBe(false);
@@ -192,7 +195,7 @@ describe('usePermissions Integration Tests', () => {
192
195
  });
193
196
 
194
197
  it('refetch does nothing when userId is empty', async () => {
195
- const { result } = renderHook(() => usePermissions('', mockScope));
198
+ const { result } = renderHook(() => usePermissions('', mockOrgId, mockEventId, mockAppId));
196
199
 
197
200
  await waitFor(() => {
198
201
  expect(result.current.isLoading).toBe(false);
@@ -207,8 +210,7 @@ describe('usePermissions Integration Tests', () => {
207
210
  });
208
211
 
209
212
  it('refetch does nothing when organisationId is empty', async () => {
210
- const invalidScope = { ...mockScope, organisationId: '' };
211
- const { result } = renderHook(() => usePermissions(mockUserId, invalidScope));
213
+ const { result } = renderHook(() => usePermissions(mockUserId, '', mockEventId, mockAppId));
212
214
 
213
215
  await waitFor(() => {
214
216
  expect(result.current.isLoading).toBe(true);
@@ -225,7 +227,7 @@ describe('usePermissions Integration Tests', () => {
225
227
 
226
228
  describe('Concurrent Permission Checks', () => {
227
229
  it('handles rapid permission checks correctly', async () => {
228
- const { result } = renderHook(() => usePermissions(mockUserId, mockScope));
230
+ const { result } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
229
231
 
230
232
  await waitFor(() => {
231
233
  expect(result.current.isLoading).toBe(false);
@@ -250,8 +252,8 @@ describe('usePermissions Integration Tests', () => {
250
252
  });
251
253
 
252
254
  it('handles multiple hooks with same scope', async () => {
253
- const { result: result1 } = renderHook(() => usePermissions(mockUserId, mockScope));
254
- const { result: result2 } = renderHook(() => usePermissions(mockUserId, mockScope));
255
+ const { result: result1 } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
256
+ const { result: result2 } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
255
257
 
256
258
  await waitFor(() => {
257
259
  expect(result1.current.isLoading).toBe(false);
@@ -266,8 +268,8 @@ describe('usePermissions Integration Tests', () => {
266
268
  });
267
269
 
268
270
  it('handles refetch from multiple components', async () => {
269
- const { result: result1 } = renderHook(() => usePermissions(mockUserId, mockScope));
270
- const { result: result2 } = renderHook(() => usePermissions(mockUserId, mockScope));
271
+ const { result: result1 } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
272
+ const { result: result2 } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
271
273
 
272
274
  await waitFor(() => {
273
275
  expect(result1.current.isLoading).toBe(false);
@@ -286,7 +288,7 @@ describe('usePermissions Integration Tests', () => {
286
288
 
287
289
  describe('Permission Array Operations', () => {
288
290
  it('hasAnyPermission handles complex arrays', async () => {
289
- const { result } = renderHook(() => usePermissions(mockUserId, mockScope));
291
+ const { result } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
290
292
 
291
293
  await waitFor(() => {
292
294
  expect(result.current.isLoading).toBe(false);
@@ -298,7 +300,7 @@ describe('usePermissions Integration Tests', () => {
298
300
  });
299
301
 
300
302
  it('hasAllPermissions handles complex arrays', async () => {
301
- const { result } = renderHook(() => usePermissions(mockUserId, mockScope));
303
+ const { result } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
302
304
 
303
305
  await waitFor(() => {
304
306
  expect(result.current.isLoading).toBe(false);
@@ -316,7 +318,7 @@ describe('usePermissions Integration Tests', () => {
316
318
  }
317
319
 
318
320
  mockGetPermissionMap.mockResolvedValue(largePermissionMap);
319
- const { result } = renderHook(() => usePermissions(mockUserId, mockScope));
321
+ const { result } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
320
322
 
321
323
  await waitFor(() => {
322
324
  expect(result.current.isLoading).toBe(false);
@@ -371,8 +373,7 @@ describe('usePermissions Integration Tests', () => {
371
373
 
372
374
  describe('Invalid Scope Handling', () => {
373
375
  it('handles empty organisationId gracefully', async () => {
374
- const invalidScope = { ...mockScope, organisationId: '' };
375
- const { result } = renderHook(() => usePermissions(mockUserId, invalidScope));
376
+ const { result } = renderHook(() => usePermissions(mockUserId, '', mockEventId, mockAppId));
376
377
 
377
378
  // Should not fetch with invalid scope
378
379
  await waitFor(() => {
@@ -381,8 +382,7 @@ describe('usePermissions Integration Tests', () => {
381
382
  });
382
383
 
383
384
  it('handles whitespace-only organisationId', async () => {
384
- const invalidScope = { ...mockScope, organisationId: ' ' };
385
- const { result } = renderHook(() => usePermissions(mockUserId, invalidScope));
385
+ const { result } = renderHook(() => usePermissions(mockUserId, ' ', mockEventId, mockAppId));
386
386
 
387
387
  // Should not fetch with invalid scope
388
388
  await waitFor(() => {
@@ -391,9 +391,7 @@ describe('usePermissions Integration Tests', () => {
391
391
  });
392
392
 
393
393
  it('handles missing organisationId', async () => {
394
- const invalidScope = { ...mockScope };
395
- delete (invalidScope as any).organisationId;
396
- const { result } = renderHook(() => usePermissions(mockUserId, invalidScope));
394
+ const { result } = renderHook(() => usePermissions(mockUserId, undefined, mockEventId, mockAppId));
397
395
 
398
396
  // Should not fetch with invalid scope
399
397
  await waitFor(() => {
@@ -405,9 +403,9 @@ describe('usePermissions Integration Tests', () => {
405
403
  describe('Memoization', () => {
406
404
  it('returns stable references for helpers', async () => {
407
405
  const { result, rerender } = renderHook(
408
- ({ userId, scope }) => usePermissions(userId, scope),
406
+ ({ userId, orgId, eventId, appId }) => usePermissions(userId, orgId, eventId, appId),
409
407
  {
410
- initialProps: { userId: mockUserId, scope: mockScope }
408
+ initialProps: { userId: mockUserId, orgId: mockOrgId, eventId: mockEventId, appId: mockAppId }
411
409
  }
412
410
  );
413
411