@jmruthers/pace-core 0.5.184 → 0.5.186

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 (319) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +60 -1
  3. package/core-usage-manifest.json +312 -0
  4. package/dist/{DataTable-QAB34V6K.js → DataTable-IX2NBUTP.js} +6 -6
  5. package/dist/{DataTable-Bz8ffqyA.d.ts → DataTable-Z9NLVJh0.d.ts} +1 -1
  6. package/dist/{index-Bl--n7-T.d.ts → PublicPageProvider-DIzEzwKl.d.ts} +23 -10
  7. package/dist/{UnifiedAuthProvider-7F6T4B6K.js → UnifiedAuthProvider-A4BCQRJY.js} +4 -2
  8. package/dist/{UnifiedAuthProvider-F86d7dSi.d.ts → UnifiedAuthProvider-BG0AL5eE.d.ts} +2 -1
  9. package/dist/{api-ROMBCNKU.js → api-BMFCXVQX.js} +2 -2
  10. package/dist/{chunk-RA3JUFMW.js → chunk-445GEP27.js} +154 -4
  11. package/dist/{chunk-RA3JUFMW.js.map → chunk-445GEP27.js.map} +1 -1
  12. package/dist/{chunk-W22JP75J.js → chunk-DAGICKHT.js} +9 -7
  13. package/dist/chunk-DAGICKHT.js.map +1 -0
  14. package/dist/{chunk-FUEYYMX5.js → chunk-FXFJRTKI.js} +24 -3
  15. package/dist/chunk-FXFJRTKI.js.map +1 -0
  16. package/dist/{chunk-CSOFYHAG.js → chunk-GRIQLQ52.js} +374 -60
  17. package/dist/chunk-GRIQLQ52.js.map +1 -0
  18. package/dist/{chunk-NQPMQGS2.js → chunk-HDCUMOOI.js} +497 -399
  19. package/dist/chunk-HDCUMOOI.js.map +1 -0
  20. package/dist/chunk-HESYZWZW.js +388 -0
  21. package/dist/chunk-HESYZWZW.js.map +1 -0
  22. package/dist/{chunk-QUVSNGIP.js → chunk-HGPQUCBC.js} +34 -9
  23. package/dist/{chunk-QUVSNGIP.js.map → chunk-HGPQUCBC.js.map} +1 -1
  24. package/dist/{chunk-PWAHJW4G.js → chunk-OALXJH4Y.js} +86 -33
  25. package/dist/chunk-OALXJH4Y.js.map +1 -0
  26. package/dist/{chunk-MI7HBHN3.js → chunk-TC7D3CR3.js} +89 -9
  27. package/dist/chunk-TC7D3CR3.js.map +1 -0
  28. package/dist/chunk-THRPYOFK.js +215 -0
  29. package/dist/chunk-THRPYOFK.js.map +1 -0
  30. package/dist/{chunk-M7W4CP3M.js → chunk-U6WNSFX5.js} +2 -1
  31. package/dist/chunk-U6WNSFX5.js.map +1 -0
  32. package/dist/{chunk-UHNYIBXL.js → chunk-UQWSHFVX.js} +1 -1
  33. package/dist/chunk-UQWSHFVX.js.map +1 -0
  34. package/dist/{chunk-QCDXODCA.js → chunk-XAUHJD3L.js} +2 -2
  35. package/dist/components.d.ts +182 -6
  36. package/dist/components.js +157 -11
  37. package/dist/components.js.map +1 -1
  38. package/dist/{database.generated-CBmg2950.d.ts → database.generated-DI89OQeI.d.ts} +63 -9
  39. package/dist/eslint-rules/pace-core-compliance.cjs +406 -0
  40. package/dist/{file-reference-D06mEEWW.d.ts → file-reference-PRTSLxKx.d.ts} +10 -1
  41. package/dist/hooks.d.ts +52 -15
  42. package/dist/hooks.js +12 -22
  43. package/dist/hooks.js.map +1 -1
  44. package/dist/index.d.ts +12 -12
  45. package/dist/index.js +82 -18
  46. package/dist/index.js.map +1 -1
  47. package/dist/providers.d.ts +1 -1
  48. package/dist/providers.js +3 -1
  49. package/dist/rbac/index.d.ts +206 -15
  50. package/dist/rbac/index.js +28 -6
  51. package/dist/timezone-_pgH8qrY.d.ts +530 -0
  52. package/dist/{types-_x1f4QBF.d.ts → types-DUyCRSTj.d.ts} +1 -1
  53. package/dist/types.d.ts +2 -2
  54. package/dist/types.js +1 -1
  55. package/dist/{usePublicRouteParams-JJczomYq.d.ts → usePublicRouteParams-D71QLlg4.d.ts} +114 -3
  56. package/dist/utils.d.ts +110 -152
  57. package/dist/utils.js +128 -138
  58. package/dist/utils.js.map +1 -1
  59. package/docs/api/README.md +60 -1
  60. package/docs/api/classes/ColumnFactory.md +1 -1
  61. package/docs/api/classes/ErrorBoundary.md +1 -1
  62. package/docs/api/classes/InvalidScopeError.md +1 -1
  63. package/docs/api/classes/Logger.md +178 -0
  64. package/docs/api/classes/MissingUserContextError.md +1 -1
  65. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  66. package/docs/api/classes/PermissionDeniedError.md +1 -1
  67. package/docs/api/classes/RBACAuditManager.md +2 -2
  68. package/docs/api/classes/RBACCache.md +1 -1
  69. package/docs/api/classes/RBACEngine.md +2 -2
  70. package/docs/api/classes/RBACError.md +1 -1
  71. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  72. package/docs/api/classes/SecureSupabaseClient.md +5 -5
  73. package/docs/api/classes/StorageUtils.md +1 -1
  74. package/docs/api/enums/FileCategory.md +1 -1
  75. package/docs/api/enums/LogLevel.md +54 -0
  76. package/docs/api/enums/RBACErrorCode.md +1 -1
  77. package/docs/api/enums/RPCFunction.md +1 -1
  78. package/docs/api/interfaces/AggregateConfig.md +1 -1
  79. package/docs/api/interfaces/BadgeProps.md +1 -1
  80. package/docs/api/interfaces/ButtonProps.md +1 -1
  81. package/docs/api/interfaces/CalendarProps.md +18 -2
  82. package/docs/api/interfaces/CardProps.md +1 -1
  83. package/docs/api/interfaces/ColorPalette.md +1 -1
  84. package/docs/api/interfaces/ColorShade.md +1 -1
  85. package/docs/api/interfaces/ComplianceResult.md +30 -0
  86. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  87. package/docs/api/interfaces/DataRecord.md +1 -1
  88. package/docs/api/interfaces/DataTableAction.md +1 -1
  89. package/docs/api/interfaces/DataTableColumn.md +1 -1
  90. package/docs/api/interfaces/DataTableProps.md +1 -1
  91. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  92. package/docs/api/interfaces/DatabaseComplianceResult.md +85 -0
  93. package/docs/api/interfaces/DatabaseIssue.md +41 -0
  94. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  95. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  96. package/docs/api/interfaces/EventAppRoleData.md +6 -6
  97. package/docs/api/interfaces/ExportColumn.md +1 -1
  98. package/docs/api/interfaces/ExportOptions.md +1 -1
  99. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  100. package/docs/api/interfaces/FileMetadata.md +1 -1
  101. package/docs/api/interfaces/FileReference.md +1 -1
  102. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  103. package/docs/api/interfaces/FileUploadOptions.md +48 -8
  104. package/docs/api/interfaces/FileUploadProps.md +46 -13
  105. package/docs/api/interfaces/FooterProps.md +1 -1
  106. package/docs/api/interfaces/FormFieldProps.md +1 -1
  107. package/docs/api/interfaces/FormProps.md +1 -1
  108. package/docs/api/interfaces/GrantEventAppRoleParams.md +9 -9
  109. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  110. package/docs/api/interfaces/InputProps.md +1 -1
  111. package/docs/api/interfaces/LabelProps.md +1 -1
  112. package/docs/api/interfaces/LoggerConfig.md +62 -0
  113. package/docs/api/interfaces/LoginFormProps.md +1 -1
  114. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  115. package/docs/api/interfaces/NavigationContextType.md +1 -1
  116. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  117. package/docs/api/interfaces/NavigationItem.md +1 -1
  118. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  119. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  120. package/docs/api/interfaces/Organisation.md +1 -1
  121. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  122. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  123. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  124. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  125. package/docs/api/interfaces/PaceAppLayoutProps.md +36 -23
  126. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  127. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  128. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  129. package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
  130. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  131. package/docs/api/interfaces/PaletteData.md +1 -1
  132. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  133. package/docs/api/interfaces/ProgressProps.md +1 -1
  134. package/docs/api/interfaces/ProtectedRouteProps.md +6 -6
  135. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  136. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  137. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  138. package/docs/api/interfaces/QuickFix.md +52 -0
  139. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  140. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  141. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  142. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  143. package/docs/api/interfaces/RBACConfig.md +4 -4
  144. package/docs/api/interfaces/RBACContext.md +1 -1
  145. package/docs/api/interfaces/RBACLogger.md +1 -1
  146. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  147. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  148. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  149. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  150. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  151. package/docs/api/interfaces/RBACResult.md +1 -1
  152. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  153. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  154. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  155. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  156. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  157. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  158. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  159. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  160. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  161. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  162. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  163. package/docs/api/interfaces/RevokeEventAppRoleParams.md +7 -7
  164. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  165. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  166. package/docs/api/interfaces/RoleManagementResult.md +5 -5
  167. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  168. package/docs/api/interfaces/RouteConfig.md +1 -1
  169. package/docs/api/interfaces/RuntimeComplianceResult.md +55 -0
  170. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  171. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  172. package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
  173. package/docs/api/interfaces/SetupIssue.md +41 -0
  174. package/docs/api/interfaces/StorageConfig.md +1 -1
  175. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  176. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  177. package/docs/api/interfaces/StorageListOptions.md +1 -1
  178. package/docs/api/interfaces/StorageListResult.md +1 -1
  179. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  180. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  181. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  182. package/docs/api/interfaces/StyleImport.md +1 -1
  183. package/docs/api/interfaces/SwitchProps.md +1 -1
  184. package/docs/api/interfaces/TabsContentProps.md +1 -1
  185. package/docs/api/interfaces/TabsListProps.md +1 -1
  186. package/docs/api/interfaces/TabsProps.md +1 -1
  187. package/docs/api/interfaces/TabsTriggerProps.md +1 -1
  188. package/docs/api/interfaces/TextareaProps.md +1 -1
  189. package/docs/api/interfaces/ToastActionElement.md +1 -1
  190. package/docs/api/interfaces/ToastProps.md +1 -1
  191. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  192. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  193. package/docs/api/interfaces/UseFormDialogOptions.md +62 -0
  194. package/docs/api/interfaces/UseFormDialogReturn.md +117 -0
  195. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  196. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  197. package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
  198. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  199. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  200. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  201. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
  202. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  203. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  204. package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
  205. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  206. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  207. package/docs/api/interfaces/UserEventAccess.md +1 -1
  208. package/docs/api/interfaces/UserMenuProps.md +1 -1
  209. package/docs/api/interfaces/UserProfile.md +1 -1
  210. package/docs/api/modules.md +746 -50
  211. package/docs/api-reference/components.md +26 -12
  212. package/docs/api-reference/hooks.md +111 -0
  213. package/docs/api-reference/rpc-functions.md +1 -1
  214. package/docs/api-reference/utilities.md +184 -0
  215. package/docs/getting-started/installation-guide.md +75 -16
  216. package/docs/getting-started/quick-start.md +61 -11
  217. package/docs/implementation-guides/authentication.md +88 -12
  218. package/docs/implementation-guides/file-reference-system.md +26 -3
  219. package/docs/implementation-guides/file-upload-storage.md +30 -1
  220. package/docs/rbac/README.md +1 -0
  221. package/docs/rbac/compliance/compliance-guide.md +544 -0
  222. package/docs/rbac/getting-started.md +158 -33
  223. package/docs/standards/pace-core-compliance.md +432 -0
  224. package/eslint-config-pace-core.cjs +93 -0
  225. package/package.json +15 -3
  226. package/scripts/analyze-bundle.js +232 -0
  227. package/scripts/build-css.js +56 -0
  228. package/scripts/build-docs-incremental.js +1015 -0
  229. package/scripts/check-pace-core-compliance.cjs +2353 -0
  230. package/scripts/check-pace-core-compliance.js +512 -0
  231. package/scripts/generate-docs.js +157 -0
  232. package/scripts/setup-build-cache.js +73 -0
  233. package/scripts/utils/command-runner.js +131 -0
  234. package/scripts/utils/env.js +33 -0
  235. package/scripts/utils/index.js +10 -0
  236. package/scripts/utils/logger.js +88 -0
  237. package/scripts/utils/path-helpers.js +37 -0
  238. package/scripts/validate-formats.js +133 -0
  239. package/scripts/validate-master.js +155 -0
  240. package/scripts/validate-pre-publish.js +140 -0
  241. package/scripts/validate-theme.js +142 -0
  242. package/src/components/Calendar/Calendar.tsx +8 -1
  243. package/src/components/Card/Card.tsx +47 -8
  244. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +314 -0
  245. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +126 -0
  246. package/src/components/DatePickerWithTimezone/README.md +135 -0
  247. package/src/components/DatePickerWithTimezone/index.ts +10 -0
  248. package/src/components/DateTimeField/DateTimeField.test.tsx +358 -0
  249. package/src/components/DateTimeField/DateTimeField.tsx +232 -0
  250. package/src/components/DateTimeField/README.md +148 -0
  251. package/src/components/DateTimeField/index.ts +10 -0
  252. package/src/components/FileUpload/FileUpload.test.tsx +2 -0
  253. package/src/components/FileUpload/FileUpload.tsx +10 -1
  254. package/src/components/Header/Header.test.tsx +47 -18
  255. package/src/components/Header/Header.tsx +22 -7
  256. package/src/components/PaceAppLayout/PaceAppLayout.tsx +29 -20
  257. package/src/components/PaceAppLayout/README.md +9 -0
  258. package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +37 -8
  259. package/src/components/ProtectedRoute/ProtectedRoute.tsx +146 -5
  260. package/src/components/index.ts +8 -0
  261. package/src/eslint-rules/pace-core-compliance.cjs +406 -0
  262. package/src/eslint-rules/pace-core-compliance.js +640 -0
  263. package/src/hooks/__tests__/useFormDialog.test.ts +478 -0
  264. package/src/hooks/index.ts +5 -0
  265. package/src/hooks/useFileReference.test.ts +2 -0
  266. package/src/hooks/useFormDialog.ts +147 -0
  267. package/src/hooks/usePreventTabReload.ts +106 -0
  268. package/src/hooks/useSecureDataAccess.ts +2 -2
  269. package/src/index.ts +27 -0
  270. package/src/providers/services/OrganisationServiceProvider.tsx +6 -5
  271. package/src/providers/services/UnifiedAuthProvider.tsx +24 -3
  272. package/src/rbac/__tests__/rbac-role-isolation.test.ts +456 -0
  273. package/src/rbac/__tests__/scenarios.user-role.test.tsx +3 -0
  274. package/src/rbac/compliance/database-validator.ts +165 -0
  275. package/src/rbac/compliance/index.ts +38 -0
  276. package/src/rbac/compliance/quick-fix-suggestions.ts +209 -0
  277. package/src/rbac/compliance/runtime-compliance.ts +77 -0
  278. package/src/rbac/compliance/setup-validator.ts +131 -0
  279. package/src/rbac/components/PagePermissionGuard.tsx +8 -64
  280. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +35 -21
  281. package/src/rbac/docs/event-based-apps.md +285 -0
  282. package/src/rbac/errors.ts +11 -0
  283. package/src/rbac/hooks/useRoleManagement.ts +292 -12
  284. package/src/rbac/index.ts +30 -0
  285. package/src/services/OrganisationService.ts +4 -0
  286. package/src/styles/core.css +5 -5
  287. package/src/types/database.generated.ts +63 -9
  288. package/src/types/file-reference.ts +9 -0
  289. package/src/utils/__tests__/timezone.test.ts +345 -0
  290. package/src/utils/file-reference/__tests__/file-reference.test.ts +60 -4
  291. package/src/utils/file-reference/index.ts +13 -2
  292. package/src/utils/formatting/formatDateTimeTimezone.test.ts +167 -0
  293. package/src/utils/formatting/formatting.ts +179 -0
  294. package/src/utils/index.ts +27 -1
  295. package/src/utils/location/index.ts +16 -0
  296. package/src/utils/location/location.test.ts +286 -0
  297. package/src/utils/location/location.ts +175 -0
  298. package/src/utils/security/secureDataAccess.ts +1 -1
  299. package/src/utils/storage/helpers.ts +68 -0
  300. package/src/utils/timezone/index.ts +17 -0
  301. package/src/utils/timezone/timezone.test.ts +349 -0
  302. package/src/utils/timezone/timezone.ts +281 -0
  303. package/dist/chunk-CSOFYHAG.js.map +0 -1
  304. package/dist/chunk-FUEYYMX5.js.map +0 -1
  305. package/dist/chunk-HKIT6O7W.js +0 -198
  306. package/dist/chunk-HKIT6O7W.js.map +0 -1
  307. package/dist/chunk-KUEN3HFB.js +0 -94
  308. package/dist/chunk-KUEN3HFB.js.map +0 -1
  309. package/dist/chunk-M7W4CP3M.js.map +0 -1
  310. package/dist/chunk-MI7HBHN3.js.map +0 -1
  311. package/dist/chunk-NQPMQGS2.js.map +0 -1
  312. package/dist/chunk-PWAHJW4G.js.map +0 -1
  313. package/dist/chunk-UHNYIBXL.js.map +0 -1
  314. package/dist/chunk-W22JP75J.js.map +0 -1
  315. package/dist/formatting-5wETwiGF.d.ts +0 -162
  316. /package/dist/{DataTable-QAB34V6K.js.map → DataTable-IX2NBUTP.js.map} +0 -0
  317. /package/dist/{UnifiedAuthProvider-7F6T4B6K.js.map → UnifiedAuthProvider-A4BCQRJY.js.map} +0 -0
  318. /package/dist/{api-ROMBCNKU.js.map → api-BMFCXVQX.js.map} +0 -0
  319. /package/dist/{chunk-QCDXODCA.js.map → chunk-XAUHJD3L.js.map} +0 -0
