@jmruthers/pace-core 0.5.186 → 0.5.188

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.
Files changed (290) hide show
  1. package/dist/{DataTable-IX2NBUTP.js → DataTable-GUFUNZ3N.js} +7 -7
  2. package/dist/{DataTable-Z9NLVJh0.d.ts → DataTable-IVYljGJ6.d.ts} +1 -1
  3. package/dist/{PublicPageProvider-DIzEzwKl.d.ts → PublicPageProvider-DrLDztHt.d.ts} +211 -106
  4. package/dist/{UnifiedAuthProvider-A4BCQRJY.js → UnifiedAuthProvider-643PUAIM.js} +2 -2
  5. package/dist/{api-BMFCXVQX.js → api-YP7XD5L6.js} +3 -3
  6. package/dist/{audit-WRS3KJKI.js → audit-B5P6FFIR.js} +2 -2
  7. package/dist/{chunk-HGPQUCBC.js → chunk-2UUZZJFT.js} +3 -3
  8. package/dist/{chunk-445GEP27.js → chunk-3GOZZZYH.js} +33 -8
  9. package/dist/chunk-3GOZZZYH.js.map +1 -0
  10. package/dist/{chunk-FSFQFJCU.js → chunk-63FOKYGO.js} +174 -6
  11. package/dist/chunk-63FOKYGO.js.map +1 -0
  12. package/dist/{chunk-DAGICKHT.js → chunk-DDM4CCYT.js} +3 -3
  13. package/dist/{chunk-XAUHJD3L.js → chunk-E7UAOUMY.js} +2 -2
  14. package/dist/{chunk-HDCUMOOI.js → chunk-EFCLXK7F.js} +792 -559
  15. package/dist/chunk-EFCLXK7F.js.map +1 -0
  16. package/dist/{chunk-U6WNSFX5.js → chunk-HEHYGYOX.js} +279 -44
  17. package/dist/chunk-HEHYGYOX.js.map +1 -0
  18. package/dist/{chunk-GRIQLQ52.js → chunk-IM4QE42D.js} +27 -23
  19. package/dist/chunk-IM4QE42D.js.map +1 -0
  20. package/dist/{chunk-OALXJH4Y.js → chunk-IPCH26AG.js} +8 -8
  21. package/dist/chunk-IPCH26AG.js.map +1 -0
  22. package/dist/{chunk-UQWSHFVX.js → chunk-SAUPYVLF.js} +1 -1
  23. package/dist/{chunk-UQWSHFVX.js.map → chunk-SAUPYVLF.js.map} +1 -1
  24. package/dist/{chunk-TC7D3CR3.js → chunk-UNOTYLQF.js} +556 -101
  25. package/dist/chunk-UNOTYLQF.js.map +1 -0
  26. package/dist/{chunk-FXFJRTKI.js → chunk-VGZZXKBR.js} +5 -5
  27. package/dist/chunk-VGZZXKBR.js.map +1 -0
  28. package/dist/chunk-YHCN776L.js +447 -0
  29. package/dist/chunk-YHCN776L.js.map +1 -0
  30. package/dist/components.d.ts +4 -4
  31. package/dist/components.js +12 -10
  32. package/dist/components.js.map +1 -1
  33. package/dist/{file-reference-PRTSLxKx.d.ts → file-reference-D037xOFK.d.ts} +0 -1
  34. package/dist/hooks.d.ts +221 -6
  35. package/dist/hooks.js +146 -49
  36. package/dist/hooks.js.map +1 -1
  37. package/dist/index.d.ts +24 -9
  38. package/dist/index.js +62 -28
  39. package/dist/index.js.map +1 -1
  40. package/dist/providers.js +1 -1
  41. package/dist/rbac/index.d.ts +124 -7
  42. package/dist/rbac/index.js +27 -7
  43. package/dist/{types-DUyCRSTj.d.ts → types-Bwgl--Xo.d.ts} +162 -1
  44. package/dist/types.d.ts +1 -1
  45. package/dist/types.js +1 -1
  46. package/dist/{usePublicRouteParams-D71QLlg4.d.ts → usePublicRouteParams-CTDELQ7H.d.ts} +2 -2
  47. package/dist/utils.d.ts +213 -3
  48. package/dist/utils.js +22 -2
  49. package/dist/utils.js.map +1 -1
  50. package/docs/api/classes/ColumnFactory.md +1 -1
  51. package/docs/api/classes/ErrorBoundary.md +1 -1
  52. package/docs/api/classes/InvalidScopeError.md +1 -1
  53. package/docs/api/classes/Logger.md +1 -1
  54. package/docs/api/classes/MissingUserContextError.md +1 -1
  55. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  56. package/docs/api/classes/PermissionDeniedError.md +1 -1
  57. package/docs/api/classes/RBACAuditManager.md +21 -17
  58. package/docs/api/classes/RBACCache.md +31 -23
  59. package/docs/api/classes/RBACEngine.md +5 -5
  60. package/docs/api/classes/RBACError.md +1 -1
  61. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  62. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  63. package/docs/api/classes/StorageUtils.md +1 -1
  64. package/docs/api/enums/FileCategory.md +1 -1
  65. package/docs/api/enums/LogLevel.md +1 -1
  66. package/docs/api/enums/RBACErrorCode.md +1 -1
  67. package/docs/api/enums/RPCFunction.md +1 -1
  68. package/docs/api/interfaces/AddressFieldProps.md +241 -0
  69. package/docs/api/interfaces/AddressFieldRef.md +94 -0
  70. package/docs/api/interfaces/AggregateConfig.md +1 -1
  71. package/docs/api/interfaces/AutocompleteOptions.md +75 -0
  72. package/docs/api/interfaces/BadgeProps.md +1 -1
  73. package/docs/api/interfaces/ButtonProps.md +1 -1
  74. package/docs/api/interfaces/CalendarProps.md +1 -1
  75. package/docs/api/interfaces/CardProps.md +1 -1
  76. package/docs/api/interfaces/ColorPalette.md +1 -1
  77. package/docs/api/interfaces/ColorShade.md +1 -1
  78. package/docs/api/interfaces/ComplianceResult.md +1 -1
  79. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  80. package/docs/api/interfaces/DataRecord.md +1 -1
  81. package/docs/api/interfaces/DataTableAction.md +1 -1
  82. package/docs/api/interfaces/DataTableColumn.md +1 -1
  83. package/docs/api/interfaces/DataTableProps.md +1 -1
  84. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  85. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  86. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  87. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  88. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  89. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  90. package/docs/api/interfaces/ExportColumn.md +1 -1
  91. package/docs/api/interfaces/ExportOptions.md +1 -1
  92. package/docs/api/interfaces/FileDisplayProps.md +15 -15
  93. package/docs/api/interfaces/FileMetadata.md +1 -1
  94. package/docs/api/interfaces/FileReference.md +1 -1
  95. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  96. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  97. package/docs/api/interfaces/FileUploadProps.md +1 -1
  98. package/docs/api/interfaces/FooterProps.md +1 -1
  99. package/docs/api/interfaces/FormFieldProps.md +1 -1
  100. package/docs/api/interfaces/FormProps.md +1 -1
  101. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  102. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  103. package/docs/api/interfaces/InputProps.md +1 -1
  104. package/docs/api/interfaces/LabelProps.md +1 -1
  105. package/docs/api/interfaces/LoggerConfig.md +1 -1
  106. package/docs/api/interfaces/LoginFormProps.md +1 -1
  107. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  108. package/docs/api/interfaces/NavigationContextType.md +1 -1
  109. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  110. package/docs/api/interfaces/NavigationItem.md +1 -1
  111. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  112. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  113. package/docs/api/interfaces/Organisation.md +1 -1
  114. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  115. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  116. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  117. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  118. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  119. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  120. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  121. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  122. package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
  123. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  124. package/docs/api/interfaces/PaletteData.md +1 -1
  125. package/docs/api/interfaces/ParsedAddress.md +120 -0
  126. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  127. package/docs/api/interfaces/ProgressProps.md +1 -1
  128. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  129. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  130. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  131. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  132. package/docs/api/interfaces/QuickFix.md +1 -1
  133. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  134. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  135. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  136. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  137. package/docs/api/interfaces/RBACConfig.md +26 -3
  138. package/docs/api/interfaces/RBACContext.md +1 -1
  139. package/docs/api/interfaces/RBACLogger.md +5 -5
  140. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  141. package/docs/api/interfaces/RBACPerformanceMetrics.md +138 -0
  142. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  143. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  144. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  145. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  146. package/docs/api/interfaces/RBACResult.md +1 -1
  147. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  148. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  149. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  150. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  151. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  152. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  153. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  154. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  155. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  156. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  157. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  158. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  159. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  160. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  161. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  162. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  163. package/docs/api/interfaces/RouteConfig.md +1 -1
  164. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  165. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  166. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  167. package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
  168. package/docs/api/interfaces/SetupIssue.md +1 -1
  169. package/docs/api/interfaces/StorageConfig.md +1 -1
  170. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  171. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  172. package/docs/api/interfaces/StorageListOptions.md +1 -1
  173. package/docs/api/interfaces/StorageListResult.md +1 -1
  174. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  175. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  176. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  177. package/docs/api/interfaces/StyleImport.md +1 -1
  178. package/docs/api/interfaces/SwitchProps.md +1 -1
  179. package/docs/api/interfaces/TabsContentProps.md +1 -1
  180. package/docs/api/interfaces/TabsListProps.md +1 -1
  181. package/docs/api/interfaces/TabsProps.md +1 -1
  182. package/docs/api/interfaces/TabsTriggerProps.md +1 -1
  183. package/docs/api/interfaces/TextareaProps.md +1 -1
  184. package/docs/api/interfaces/ToastActionElement.md +1 -1
  185. package/docs/api/interfaces/ToastProps.md +1 -1
  186. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  187. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  188. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  189. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  190. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  191. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  192. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  193. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  194. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  195. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  196. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
  197. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  198. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  199. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  200. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  201. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  202. package/docs/api/interfaces/UserEventAccess.md +1 -1
  203. package/docs/api/interfaces/UserMenuProps.md +1 -1
  204. package/docs/api/interfaces/UserProfile.md +1 -1
  205. package/docs/api/modules.md +318 -59
  206. package/docs/best-practices/performance.md +11 -0
  207. package/docs/getting-started/examples/README.md +2 -2
  208. package/docs/implementation-guides/file-upload-storage.md +29 -0
  209. package/docs/implementation-guides/public-pages.md +140 -1230
  210. package/docs/rbac/README.md +2 -1
  211. package/docs/rbac/api-reference.md +11 -0
  212. package/docs/rbac/performance.md +320 -0
  213. package/docs/standards/01-architecture-standard.md +5 -0
  214. package/docs/standards/05-security-standard.md +14 -0
  215. package/docs/standards/07-rbac-and-rls-standard.md +356 -0
  216. package/package.json +1 -1
  217. package/src/__tests__/public-recipe-view.test.ts +199 -0
  218. package/src/__tests__/rls-policies.test.ts +333 -0
  219. package/src/components/AddressField/AddressField.test.tsx +411 -0
  220. package/src/components/AddressField/AddressField.tsx +323 -0
  221. package/src/components/AddressField/README.md +336 -0
  222. package/src/components/AddressField/index.ts +10 -0
  223. package/src/components/AddressField/types.ts +65 -0
  224. package/src/components/FileDisplay/FileDisplay.test.tsx +454 -0
  225. package/src/components/FileDisplay/FileDisplay.tsx +28 -1
  226. package/src/components/index.ts +2 -0
  227. package/src/hooks/__tests__/useFileDisplay.unit.test.ts +30 -5
  228. package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +11 -10
  229. package/src/hooks/__tests__/usePublicFileDisplay.test.ts +31 -6
  230. package/src/hooks/index.ts +6 -0
  231. package/src/hooks/public/usePublicFileDisplay.ts +8 -10
  232. package/src/hooks/useAddressAutocomplete.test.ts +318 -0
  233. package/src/hooks/useAddressAutocomplete.ts +268 -0
  234. package/src/hooks/useFileDisplay.ts +3 -15
  235. package/src/hooks/useFileReference.test.ts +20 -3
  236. package/src/hooks/useFileReference.ts +3 -24
  237. package/src/hooks/useFileUrlCache.ts +246 -0
  238. package/src/hooks/useInactivityTracker.ts +31 -20
  239. package/src/hooks/useOrganisationSecurity.test.ts +10 -7
  240. package/src/hooks/useOrganisationSecurity.ts +3 -3
  241. package/src/hooks/useQueryCache.ts +315 -0
  242. package/src/index.ts +2 -0
  243. package/src/providers/services/EventServiceProvider.tsx +4 -1
  244. package/src/rbac/api.test.ts +21 -6
  245. package/src/rbac/api.ts +32 -11
  246. package/src/rbac/audit-batched.ts +223 -0
  247. package/src/rbac/audit-enhanced.ts +2 -2
  248. package/src/rbac/audit.test.ts +6 -5
  249. package/src/rbac/audit.ts +34 -6
  250. package/src/rbac/cache-invalidation.ts +63 -12
  251. package/src/rbac/cache.test.ts +2 -2
  252. package/src/rbac/cache.ts +61 -14
  253. package/src/rbac/components/PagePermissionGuard.tsx +19 -10
  254. package/src/rbac/components/__tests__/PagePermissionGuard.performance.test.tsx +248 -0
  255. package/src/rbac/config.ts +9 -0
  256. package/src/rbac/engine.ts +2 -21
  257. package/src/rbac/hooks/usePermissions.ts +21 -5
  258. package/src/rbac/index.ts +19 -0
  259. package/src/rbac/performance.ts +210 -0
  260. package/src/rbac/request-deduplication.ts +87 -0
  261. package/src/rbac/utils/deep-equal.ts +93 -0
  262. package/src/services/OrganisationService.ts +5 -4
  263. package/src/types/file-reference.ts +0 -1
  264. package/src/utils/file-reference/__tests__/file-reference.test.ts +31 -4
  265. package/src/utils/file-reference/index.ts +44 -15
  266. package/src/utils/google-places/googlePlacesUtils.test.ts +403 -0
  267. package/src/utils/google-places/googlePlacesUtils.ts +475 -0
  268. package/src/utils/google-places/index.ts +26 -0
  269. package/src/utils/google-places/loadGoogleMapsScript.ts +207 -0
  270. package/src/utils/google-places/types.ts +94 -0
  271. package/src/utils/index.ts +23 -0
  272. package/src/utils/request-deduplication.ts +165 -0
  273. package/src/utils/storage/helpers.ts +143 -4
  274. package/dist/chunk-445GEP27.js.map +0 -1
  275. package/dist/chunk-FMUCXFII.js +0 -76
  276. package/dist/chunk-FMUCXFII.js.map +0 -1
  277. package/dist/chunk-FSFQFJCU.js.map +0 -1
  278. package/dist/chunk-FXFJRTKI.js.map +0 -1
  279. package/dist/chunk-GRIQLQ52.js.map +0 -1
  280. package/dist/chunk-HDCUMOOI.js.map +0 -1
  281. package/dist/chunk-OALXJH4Y.js.map +0 -1
  282. package/dist/chunk-TC7D3CR3.js.map +0 -1
  283. package/dist/chunk-U6WNSFX5.js.map +0 -1
  284. /package/dist/{DataTable-IX2NBUTP.js.map → DataTable-GUFUNZ3N.js.map} +0 -0
  285. /package/dist/{UnifiedAuthProvider-A4BCQRJY.js.map → UnifiedAuthProvider-643PUAIM.js.map} +0 -0
  286. /package/dist/{api-BMFCXVQX.js.map → api-YP7XD5L6.js.map} +0 -0
  287. /package/dist/{audit-WRS3KJKI.js.map → audit-B5P6FFIR.js.map} +0 -0
  288. /package/dist/{chunk-HGPQUCBC.js.map → chunk-2UUZZJFT.js.map} +0 -0
  289. /package/dist/{chunk-DAGICKHT.js.map → chunk-DDM4CCYT.js.map} +0 -0
  290. /package/dist/{chunk-XAUHJD3L.js.map → chunk-E7UAOUMY.js.map} +0 -0