@@ -69,17 +69,64 @@ if (!supabaseUrl || !supabaseAnonKey) {
69
69
  export const supabase = createClient(supabaseUrl, supabaseAnonKey)
70
70
  ```
71
71
 
72
- ### 4. App Setup with Authentication
72
+ ### 4. Configure Vite (CRITICAL)
73
73
 
74
- **CRITICAL**: UnifiedAuthProvider now requires inactivity timeout configuration:
74
+ **⚠️ CRITICAL**: This configuration prevents React context and Router context errors.
75
+
76
+ Add to your `vite.config.ts`:
77
+
78
+ ```typescript
79
+ import { defineConfig } from 'vite';
80
+ import react from '@vitejs/plugin-react';
81
+ import tailwindcss from '@tailwindcss/vite';
82
+ import path from 'path';
83
+
84
+ export default defineConfig({
85
+ plugins: [
86
+ react(),
87
+ tailwindcss({
88
+ content: [
89
+ './src/**/*.{js,ts,jsx,tsx}',
90
+ './node_modules/@jmruthers/pace-core/src/**/*.{js,ts,jsx,tsx}'
91
+ ]
92
+ })
93
+ ],
94
+ resolve: {
95
+ alias: {
96
+ "@": path.resolve(__dirname, "./src"),
97
+ },
98
+ // CRITICAL: Dedupe React and React Router to ensure single instances
99
+ dedupe: ['react', 'react-dom', 'react-router-dom']
100
+ },
101
+ // CRITICAL: Exclude pace-core from pre-bundling to prevent React context mismatches
102
+ optimizeDeps: {
103
+ include: [
104
+ 'react',
105
+ 'react-dom',
106
+ 'react/jsx-runtime'
107
+ ],
108
+ exclude: ['@jmruthers/pace-core', 'react-router-dom']
109
+ },
110
+ });
111
+ ```
112
+
113
+ ### 5. App Setup with Authentication
114
+
115
+ **⚠️ CRITICAL**:
116
+ 1. Provider nesting order matters - follow the exact structure below
117
+ 2. UnifiedAuthProvider requires inactivity timeout configuration
118
+ 3. setupRBAC() must be called before rendering
75
119
 
76
120
  ```tsx
77
121
  // src/main.tsx
78
122
  import React from 'react'
79
123
  import ReactDOM from 'react-dom/client'
80
124
  import { BrowserRouter } from 'react-router-dom'
125
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
81
126
  import {
82
- UnifiedAuthProvider
127
+ UnifiedAuthProvider,
128
+ OrganisationProvider,
129
+ setupRBAC
83
130
  } from '@jmruthers/pace-core'
84
131
  import { supabase } from './lib/supabase'
85
132
  import App from './App.tsx'
@@ -87,17 +134,46 @@ import App from './App.tsx'
87
134
  // CRITICAL: Import the CSS system - includes everything you need
88
135
  import '@jmruthers/pace-core/src/styles/core.css'
89
136
 
137
+ // ⚠️ REQUIRED: Setup RBAC before rendering
138
+ setupRBAC(supabase);
139
+
140
+ const queryClient = new QueryClient();
141
+
90
142
  ReactDOM.createRoot(document.getElementById('root')!).render(
91
143
  <React.StrictMode>
92
- <BrowserRouter>
93
- <UnifiedAuthProvider
94
- supabaseClient={supabase}
95
- appName="my-app"
96
- requireOrganisationContext={true}
97
- idleTimeoutMs={30 * 60 * 1000} // 30 minutes - REQUIRED
98
- warnBeforeMs={60 * 1000} // 60 seconds - REQUIRED
99
- onIdleLogout={() => window.location.href = '/login'} // REQUIRED
100
- >
144
+ {/* CRITICAL: Correct nesting order */}
145
+ <QueryClientProvider client={queryClient}>
146
+ <BrowserRouter>
147
+ <UnifiedAuthProvider
148
+ supabaseClient={supabase}
149
+ appName="my-app"
150
+ requireOrganisationContext={true}
151
+ idleTimeoutMs={30 * 60 * 1000} // 30 minutes - REQUIRED
152
+ warnBeforeMs={60 * 1000} // 60 seconds - REQUIRED
153
+ onIdleLogout={() => window.location.href = '/login'} // REQUIRED
154
+ >
155
+ <OrganisationProvider>
156
+ <App />
157
+ </OrganisationProvider>
158
+ </UnifiedAuthProvider>
159
+ </BrowserRouter>
160
+ </QueryClientProvider>
161
+ </React.StrictMode>
162
+ )
163
+ ```
164
+
165
+ **Provider Nesting Order (CRITICAL):**
166
+ 1. `React.StrictMode` (outermost)
167
+ 2. `QueryClientProvider`
168
+ 3. `BrowserRouter`
169
+ 4. `UnifiedAuthProvider`
170
+ 5. `OrganisationProvider`
171
+ 6. `App` (innermost)
172
+
173
+ **Why this order matters:**
174
+ - `BrowserRouter` must wrap `UnifiedAuthProvider` to provide Router context
175
+ - `UnifiedAuthProvider` must be inside `BrowserRouter` to use Router hooks
176
+ - Wrong nesting causes "useNavigate() may be used only in the context of a <Router>" errors
101
177
  <App />
102
178
  </UnifiedAuthProvider>
103
179
  </BrowserRouter>
@@ -45,14 +45,16 @@ CREATE TABLE file_references (
45
45
 
46
46
  **Organisation-First Structure:**
47
47
  ```
48
- {bucket}/{orgId}/{category}/{filename}
48
+ {bucket}/{orgId}/{folder}/{timestamp-uuid-filename}
49
49
 
50
50
  Examples:
51
51
  - files/org-123/profile_photos/timestamp-uuid-photo.jpg (private)
52
- - files/org-123/id_documents/timestamp-uuid-passport.pdf (private)
52
+ - files/org-123/documents/timestamp-uuid-passport.pdf (private)
53
53
  - public-files/org-123/event_logos/timestamp-uuid-logo.png (public)
54
54
  ```
55
55
 
56
+ **Note:** The `folder` prop determines the storage path, while `category` is stored in the `file_metadata` JSONB field for filtering and metadata purposes. You can use the same value for both (e.g., `category={FileCategory.PROFILE_PHOTOS}` and `folder="profile_photos"`), or use different values if needed.
57
+
56
58
  ### Bucket Selection
57
59
 
58
60
  The system uses two Supabase storage buckets:
@@ -77,7 +79,10 @@ await service.createFileReference({
77
79
  table_name: 'pace_person',
78
80
  record_id: personId,
79
81
  organisation_id: orgId,
82
+ app_id: 'your-app-id',
80
83
  category: FileCategory.PROFILE_PHOTOS,
84
+ folder: 'profile_photos',
85
+ pageContext: 'configuration',
81
86
  is_public: false // Uses 'files' bucket
82
87
  }, file);
83
88
 
@@ -86,7 +91,10 @@ await service.createFileReference({
86
91
  table_name: 'event',
87
92
  record_id: eventId,
88
93
  organisation_id: orgId,
94
+ app_id: 'your-app-id',
89
95
  category: FileCategory.EVENT_LOGOS,
96
+ folder: 'event_logos',
97
+ pageContext: 'configuration',
90
98
  is_public: true // Uses 'public-files' bucket
91
99
  }, file);
92
100
  ```
@@ -136,6 +144,8 @@ import { FileUpload, FileCategory } from '@jmruthers/pace-core';
136
144
  organisation_id={orgId}
137
145
  app_id="your-app-id" // Optional - auto-resolved from app name if not provided
138
146
  category={FileCategory.PROFILE_PHOTOS}
147
+ folder="profile_photos"
148
+ pageContext="configuration"
139
149
  accept="image/*"
140
150
  maxSize={5 * 1024 * 1024}
141
151
  onUploadSuccess={(result) => {
@@ -157,6 +167,8 @@ import { FileUpload, FileCategory } from '@jmruthers/pace-core';
157
167
  organisation_id={orgId}
158
168
  // app_id omitted - will be auto-resolved from app name
159
169
  category={FileCategory.PROFILE_PHOTOS}
170
+ folder="profile_photos"
171
+ pageContext="configuration"
160
172
  accept="image/*"
161
173
  maxSize={5 * 1024 * 1024}
162
174
  showProgress={true}
@@ -191,6 +203,8 @@ import { FileUpload, FileCategory } from '@jmruthers/pace-core';
191
203
  organisation_id={orgId}
192
204
  app_id="your-app-id"
193
205
  category={FileCategory.EVENT_LOGOS}
206
+ folder="event_logos"
207
+ pageContext="configuration"
194
208
  accept="image/*"
195
209
  isPublic={true} // Uploads to public-files bucket
196
210
  showPreview={true}
@@ -210,6 +224,8 @@ import { FileUpload, FileCategory } from '@jmruthers/pace-core';
210
224
  organisation_id={orgId}
211
225
  app_id="your-app-id"
212
226
  category={FileCategory.PROFILE_PHOTOS}
227
+ folder="profile_photos"
228
+ pageContext="configuration"
213
229
  >
214
230
  <div className="custom-upload-ui">
215
231
  <p>Click to upload profile photo</p>
@@ -237,6 +253,8 @@ import { FileDisplay, FileCategory } from '@jmruthers/pace-core';
237
253
  organisation_id={orgId}
238
254
  app_id="your-app-id"
239
255
  category={FileCategory.PROFILE_PHOTOS}
256
+ folder="profile_photos"
257
+ pageContext="configuration"
240
258
  />
241
259
  </FileDisplay>
242
260
  ```
@@ -331,6 +349,8 @@ const result = await uploadFile({
331
349
  organisation_id: orgId,
332
350
  app_id: 'your-app-id',
333
351
  category: FileCategory.PROFILE_PHOTOS,
352
+ folder: 'profile_photos',
353
+ pageContext: 'configuration',
334
354
  is_public: false // Uses 'files' bucket
335
355
  }, file);
336
356
 
@@ -341,6 +361,8 @@ const publicResult = await uploadFile({
341
361
  organisation_id: orgId,
342
362
  app_id: 'your-app-id',
343
363
  category: FileCategory.EVENT_LOGOS,
364
+ folder: 'event_logos',
365
+ pageContext: 'configuration',
344
366
  is_public: true // Uses 'public-files' bucket
345
367
  }, logoFile);
346
368
 
@@ -475,14 +497,15 @@ const files = await service.listFileReferences('pace_person', personId, orgId);
475
497
 
476
498
  ```sql
477
499
  -- Create file reference (replaces insert_file_reference)
500
+ -- Requires page context for context-aware permission checks
478
501
  SELECT data_file_reference_create(
479
502
  p_table_name := 'pace_person',
480
503
  p_record_id := 'person-uuid',
481
504
  p_file_path := 'org-123/profile_photos/file.jpg',
482
505
  p_organisation_id := 'org-uuid',
483
506
  p_app_id := 'app-uuid',
507
+ p_page_context := 'configuration',
484
508
  p_file_metadata := '{"fileName": "photo.jpg"}'::jsonb,
485
- p_category := 'profile_photos',
486
509
  p_is_public := false
487
510
  );
488
511
 
@@ -48,6 +48,8 @@ function MyFileUpload() {
48
48
  organisation_id="org-123"
49
49
  // app_id auto-resolved from app name
50
50
  category={FileCategory.GENERAL_DOCUMENTS}
51
+ folder="documents"
52
+ pageContext="configuration"
51
53
  accept=".pdf,.doc,.docx"
52
54
  maxSize={5 * 1024 * 1024} // 5MB
53
55
  showProgress={true}
@@ -102,6 +104,8 @@ function UserProfile({ userId }: { userId: string }) {
102
104
  record_id={userId}
103
105
  organisation_id="org-123"
104
106
  category={FileCategory.GENERAL_DOCUMENTS}
107
+ folder="documents"
108
+ pageContext="configuration"
105
109
  accept=".pdf,.doc,.docx"
106
110
  maxSize={10 * 1024 * 1024}
107
111
  />
@@ -126,7 +130,9 @@ interface FileUploadProps {
126
130
  record_id: string;
127
131
  organisation_id: string;
128
132
  app_id?: string; // Optional - will be resolved from app name if not provided
129
- category: FileCategory;
133
+ category: FileCategory; // File category for metadata (stored in file_metadata JSONB field)
134
+ folder: string; // Folder name in storage bucket (e.g., 'profile_photos', 'documents')
135
+ pageContext: string; // The page context where the file upload occurs (e.g., 'configuration', 'forms', 'applications')
130
136
  accept?: string;
131
137
  maxSize?: number;
132
138
  multiple?: boolean;
@@ -142,6 +148,8 @@ interface FileUploadProps {
142
148
  }
143
149
  ```
144
150
 
151
+ **Note:** The `category` prop is used for metadata purposes (stored in the `file_metadata` JSONB field), while the `folder` prop determines the actual storage path: `{orgId}/{folder}/{timestamp-uuid-filename}`. You can use the same value for both (e.g., `category={FileCategory.PROFILE_PHOTOS}` and `folder="profile_photos"`), or use different values if needed.
152
+
145
153
  #### Usage Examples
146
154
 
147
155
  **Basic Upload:**
@@ -152,6 +160,8 @@ interface FileUploadProps {
152
160
  record_id="person-123"
153
161
  organisation_id={organisationId}
154
162
  category={FileCategory.PROFILE_PHOTOS}
163
+ folder="profile_photos"
164
+ pageContext="configuration"
155
165
  accept="image/*"
156
166
  maxSize={2 * 1024 * 1024} // 2MB
157
167
  onUploadSuccess={(result) => console.log('Uploaded:', result.file_reference)}
@@ -168,6 +178,8 @@ interface FileUploadProps {
168
178
  record_id="person-123"
169
179
  organisation_id={organisationId}
170
180
  category={FileCategory.GENERAL_DOCUMENTS}
181
+ folder="documents"
182
+ pageContext="forms"
171
183
  multiple={true}
172
184
  accept=".pdf,.doc,.docx"
173
185
  showProgress={true}
@@ -197,6 +209,23 @@ interface FileUploadProps {
197
209
  </FileUpload>
198
210
  ```
199
211
 
212
+ #### Page Context and Permissions
213
+
214
+ The `pageContext` parameter enables context-aware permission checks for file uploads. Instead of requiring a generic `'create:files'` permission on a `'files'` page, the system checks permissions based on the actual page where the upload occurs.
215
+
216
+ **Permission Check Behavior:**
217
+ - The system checks for `'create:page.{pageContext}'` permission first
218
+ - If that permission doesn't exist, it checks for `'update:page.{pageContext}'` permission
219
+ - The user needs at least one of these permissions to upload files
220
+ - This ensures file uploads are controlled by the same permissions as the page where they occur
221
+
222
+ **Example Use Cases:**
223
+ - Event logo uploads on the `'configuration'` page require `'create:page.configuration'` or `'update:page.configuration'` permission
224
+ - Form document uploads on the `'forms'` page require `'create:page.forms'` or `'update:page.forms'` permission
225
+ - Application file uploads on the `'applications'` page require `'create:page.applications'` or `'update:page.applications'` permission
226
+
227
+ **Important:** The `pageContext` must match a page defined in your RBAC system (`rbac_app_pages` table) for the permission checks to work correctly.
228
+
200
229
  ### FileDisplay
201
230
 
202
231
  A component for displaying and managing files associated with database records.
@@ -66,6 +66,7 @@ function MyComponent() {
66
66
  - **[Event-Based Apps](./event-based-apps.md)** - Get up and running in 10 minutes (foolproof guide for event-based apps)
67
67
  - **[API Reference](./api-reference.md)** - Complete API documentation
68
68
  - **[Troubleshooting](./troubleshooting.md)** - Common issues and solutions
69
+ - **[Compliance Guide](./compliance/compliance-guide.md)** - Ensuring proper RBAC/auth setup and usage
69
70
  - **[Examples](./examples.md)** - Practical usage examples
70
71
  - **[Advanced Patterns](./advanced-patterns.md)** - Complex scenarios and optimizations
71
72