@@ -96,7 +96,7 @@ The RBAC system uses a **database-first architecture** where all permission logi
96
96
  ## 🎯 Key Features
97
97
 
98
98
  - **🔐 Secure by Default** - Organisation context enforced, RLS integrated, database-first API
99
- - **⚡ High Performance** - Intelligent caching with 60s TTL, optimized RPC calls
99
+ - **⚡ High Performance** - Intelligent two-tier caching (60s + 5min), request deduplication, batched audit logging, optimized RPC calls
100
100
  - **🎨 React Integration** - Hooks and components for easy UI integration
101
101
  - **🔄 Real-time Updates** - Automatic cache invalidation on permission changes
102
102
  - **📊 Audit Logging** - Complete audit trail for all permission checks
@@ -422,6 +422,7 @@ When database connection is lost:
422
422
  - **[API Reference](./api-reference.md)** - Explore all available APIs
423
423
  - **[Examples](./examples.md)** - See real-world usage patterns
424
424
  - **[Advanced Patterns](./advanced-patterns.md)** - Learn optimization techniques
425
+ - **[Performance Guide](./performance.md)** - Performance optimizations and configuration
425
426
 
426
427
  ## 🆘 Need Help?
427
428
 
@@ -331,6 +331,17 @@ function UsersPage() {
331
331
 
332
332
  4. **Error Handling**: If permission check fails, the component shows the `fallback`. Check browser console for `[PagePermissionGuard]` logs to debug issues.
333
333
 
334
+ #### Performance Optimizations
335
+
336
+ `PagePermissionGuard` includes built-in performance optimizations:
337
+
338
+ - **Request Deduplication**: Multiple instances checking the same permission share network requests
339
+ - **Enhanced Caching**: Two-tier caching (60s short-term + 5min session cache for page-level checks)
340
+ - **Batched Audit Logging**: Audit events are automatically batched to reduce network requests
341
+ - **Memoization**: Component is memoized with deep equality checks to prevent unnecessary re-renders
342
+
343
+ These optimizations reduce network requests from 1,200+ to <50 per page load. See [RBAC Performance Guide](../rbac/performance.md) for details.
344
+
334
345
  ### NavigationGuard
335
346
 
336
347
  Conditionally render navigation items based on permissions.
@@ -0,0 +1,320 @@
1
+ ---
2
+ lastUpdated: 2025-01-26T00:00:00+11:00
3
+ version: 0.5.186
4
+ reviewedBy: documentation-standards-audit
5
+ ---
6
+
7
+ # RBAC Performance Optimizations
8
+
9
+ > **📚 RBAC Performance Guide** | [← Back to RBAC Documentation](./README.md) | [API Reference](./api-reference.md)
10
+
11
+ The RBAC system includes comprehensive performance optimizations to minimize network requests and improve page load times. This guide explains how these optimizations work and how to configure them.
12
+
13
+ ## Overview
14
+
15
+ The RBAC performance optimizations address the common issue of excessive network requests when using `PagePermissionGuard` and other RBAC components. Without optimizations, a single page load could generate 1,200+ network requests. With optimizations enabled, this is reduced to <50 requests per page load.
16
+
17
+ ## Performance Features
18
+
19
+ ### 1. Request Deduplication
20
+
21
+ **Problem**: Multiple components checking the same permission simultaneously make separate network requests.
22
+
23
+ **Solution**: Request deduplication shares in-flight permission check requests across all components. When multiple `PagePermissionGuard` instances check the same permission at the same time, they share a single network request.
24
+
25
+ **How it works**:
26
+ - When a permission check is requested, the system checks if an identical request is already in-flight
27
+ - If found, the existing promise is returned instead of making a new request
28
+ - The deduplication map is automatically cleaned up when requests complete
29
+
30
+ **Example**:
31
+ ```tsx
32
+ // Three components checking the same permission
33
+ <PagePermissionGuard pageName="dashboard" operation="read">
34
+ <Component1 />
35
+ </PagePermissionGuard>
36
+ <PagePermissionGuard pageName="dashboard" operation="read">
37
+ <Component2 />
38
+ </PagePermissionGuard>
39
+ <PagePermissionGuard pageName="dashboard" operation="read">
40
+ <Component3 />
41
+ </PagePermissionGuard>
42
+ // Result: Only 1 network request instead of 3
43
+ ```
44
+
45
+ **Configuration**: Enabled by default. Can be disabled via configuration:
46
+ ```typescript
47
+ setupRBAC(supabase, {
48
+ performance: {
49
+ enableRequestDeduplication: false, // Disable deduplication
50
+ },
51
+ });
52
+ ```
53
+
54
+ ### 2. Enhanced Caching
55
+
56
+ **Problem**: Short cache TTL (60 seconds) causes frequent re-checks, especially for stable page-level permissions.
57
+
58
+ **Solution**: Two-tier caching strategy with session-level cache for page-level permissions.
59
+
60
+ **Cache Tiers**:
61
+ - **Short-term cache**: 60 seconds for frequently changing permissions
62
+ - **Session cache**: 5 minutes for stable page-level permissions
63
+
64
+ **How it works**:
65
+ - Permission checks first look in the short-term cache
66
+ - If not found, check the session cache (for page-level checks)
67
+ - Page-level permission checks automatically use session cache
68
+ - Cache is invalidated on user/org/event changes
69
+
70
+ **Example**:
71
+ ```typescript
72
+ // First check: Network request + cache result
73
+ await isPermittedCached({ userId, scope, permission: 'read:page.dashboard' });
74
+
75
+ // Subsequent checks within 5 minutes: Cache hit (no network request)
76
+ await isPermittedCached({ userId, scope, permission: 'read:page.dashboard' });
77
+ ```
78
+
79
+ **Configuration**:
80
+ ```typescript
81
+ setupRBAC(supabase, {
82
+ cache: {
83
+ ttl: 60000, // Short-term cache TTL (default: 60s)
84
+ sessionTtl: 300000, // Session cache TTL (default: 5min)
85
+ },
86
+ });
87
+ ```
88
+
89
+ ### 3. Batched Audit Logging
90
+
91
+ **Problem**: Every permission check generates a separate audit log request, even for cached checks.
92
+
93
+ **Solution**: Batched audit logging queues events and sends them in batches, and skips logging for cached checks.
94
+
95
+ **How it works**:
96
+ - Audit events are queued instead of being sent immediately
97
+ - Events are batched by time window (default: 100ms) or batch size (default: 10 events)
98
+ - Cached permission checks skip audit logging entirely (only cache misses are logged)
99
+ - Batches are automatically flushed when the window expires or batch size is reached
100
+
101
+ **Example**:
102
+ ```typescript
103
+ // 10 permission checks in quick succession
104
+ // Without batching: 10 separate audit log requests
105
+ // With batching: 1 batched request with 10 events
106
+ ```
107
+
108
+ **Configuration**:
109
+ ```typescript
110
+ setupRBAC(supabase, {
111
+ audit: {
112
+ batched: true, // Enable batched logging (default: true)
113
+ batchWindow: 100, // Time window in ms (default: 100ms)
114
+ batchSize: 10, // Maximum batch size (default: 10)
115
+ },
116
+ performance: {
117
+ enableBatchedAuditLogging: true, // Enable/disable (default: true)
118
+ },
119
+ });
120
+ ```
121
+
122
+ ### 4. Improved Memoization
123
+
124
+ **Problem**: Scope objects are recreated on every render, causing unnecessary permission re-checks.
125
+
126
+ **Solution**: Deep equality checks for scope objects and React.memo for components.
127
+
128
+ **How it works**:
129
+ - `PagePermissionGuard` uses `React.memo` to prevent unnecessary re-renders
130
+ - Scope objects are compared using deep equality instead of reference equality
131
+ - Permission strings are memoized to prevent recreation
132
+ - Only re-check permissions when dependencies actually change
133
+
134
+ **Example**:
135
+ ```tsx
136
+ // Component re-renders with same scope object
137
+ // Without memoization: Permission re-checked
138
+ // With memoization: Cached result used, no re-check
139
+ ```
140
+
141
+ **Configuration**: Automatic, no configuration needed.
142
+
143
+ ### 5. Performance Monitoring
144
+
145
+ **Problem**: No visibility into performance metrics and optimization effectiveness.
146
+
147
+ **Solution**: Built-in performance monitoring tracks key metrics.
148
+
149
+ **Metrics Tracked**:
150
+ - Total permission checks
151
+ - Cache hit rate
152
+ - Request deduplication rate
153
+ - Network request count
154
+ - Average response time
155
+ - Batched vs individual audit events
156
+
157
+ **Usage**:
158
+ ```typescript
159
+ import {
160
+ enablePerformanceMonitoring,
161
+ getPerformanceMetrics,
162
+ getPerformanceSummary
163
+ } from '@jmruthers/pace-core/rbac';
164
+
165
+ // Enable monitoring
166
+ enablePerformanceMonitoring();
167
+
168
+ // Get metrics
169
+ const metrics = getPerformanceMetrics();
170
+ console.log('Cache hit rate:', metrics.cacheHitRate);
171
+ console.log('Network requests:', metrics.networkRequests);
172
+
173
+ // Get formatted summary
174
+ console.log(getPerformanceSummary());
175
+ ```
176
+
177
+ **Configuration**:
178
+ ```typescript
179
+ setupRBAC(supabase, {
180
+ performance: {
181
+ enablePerformanceTracking: true, // Enable in development
182
+ },
183
+ });
184
+ ```
185
+
186
+ ## Configuration
187
+
188
+ All performance optimizations can be configured when setting up RBAC:
189
+
190
+ ```typescript
191
+ import { setupRBAC } from '@jmruthers/pace-core/rbac';
192
+
193
+ setupRBAC(supabase, {
194
+ // Cache configuration
195
+ cache: {
196
+ ttl: 60000, // Short-term cache TTL (default: 60s)
197
+ sessionTtl: 300000, // Session cache TTL (default: 5min)
198
+ enabled: true, // Enable caching (default: true)
199
+ },
200
+
201
+ // Audit configuration
202
+ audit: {
203
+ enabled: true, // Enable audit logging (default: true)
204
+ batched: true, // Enable batched logging (default: true)
205
+ batchWindow: 100, // Batch time window in ms (default: 100ms)
206
+ batchSize: 10, // Maximum batch size (default: 10)
207
+ },
208
+
209
+ // Performance configuration
210
+ performance: {
211
+ enableRequestDeduplication: true, // Enable deduplication (default: true)
212
+ enableBatchedAuditLogging: true, // Enable batched audit (default: true)
213
+ enablePerformanceTracking: false, // Enable monitoring (default: false in production)
214
+ },
215
+ });
216
+ ```
217
+
218
+ ## Expected Performance Improvements
219
+
220
+ With all optimizations enabled:
221
+
222
+ | Metric | Before | After | Improvement |
223
+ |--------|--------|-------|-------------|
224
+ | Network Requests | 1,200+ | <50 | 96% reduction |
225
+ | Page Load Time | 1+ minute | <5 seconds | 92% reduction |
226
+ | Bandwidth | 13+ MB | <1 MB | 92% reduction |
227
+ | Cache Hit Rate | N/A | >90% | - |
228
+ | Audit Log Requests | 1,200+ | <50 | 96% reduction |
229
+
230
+ ## Best Practices
231
+
232
+ ### 1. Enable All Optimizations
233
+
234
+ All optimizations are enabled by default. Only disable them if you have a specific reason:
235
+
236
+ ```typescript
237
+ // ✅ Good: Use defaults
238
+ setupRBAC(supabase);
239
+
240
+ // ❌ Avoid: Disabling optimizations without reason
241
+ setupRBAC(supabase, {
242
+ performance: {
243
+ enableRequestDeduplication: false, // Only if you have a specific need
244
+ },
245
+ });
246
+ ```
247
+
248
+ ### 2. Monitor Performance in Development
249
+
250
+ Enable performance tracking during development to identify bottlenecks:
251
+
252
+ ```typescript
253
+ setupRBAC(supabase, {
254
+ performance: {
255
+ enablePerformanceTracking: import.meta.env.MODE === 'development',
256
+ },
257
+ });
258
+ ```
259
+
260
+ ### 3. Adjust Cache TTL Based on Use Case
261
+
262
+ For applications with frequently changing permissions, reduce cache TTL:
263
+
264
+ ```typescript
265
+ setupRBAC(supabase, {
266
+ cache: {
267
+ ttl: 30000, // 30 seconds for frequently changing permissions
268
+ sessionTtl: 180000, // 3 minutes for page-level checks
269
+ },
270
+ });
271
+ ```
272
+
273
+ ### 4. Tune Batch Settings for High-Volume Apps
274
+
275
+ For applications with many permission checks, adjust batch settings:
276
+
277
+ ```typescript
278
+ setupRBAC(supabase, {
279
+ audit: {
280
+ batchWindow: 50, // Shorter window for faster batching
281
+ batchSize: 20, // Larger batches for high volume
282
+ },
283
+ });
284
+ ```
285
+
286
+ ## Troubleshooting
287
+
288
+ ### High Network Request Count
289
+
290
+ If you're still seeing high request counts:
291
+
292
+ 1. **Check cache hit rate**: Use performance monitoring to verify cache is working
293
+ 2. **Verify deduplication**: Ensure multiple components aren't bypassing deduplication
294
+ 3. **Check audit batching**: Verify batched audit logging is enabled
295
+ 4. **Review scope changes**: Ensure scope objects aren't being recreated unnecessarily
296
+
297
+ ### Low Cache Hit Rate
298
+
299
+ If cache hit rate is low:
300
+
301
+ 1. **Check cache TTL**: Verify cache TTL settings are appropriate
302
+ 2. **Review cache invalidation**: Ensure cache isn't being invalidated too frequently
303
+ 3. **Verify session cache**: Check that page-level checks are using session cache
304
+ 4. **Monitor scope changes**: Frequent scope changes will reduce cache effectiveness
305
+
306
+ ### Performance Monitoring Not Working
307
+
308
+ If performance monitoring isn't showing data:
309
+
310
+ 1. **Verify it's enabled**: Check `enablePerformanceTracking` is set to `true`
311
+ 2. **Check timing**: Metrics accumulate over time, check after multiple permission checks
312
+ 3. **Review console**: Check for any errors in the console
313
+
314
+ ## Related Documentation
315
+
316
+ - [PagePermissionGuard API Reference](./api-reference.md#pagepermissionguard) - Component API
317
+ - [RBAC Configuration](./api-reference.md#configuration) - Configuration options
318
+ - [Performance Best Practices](../best-practices/performance.md) - General performance guide
319
+ - [RBAC Getting Started](./getting-started.md) - Getting started guide
320
+
@@ -11,6 +11,11 @@ Define the core architectural principles for pace-core so that components, APIs,
11
11
  - Secure by default
12
12
  - Performance-conscious
13
13
 
14
+ ## Performance Requirements
15
+ - **RLS policies must use helper functions** - Never use subqueries in RLS policies as they cause N+1 query patterns
16
+ - **Database migrations must be tested** - Verify migrations don't cause query timeouts or performance degradation
17
+ - **Monitor query performance** - Use EXPLAIN ANALYZE to verify RLS policies don't create expensive execution plans
18
+
14
19
  ## Boundaries
15
20
  ### In scope
16
21
  - UI primitives
@@ -13,6 +13,18 @@
13
13
  - Never store secrets in code
14
14
  - Use safe error messaging
15
15
 
16
+ ## RLS Policy Performance Rules
17
+ - **NEVER use subqueries in RLS policies** - They execute for every row check and cause severe performance degradation
18
+ - **ALWAYS use helper functions** - Create STABLE SECURITY DEFINER functions for lookups (e.g., `get_app_id()`, `get_form_event_id()`)
19
+ - **Helper functions must be**:
20
+ - `STABLE` - Results are consistent within a transaction
21
+ - `SECURITY DEFINER` - Bypass RLS to avoid recursion
22
+ - `SET search_path TO 'public'` - Prevent search path injection
23
+ - **Test RLS policies** - Verify they don't cause query timeouts or N+1 query patterns
24
+ - **Monitor performance** - Watch for slow queries after RLS policy changes
25
+
26
+ **See [RBAC and RLS Standard](./07-rbac-and-rls-standard.md) for detailed RLS policy patterns and helper function documentation.**
27
+
16
28
  ## Logging Rules
17
29
  Allowed:
18
30
  - IDs
@@ -28,3 +40,5 @@ Forbidden:
28
40
  - Ensure no sensitive logs
29
41
  - Replace raw errors with ApiError
30
42
  - Validate input shapes
43
+ - **RLS policies use helper functions, not subqueries**
44
+ - **Helper functions are STABLE and SECURITY DEFINER**