@jmruthers/pace-core 0.5.74 → 0.5.75

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 (278) hide show
  1. package/dist/{DataTable-2QR5TER5.js → DataTable-HWZQGASI.js} +8 -8
  2. package/dist/{PublicLoadingSpinner-DLpF5bbs.d.ts → PublicLoadingSpinner-BKNBT6b6.d.ts} +2 -2
  3. package/dist/RBACService-C4udt_Zp.d.ts +528 -0
  4. package/dist/{UnifiedAuthProvider-K4NRGXL4.js → UnifiedAuthProvider-3NKDOSOK.js} +6 -4
  5. package/dist/UnifiedAuthProvider-Bj6YCf7c.d.ts +113 -0
  6. package/dist/{chunk-UJMCGBLS.js → chunk-2CHATWBF.js} +5 -7
  7. package/dist/chunk-2CHATWBF.js.map +1 -0
  8. package/dist/{chunk-BKVGJVUR.js → chunk-2DFZ432F.js} +496 -30
  9. package/dist/chunk-2DFZ432F.js.map +1 -0
  10. package/dist/{chunk-LVQ26TCN.js → chunk-33PHABLB.js} +36 -3
  11. package/dist/chunk-33PHABLB.js.map +1 -0
  12. package/dist/chunk-5F3NDPJV.js +232 -0
  13. package/dist/chunk-5F3NDPJV.js.map +1 -0
  14. package/dist/chunk-A4FUBC7B.js +17 -0
  15. package/dist/chunk-A4FUBC7B.js.map +1 -0
  16. package/dist/{chunk-SMJZMKYN.js → chunk-A6HBIY5P.js} +2 -11
  17. package/dist/{chunk-SMJZMKYN.js.map → chunk-A6HBIY5P.js.map} +1 -1
  18. package/dist/{chunk-IHMMNKNA.js → chunk-CY3AHGO4.js} +6256 -1937
  19. package/dist/chunk-CY3AHGO4.js.map +1 -0
  20. package/dist/{chunk-H2TNUICK.js → chunk-DAXLNIDY.js} +47 -49
  21. package/dist/chunk-DAXLNIDY.js.map +1 -0
  22. package/dist/{chunk-VKOCWWVY.js → chunk-L3RV2ALE.js} +1 -6
  23. package/dist/{chunk-VKOCWWVY.js.map → chunk-L3RV2ALE.js.map} +1 -1
  24. package/dist/chunk-LW7MMEAQ.js +59 -0
  25. package/dist/chunk-LW7MMEAQ.js.map +1 -0
  26. package/dist/{chunk-DG5Z55HH.js → chunk-NTNILOBC.js} +7 -9
  27. package/dist/chunk-NTNILOBC.js.map +1 -0
  28. package/dist/chunk-PYUXFQJ3.js +11 -0
  29. package/dist/chunk-PYUXFQJ3.js.map +1 -0
  30. package/dist/chunk-URUTVZ7N.js +27 -0
  31. package/dist/chunk-URUTVZ7N.js.map +1 -0
  32. package/dist/chunk-WN6XJWOS.js +2468 -0
  33. package/dist/chunk-WN6XJWOS.js.map +1 -0
  34. package/dist/{chunk-3SP4P7NS.js → chunk-XLZ7U46Z.js} +59 -1
  35. package/dist/chunk-XLZ7U46Z.js.map +1 -0
  36. package/dist/{chunk-ORSMVXO2.js → chunk-ZTT2AXMX.js} +9 -14
  37. package/dist/chunk-ZTT2AXMX.js.map +1 -0
  38. package/dist/components.d.ts +4 -5
  39. package/dist/components.js +32 -39
  40. package/dist/components.js.map +1 -1
  41. package/dist/hooks.d.ts +3 -3
  42. package/dist/hooks.js +9 -8
  43. package/dist/hooks.js.map +1 -1
  44. package/dist/index.d.ts +156 -10
  45. package/dist/index.js +188 -93
  46. package/dist/index.js.map +1 -1
  47. package/dist/{organisation-t-vvQC3g.d.ts → organisation-BtshODVF.d.ts} +4 -3
  48. package/dist/providers.d.ts +27 -38
  49. package/dist/providers.js +33 -23
  50. package/dist/rbac/index.d.ts +61 -5
  51. package/dist/rbac/index.js +13 -14
  52. package/dist/styles/index.js +2 -2
  53. package/dist/theming/runtime.js +1 -3
  54. package/dist/types.d.ts +3 -3
  55. package/dist/types.js +1 -1
  56. package/dist/types.js.map +1 -1
  57. package/dist/{unified-CMPjE_fv.d.ts → unified-CM7T0aTK.d.ts} +1 -1
  58. package/dist/useInactivityTracker-MRUU55XI.js +10 -0
  59. package/dist/useInactivityTracker-MRUU55XI.js.map +1 -0
  60. package/dist/{usePublicRouteParams-Ua1Vz-HG.d.ts → usePublicRouteParams-B-CumWRc.d.ts} +3 -3
  61. package/dist/utils.js +7 -9
  62. package/dist/utils.js.map +1 -1
  63. package/dist/validation.d.ts +1 -1
  64. package/docs/api/classes/ColumnFactory.md +1 -1
  65. package/docs/api/classes/ErrorBoundary.md +1 -1
  66. package/docs/api/classes/InvalidScopeError.md +1 -1
  67. package/docs/api/classes/MissingUserContextError.md +1 -1
  68. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  69. package/docs/api/classes/PermissionDeniedError.md +1 -1
  70. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  71. package/docs/api/classes/RBACAuditManager.md +1 -1
  72. package/docs/api/classes/RBACCache.md +1 -1
  73. package/docs/api/classes/RBACEngine.md +1 -1
  74. package/docs/api/classes/RBACError.md +1 -1
  75. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  76. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  77. package/docs/api/classes/StorageUtils.md +1 -1
  78. package/docs/api/enums/FileCategory.md +1 -1
  79. package/docs/api/interfaces/AggregateConfig.md +1 -1
  80. package/docs/api/interfaces/ButtonProps.md +3 -3
  81. package/docs/api/interfaces/CardProps.md +2 -2
  82. package/docs/api/interfaces/ColorPalette.md +1 -1
  83. package/docs/api/interfaces/ColorShade.md +1 -1
  84. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  85. package/docs/api/interfaces/DataTableAction.md +1 -1
  86. package/docs/api/interfaces/DataTableColumn.md +1 -1
  87. package/docs/api/interfaces/DataTableProps.md +1 -1
  88. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  89. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  90. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  91. package/docs/api/interfaces/EventLogoProps.md +2 -2
  92. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  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/InactivityWarningModalProps.md +1 -1
  100. package/docs/api/interfaces/InputProps.md +2 -2
  101. package/docs/api/interfaces/LabelProps.md +1 -1
  102. package/docs/api/interfaces/LoginFormProps.md +1 -1
  103. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  104. package/docs/api/interfaces/NavigationContextType.md +1 -1
  105. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  106. package/docs/api/interfaces/NavigationItem.md +1 -1
  107. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  108. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  109. package/docs/api/interfaces/Organisation.md +1 -1
  110. package/docs/api/interfaces/OrganisationContextType.md +28 -17
  111. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  112. package/docs/api/interfaces/OrganisationProviderProps.md +2 -2
  113. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  114. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  115. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  116. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  117. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  118. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  119. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  120. package/docs/api/interfaces/PaletteData.md +1 -1
  121. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  122. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  123. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  124. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +2 -2
  125. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  126. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  127. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  128. package/docs/api/interfaces/RBACConfig.md +1 -1
  129. package/docs/api/interfaces/RBACContextType.md +5 -11
  130. package/docs/api/interfaces/RBACLogger.md +1 -1
  131. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  132. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  133. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  134. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  135. package/docs/api/interfaces/RouteConfig.md +1 -1
  136. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  137. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  138. package/docs/api/interfaces/StorageConfig.md +1 -1
  139. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  140. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  141. package/docs/api/interfaces/StorageListOptions.md +1 -1
  142. package/docs/api/interfaces/StorageListResult.md +1 -1
  143. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  144. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  145. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  146. package/docs/api/interfaces/StyleImport.md +1 -1
  147. package/docs/api/interfaces/SwitchProps.md +1 -1
  148. package/docs/api/interfaces/ToastActionElement.md +1 -1
  149. package/docs/api/interfaces/ToastProps.md +1 -1
  150. package/docs/api/interfaces/UnifiedAuthContextType.md +524 -440
  151. package/docs/api/interfaces/UnifiedAuthProviderProps.md +14 -14
  152. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  153. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  154. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  155. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  156. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  157. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  158. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  159. package/docs/api/interfaces/UserEventAccess.md +11 -11
  160. package/docs/api/interfaces/UserMenuProps.md +1 -1
  161. package/docs/api/interfaces/UserProfile.md +1 -1
  162. package/docs/api/modules.md +179 -52
  163. package/docs/architecture/services.md +30 -32
  164. package/docs/breaking-changes.md +2 -5
  165. package/docs/migration/service-architecture.md +121 -260
  166. package/docs/rbac/README-rbac-rls-integration.md +48 -38
  167. package/{src/rbac/examples → examples/RBAC}/CompleteRBACExample.tsx +3 -2
  168. package/{src/rbac/examples → examples/RBAC}/EventBasedApp.tsx +5 -4
  169. package/{src/components/examples → examples/RBAC}/PermissionExample.tsx +7 -6
  170. package/examples/RBAC/__tests__/PermissionExample.test.tsx +150 -0
  171. package/examples/RBAC/index.ts +13 -0
  172. package/examples/README.md +37 -0
  173. package/examples/index.ts +22 -0
  174. package/{src/examples → examples/public-pages}/CorrectPublicPageImplementation.tsx +1 -1
  175. package/{src/examples → examples/public-pages}/PublicEventPage.tsx +1 -1
  176. package/{src/examples → examples/public-pages}/PublicPageApp.tsx +1 -1
  177. package/{src/examples → examples/public-pages}/PublicPageUsageExample.tsx +1 -1
  178. package/examples/public-pages/__tests__/PublicPageUsageExample.test.tsx +159 -0
  179. package/examples/public-pages/index.ts +14 -0
  180. package/package.json +22 -18
  181. package/src/__tests__/TEST_GUIDE_CURSOR.md +650 -9
  182. package/src/__tests__/helpers/README.md +255 -0
  183. package/src/__tests__/helpers/index.ts +62 -0
  184. package/src/__tests__/helpers/supabaseMock.ts +27 -3
  185. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +6 -8
  186. package/src/components/DataTable/components/__tests__/COVERAGE_NOTE.md +55 -0
  187. package/src/components/DataTable/core/ColumnManager.ts +10 -0
  188. package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +254 -0
  189. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +193 -0
  190. package/src/components/DataTable/examples/__tests__/HierarchicalExample.test.tsx +45 -0
  191. package/src/components/DataTable/examples/__tests__/PerformanceExample.test.tsx +117 -0
  192. package/src/components/Dialog/examples/__tests__/HtmlDialogExample.test.tsx +71 -0
  193. package/src/components/Dialog/examples/__tests__/SimpleHtmlTest.test.tsx +122 -0
  194. package/src/components/EventSelector/EventSelector.tsx +1 -1
  195. package/src/components/Header/Header.test.tsx +35 -1
  196. package/src/components/Header/Header.tsx +3 -1
  197. package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -3
  198. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +24 -4
  199. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +3 -2
  200. package/src/hooks/__tests__/useFocusManagement.unit.test.ts +220 -0
  201. package/src/hooks/__tests__/useIsMobile.unit.test.ts +117 -0
  202. package/src/hooks/__tests__/useKeyboardShortcuts.unit.test.ts +295 -0
  203. package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +29 -19
  204. package/src/hooks/__tests__/useRBAC.unit.test.ts +7 -3
  205. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +115 -19
  206. package/src/hooks/useEventTheme.test.ts +350 -0
  207. package/src/hooks/useEventTheme.ts +1 -1
  208. package/src/hooks/useEvents.ts +61 -0
  209. package/src/hooks/useOrganisationSecurity.test.ts +4 -4
  210. package/src/hooks/useOrganisationSecurity.ts +2 -2
  211. package/src/hooks/useOrganisations.ts +64 -0
  212. package/src/hooks/useSecureDataAccess.test.ts +9 -5
  213. package/src/hooks/useSecureDataAccess.ts +2 -2
  214. package/src/index.ts +18 -3
  215. package/src/providers/AuthProvider.tsx +8 -292
  216. package/src/providers/EventProvider.tsx +15 -425
  217. package/src/providers/InactivityProvider.tsx +8 -231
  218. package/src/providers/OrganisationProvider.test.simple.tsx +3 -2
  219. package/src/providers/OrganisationProvider.tsx +11 -890
  220. package/src/providers/UnifiedAuthProvider.tsx +8 -320
  221. package/src/providers/__tests__/AuthProvider.test.tsx +18 -17
  222. package/src/providers/__tests__/EventProvider.test.tsx +253 -2
  223. package/src/providers/__tests__/InactivityProvider.test-helper.tsx +65 -0
  224. package/src/providers/__tests__/InactivityProvider.test.tsx +46 -114
  225. package/src/providers/__tests__/OrganisationProvider.test.tsx +313 -3
  226. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +383 -2
  227. package/src/providers/index.ts +8 -7
  228. package/src/providers/services/EventServiceProvider.tsx +3 -0
  229. package/src/providers/services/UnifiedAuthProvider.tsx +3 -0
  230. package/src/rbac/hooks/usePermissions.test.ts +296 -0
  231. package/src/rbac/hooks/useRBAC.test.ts +9 -5
  232. package/src/rbac/hooks/useRBAC.ts +3 -3
  233. package/src/rbac/providers/__tests__/RBACProvider.integration.test.tsx +688 -0
  234. package/src/rbac/providers/__tests__/RBACProvider.test.tsx +507 -0
  235. package/src/services/AuthService.ts +19 -4
  236. package/src/services/__tests__/AuthService.test.ts +288 -0
  237. package/src/styles/core.css +2 -0
  238. package/src/types/__tests__/guards.test.ts +246 -0
  239. package/src/types/guards.ts +1 -0
  240. package/src/types/organisation.ts +3 -2
  241. package/src/validation/__tests__/sanitization.unit.test.ts +250 -0
  242. package/src/validation/__tests__/schemaUtils.unit.test.ts +451 -0
  243. package/src/validation/__tests__/user.unit.test.ts +440 -0
  244. package/dist/RBACProvider-BO4ilsQB.d.ts +0 -63
  245. package/dist/UnifiedAuthProvider-D02AMXgO.d.ts +0 -103
  246. package/dist/chunk-3SP4P7NS.js.map +0 -1
  247. package/dist/chunk-B5LK25HV.js +0 -953
  248. package/dist/chunk-B5LK25HV.js.map +0 -1
  249. package/dist/chunk-BKVGJVUR.js.map +0 -1
  250. package/dist/chunk-C5Q5LRU5.js +0 -5691
  251. package/dist/chunk-C5Q5LRU5.js.map +0 -1
  252. package/dist/chunk-CDDYJCYU.js +0 -79
  253. package/dist/chunk-CDDYJCYU.js.map +0 -1
  254. package/dist/chunk-DG5Z55HH.js.map +0 -1
  255. package/dist/chunk-H2TNUICK.js.map +0 -1
  256. package/dist/chunk-IHMMNKNA.js.map +0 -1
  257. package/dist/chunk-LVQ26TCN.js.map +0 -1
  258. package/dist/chunk-ORSMVXO2.js.map +0 -1
  259. package/dist/chunk-UJMCGBLS.js.map +0 -1
  260. package/dist/chunk-V6BHACCH.js +0 -17
  261. package/dist/chunk-V6BHACCH.js.map +0 -1
  262. package/dist/rbac/cli/policy-manager.js +0 -278
  263. package/dist/rbac/cli/policy-manager.js.map +0 -1
  264. package/docs/api/interfaces/EventContextType.md +0 -96
  265. package/docs/api/interfaces/EventProviderProps.md +0 -19
  266. package/src/providers/OrganisationProvider.test.tsx +0 -164
  267. package/src/providers/UnifiedAuthProvider.test.tsx +0 -124
  268. package/src/providers/__tests__/AuthProvider.test.tsx.backup +0 -771
  269. package/src/providers/__tests__/EventProvider.test.tsx.backup +0 -824
  270. package/src/providers/__tests__/OrganisationProvider.test.tsx.backup +0 -820
  271. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup +0 -911
  272. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup2 +0 -166
  273. package/src/rbac/cli/__tests__/policy-manager.test.ts +0 -339
  274. package/src/rbac/cli/policy-manager.ts +0 -443
  275. package/dist/{DataTable-2QR5TER5.js.map → DataTable-HWZQGASI.js.map} +0 -0
  276. package/dist/{UnifiedAuthProvider-K4NRGXL4.js.map → UnifiedAuthProvider-3NKDOSOK.js.map} +0 -0
  277. package/dist/{validation-PM_iOaTI.d.ts → validation-D8VcbTzC.d.ts} +2 -2
  278. /package/src/utils/{appNameResolver.test.ts.backup → appNameResolver.test 2.ts} +0 -0
@@ -82,11 +82,11 @@ export abstract class BaseService {
82
82
  ### Basic Setup
83
83
 
84
84
  ```tsx
85
- import { NewUnifiedAuthProvider } from '@core/providers/services/NewUnifiedAuthProvider';
85
+ import { UnifiedAuthProvider, useUnifiedAuth } from '@jmruthers/pace-core';
86
86
 
87
87
  function App() {
88
88
  return (
89
- <NewUnifiedAuthProvider
89
+ <UnifiedAuthProvider
90
90
  supabaseClient={supabase}
91
91
  appName="MY_APP"
92
92
  idleTimeoutMs={30 * 60 * 1000} // 30 minutes
@@ -94,7 +94,7 @@ function App() {
94
94
  onIdleLogout={() => window.location.href = '/login'}
95
95
  >
96
96
  <YourAppContent />
97
- </NewUnifiedAuthProvider>
97
+ </UnifiedAuthProvider>
98
98
  );
99
99
  }
100
100
  ```
@@ -102,10 +102,10 @@ function App() {
102
102
  ### Using Services in Components
103
103
 
104
104
  ```tsx
105
- import { useNewUnifiedAuth } from '@core/providers/services/NewUnifiedAuthProvider';
105
+ import { useUnifiedAuth } from '@jmruthers/pace-core';
106
106
 
107
107
  function MyComponent() {
108
- const auth = useNewUnifiedAuth();
108
+ const auth = useUnifiedAuth();
109
109
 
110
110
  return (
111
111
  <div>
@@ -121,24 +121,26 @@ function MyComponent() {
121
121
  ### Using Individual Service Hooks
122
122
 
123
123
  ```tsx
124
- import { useAuth } from '@core/hooks/services/useAuth';
125
- import { usePermissions } from '@core/hooks/services/usePermissions';
126
- import { useCurrentOrganisation } from '@core/hooks/services/useCurrentOrganisation';
127
- import { useCurrentEvent } from '@core/hooks/services/useCurrentEvent';
124
+ import {
125
+ useAuthService,
126
+ useOrganisationService,
127
+ useEventService,
128
+ useRBACService
129
+ } from '@jmruthers/pace-core';
128
130
 
129
131
  function MyComponent() {
130
- const auth = useAuth();
131
- const permissions = usePermissions();
132
- const organisation = useCurrentOrganisation();
133
- const events = useCurrentEvent();
132
+ const authService = useAuthService();
133
+ const orgService = useOrganisationService();
134
+ const eventService = useEventService();
135
+ const rbacService = useRBACService();
134
136
 
135
137
  return (
136
138
  <div>
137
- {auth.isAuthenticated && (
139
+ {authService.isAuthenticated() && (
138
140
  <div>
139
- <h1>{organisation.selectedOrganisation?.display_name}</h1>
140
- {permissions.hasPermission('events:read') && (
141
- <EventList events={events.events} />
141
+ <h1>{orgService.getSelectedOrganisation()?.display_name}</h1>
142
+ {rbacService.hasPermission('events:read') && (
143
+ <EventList events={eventService.getEvents()} />
142
144
  )}
143
145
  </div>
144
146
  )}
@@ -238,17 +240,13 @@ describe('AuthServiceProvider Integration', () => {
238
240
 
239
241
  ### From Old Architecture
240
242
 
241
- The new architecture provides backward compatibility through the `NewUnifiedAuthProvider` which maintains the same API as the old `UnifiedAuthProvider`:
243
+ The architecture is backward compatible. The `UnifiedAuthProvider` now uses the service-based architecture internally:
242
244
 
243
245
  ```tsx
244
- // Old way
245
- import { UnifiedAuthProvider } from '@core/providers';
246
+ import { UnifiedAuthProvider } from '@jmruthers/pace-core';
246
247
 
247
- // New way
248
- import { NewUnifiedAuthProvider } from '@core/providers/services/NewUnifiedAuthProvider';
249
-
250
- // Same API, better architecture
251
- <NewUnifiedAuthProvider
248
+ // Same API, service-based architecture internally
249
+ <UnifiedAuthProvider
252
250
  supabaseClient={supabase}
253
251
  appName="MY_APP"
254
252
  idleTimeoutMs={30 * 60 * 1000}
@@ -256,17 +254,17 @@ import { NewUnifiedAuthProvider } from '@core/providers/services/NewUnifiedAuthP
256
254
  onIdleLogout={() => window.location.href = '/login'}
257
255
  >
258
256
  <YourAppContent />
259
- </NewUnifiedAuthProvider>
257
+ </UnifiedAuthProvider>
260
258
  ```
261
259
 
262
- ### Gradual Migration
260
+ ### How It Works
263
261
 
264
- You can migrate gradually by:
262
+ All providers use the service-based architecture:
265
263
 
266
- 1. **Start with new apps**: Use `NewUnifiedAuthProvider` for new applications
267
- 2. **Migrate existing apps**: Replace `UnifiedAuthProvider` with `NewUnifiedAuthProvider`
268
- 3. **Use individual services**: Gradually move to individual service hooks for better performance
269
- 4. **Remove old providers**: Once migration is complete, remove old provider imports
264
+ 1. **UnifiedAuthProvider**: Uses service architecture internally
265
+ 2. **Individual Services**: Available for advanced usage via hooks
266
+ 3. **Backward Compatible**: Existing code works without changes
267
+ 4. **Performance**: All providers instantiate services once and reuse them
270
268
 
271
269
  ## File Structure
272
270
 
@@ -87,14 +87,11 @@ The library now uses a service-based architecture with pure TypeScript service c
87
87
 
88
88
  #### Migration
89
89
 
90
- Migration is optional. Existing code continues to work. To adopt new architecture:
90
+ The service architecture is now the default. Existing code continues to work without changes:
91
91
 
92
92
  ```tsx
93
- // Old way (still works)
93
+ // Works out of the box - uses service architecture internally
94
94
  import { UnifiedAuthProvider } from '@jmruthers/pace-core';
95
-
96
- // New way (optional)
97
- import { NewUnifiedAuthProvider } from '@core/providers/services/NewUnifiedAuthProvider';
98
95
  ```
99
96
 
100
97
  See [Service Architecture Guide](./architecture/services.md) for details.
@@ -1,257 +1,151 @@
1
- # Migration Guide: Service Architecture
1
+ # Provider Architecture: Service-Based Design
2
2
 
3
3
  ## Overview
4
4
 
5
- This guide helps you migrate from the old provider architecture to the new service-based architecture. The new architecture provides better testability, maintainability, and follows SOLID principles.
5
+ pace-core now uses a **service-based architecture** for all providers. This provides better testability, maintainability, and follows SOLID principles by separating business logic (services) from React context (providers).
6
6
 
7
- ## Quick Start
8
-
9
- ### 1. Update Provider Import
10
-
11
- Replace the old provider with the new one:
12
-
13
- ```tsx
14
- // Old way
15
- import { UnifiedAuthProvider } from '@core/providers';
16
-
17
- // New way
18
- import { NewUnifiedAuthProvider } from '@core/providers/services/NewUnifiedAuthProvider';
19
- ```
20
-
21
- ### 2. Update Provider Usage
7
+ ## Architecture Benefits
22
8
 
23
- The new provider has the same API but requires additional configuration:
9
+ - **Separation of Concerns**: Business logic in pure TypeScript services
10
+ - **Better Testability**: Services can be tested without React
11
+ - **Improved Performance**: Services instantiated once and reused
12
+ - **Type Safety**: Full TypeScript support with clear interfaces
24
13
 
25
- ```tsx
26
- // Old way
27
- <UnifiedAuthProvider supabaseClient={supabase} appName="MY_APP">
28
- <YourAppContent />
29
- </UnifiedAuthProvider>
30
-
31
- // New way
32
- <NewUnifiedAuthProvider
33
- supabaseClient={supabase}
34
- appName="MY_APP"
35
- idleTimeoutMs={30 * 60 * 1000} // 30 minutes
36
- warnBeforeMs={60 * 1000} // 60 seconds
37
- onIdleLogout={() => {
38
- // Handle idle logout - redirect to login
39
- window.location.href = '/login';
40
- }}
41
- >
42
- <YourAppContent />
43
- </NewUnifiedAuthProvider>
44
- ```
45
-
46
- ### 3. Update Hook Imports
47
-
48
- Replace the old hook with the new one:
49
-
50
- ```tsx
51
- // Old way
52
- import { useUnifiedAuth } from '@core/providers';
53
-
54
- // New way
55
- import { useNewUnifiedAuth } from '@core/providers/services/NewUnifiedAuthProvider';
56
- ```
57
-
58
- ## Detailed Migration Steps
59
-
60
- ### Step 1: Update Main App Setup
14
+ ## Quick Start
61
15
 
62
- Update your main app file (usually `main.tsx` or `App.tsx`):
16
+ ### Basic Usage
63
17
 
64
18
  ```tsx
65
- // Before
66
- import { UnifiedAuthProvider, OrganisationProvider, EventProvider } from '@core/providers';
19
+ import { UnifiedAuthProvider, useUnifiedAuth } from '@jmruthers/pace-core';
67
20
 
68
21
  function App() {
69
22
  return (
70
- <UnifiedAuthProvider supabaseClient={supabase} appName="MY_APP">
71
- <OrganisationProvider>
72
- <EventProvider>
73
- <YourAppContent />
74
- </EventProvider>
75
- </OrganisationProvider>
76
- </UnifiedAuthProvider>
77
- );
78
- }
79
-
80
- // After
81
- import { NewUnifiedAuthProvider } from '@core/providers/services/NewUnifiedAuthProvider';
82
-
83
- function App() {
84
- return (
85
- <NewUnifiedAuthProvider
23
+ <UnifiedAuthProvider
86
24
  supabaseClient={supabase}
87
25
  appName="MY_APP"
88
- idleTimeoutMs={30 * 60 * 1000}
89
- warnBeforeMs={60 * 1000}
90
- onIdleLogout={() => window.location.href = '/login'}
26
+ idleTimeoutMs={30 * 60 * 1000} // 30 minutes
27
+ warnBeforeMs={60 * 1000} // 60 seconds
28
+ onIdleLogout={() => {
29
+ // Handle idle logout - redirect to login
30
+ window.location.href = '/login';
31
+ }}
91
32
  >
92
33
  <YourAppContent />
93
- </NewUnifiedAuthProvider>
34
+ </UnifiedAuthProvider>
94
35
  );
95
36
  }
96
37
  ```
97
38
 
98
- ### Step 2: Update Component Hooks
99
-
100
- Update components that use the old hooks:
39
+ ### Using Hooks
101
40
 
102
41
  ```tsx
103
- // Before
104
- import { useUnifiedAuth } from '@core/providers';
42
+ import { useUnifiedAuth, useEvents, useOrganisations } from '@jmruthers/pace-core';
105
43
 
106
44
  function MyComponent() {
107
45
  const { user, isAuthenticated, signOut } = useUnifiedAuth();
108
- // ... component logic
109
- }
110
-
111
- // After
112
- import { useNewUnifiedAuth } from '@core/providers/services/NewUnifiedAuthProvider';
113
-
114
- function MyComponent() {
115
- const { user, isAuthenticated, signOut } = useNewUnifiedAuth();
116
- // ... component logic (same API)
46
+ const { events, selectedEvent, setSelectedEvent } = useEvents();
47
+ const { selectedOrganisation, organisations } = useOrganisations();
48
+
49
+ // Use the hooks as needed
117
50
  }
118
51
  ```
119
52
 
120
- ### Step 3: Update Individual Provider Usage
121
-
122
- If you were using individual providers, you can now use individual service hooks:
123
-
124
- ```tsx
125
- // Before
126
- import { useAuth } from '@core/providers';
127
- import { useOrganisations } from '@core/providers';
128
- import { useEvents } from '@core/providers';
53
+ ## Service Architecture Overview
129
54
 
130
- function MyComponent() {
131
- const auth = useAuth();
132
- const orgs = useOrganisations();
133
- const events = useEvents();
134
- // ... component logic
135
- }
55
+ ### How It Works
136
56
 
137
- // After - Option 1: Use unified hook (same API)
138
- import { useNewUnifiedAuth } from '@core/providers/services/NewUnifiedAuthProvider';
57
+ 1. **Services** (`src/services/`) - Pure TypeScript classes containing business logic
58
+ 2. **Service Providers** (`src/providers/services/`) - React context providers that create service instances
59
+ 3. **Hooks** - Convenience hooks that access services from context
139
60
 
140
- function MyComponent() {
141
- const auth = useNewUnifiedAuth();
142
- // ... component logic (same API)
143
- }
61
+ ### Service Layer
144
62
 
145
- // After - Option 2: Use individual service hooks (better performance)
146
- import { useAuth } from '@core/hooks/services/useAuth';
147
- import { useCurrentOrganisation } from '@core/hooks/services/useCurrentOrganisation';
148
- import { useCurrentEvent } from '@core/hooks/services/useCurrentEvent';
63
+ Each service is a pure TypeScript class:
149
64
 
150
- function MyComponent() {
151
- const auth = useAuth();
152
- const orgs = useCurrentOrganisation();
153
- const events = useCurrentEvent();
154
- // ... component logic
65
+ ```typescript
66
+ class AuthService extends BaseService {
67
+ signIn(email: string, password: string): Promise<AuthResult> { /* ... */ }
68
+ signOut(): Promise<AuthResult> { /* ... */ }
69
+ // ... other methods
155
70
  }
156
71
  ```
157
72
 
158
- ## API Changes
73
+ ### Provider Layer
159
74
 
160
- ### New Required Props
161
-
162
- The new provider requires additional props for inactivity management:
75
+ Service providers create and manage service instances:
163
76
 
164
77
  ```tsx
165
- interface NewUnifiedAuthProviderProps {
166
- // ... existing props
167
- idleTimeoutMs: number; // REQUIRED: Inactivity timeout in milliseconds
168
- warnBeforeMs: number; // REQUIRED: Warning time before logout in milliseconds
169
- onIdleLogout: (reason: 'inactivity') => void; // REQUIRED: App handles redirect/navigation
78
+ function AuthServiceProvider({ children, supabaseClient }) {
79
+ const authService = useMemo(() => new AuthService(supabaseClient), [supabaseClient]);
80
+ // Initialize and manage service lifecycle
81
+ return <AuthServiceContext.Provider value={{ authService }}>{children}</AuthServiceContext.Provider>;
170
82
  }
171
83
  ```
172
84
 
173
- ### Backward Compatibility
85
+ ### Hook Layer
174
86
 
175
- The new provider maintains the same API as the old one, so existing components should work without changes:
87
+ Convenience hooks provide easy access to services:
176
88
 
177
89
  ```tsx
178
- // This still works exactly the same
179
- const { user, isAuthenticated, signOut, hasRole, hasPermission } = useNewUnifiedAuth();
90
+ function useAuth() {
91
+ const context = useContext(AuthServiceContext);
92
+ return context.authService;
93
+ }
180
94
  ```
181
95
 
182
- ## Performance Optimizations
96
+ ## Available Hooks
183
97
 
184
- ### Use Individual Service Hooks
185
-
186
- For better performance, use individual service hooks instead of the unified hook:
98
+ ### Unified Hook (Recommended for Most Use Cases)
187
99
 
188
100
  ```tsx
189
- // Less efficient - re-renders on any state change
190
- const auth = useNewUnifiedAuth();
191
-
192
- // More efficient - only re-renders when auth state changes
193
- const auth = useAuth();
194
- const permissions = usePermissions();
195
- const organisation = useCurrentOrganisation();
196
- const events = useCurrentEvent();
197
- ```
101
+ import { useUnifiedAuth } from '@jmruthers/pace-core';
198
102
 
199
- ### Service Subscription
200
-
201
- Services use an observable pattern for efficient updates:
202
-
203
- ```tsx
204
- // Services automatically notify subscribers of state changes
205
- // No need to manually manage subscriptions
206
- const auth = useAuth(); // Automatically subscribes to auth service changes
103
+ function MyComponent() {
104
+ const {
105
+ user,
106
+ isAuthenticated,
107
+ signOut,
108
+ selectedOrganisation,
109
+ events,
110
+ selectedEvent,
111
+ permissions,
112
+ hasRole,
113
+ hasPermission
114
+ } = useUnifiedAuth();
115
+
116
+ // Access all features from one hook
117
+ }
207
118
  ```
208
119
 
209
- ## Testing Updates
210
-
211
- ### Update Test Imports
120
+ ### Individual Hooks (For Performance)
212
121
 
213
- Update your test files to use the new providers:
122
+ For better performance, use individual hooks:
214
123
 
215
124
  ```tsx
216
- // Before
217
- import { UnifiedAuthProvider } from '@core/providers';
125
+ import {
126
+ useEvents,
127
+ useOrganisations,
128
+ useAuthService,
129
+ useRBACService
130
+ } from '@jmruthers/pace-core';
218
131
 
219
- // After
220
- import { NewUnifiedAuthProvider } from '@core/providers/services/NewUnifiedAuthProvider';
132
+ function MyComponent() {
133
+ const events = useEvents();
134
+ const orgs = useOrganisations();
135
+ const auth = useAuthService();
136
+ const rbac = useRBACService();
137
+
138
+ // Only re-renders when relevant service state changes
139
+ }
221
140
  ```
222
141
 
223
- ### Update Test Setup
224
-
225
- Update your test setup to use the new provider:
226
-
227
- ```tsx
228
- // Before
229
- render(
230
- <UnifiedAuthProvider supabaseClient={mockSupabase} appName="TEST_APP">
231
- <TestComponent />
232
- </UnifiedAuthProvider>
233
- );
234
-
235
- // After
236
- render(
237
- <NewUnifiedAuthProvider
238
- supabaseClient={mockSupabase}
239
- appName="TEST_APP"
240
- idleTimeoutMs={30000}
241
- warnBeforeMs={5000}
242
- onIdleLogout={() => {}}
243
- >
244
- <TestComponent />
245
- </NewUnifiedAuthProvider>
246
- );
247
- ```
142
+ ## Testing
248
143
 
249
- ### Service Testing
144
+ ### Testing Services
250
145
 
251
- You can now test services directly:
146
+ Services are pure TypeScript classes, making them easy to unit test:
252
147
 
253
- ```tsx
254
- // Test services in isolation
148
+ ```typescript
255
149
  describe('AuthService', () => {
256
150
  let authService: AuthService;
257
151
 
@@ -266,86 +160,53 @@ describe('AuthService', () => {
266
160
  });
267
161
  ```
268
162
 
269
- ## Common Issues and Solutions
270
-
271
- ### Issue 1: Missing Required Props
272
-
273
- **Error**: `Missing required prop: idleTimeoutMs`
163
+ ### Testing Providers
274
164
 
275
- **Solution**: Add the required inactivity management props:
165
+ Providers can be tested with React Testing Library:
276
166
 
277
- ```tsx
278
- <NewUnifiedAuthProvider
279
- supabaseClient={supabase}
280
- appName="MY_APP"
281
- idleTimeoutMs={30 * 60 * 1000} // Add this
282
- warnBeforeMs={60 * 1000} // Add this
283
- onIdleLogout={() => window.location.href = '/login'} // Add this
284
- >
285
- <YourAppContent />
286
- </NewUnifiedAuthProvider>
167
+ ```typescript
168
+ render(
169
+ <UnifiedAuthProvider
170
+ supabaseClient={mockSupabase}
171
+ appName="TEST_APP"
172
+ idleTimeoutMs={30000}
173
+ warnBeforeMs={5000}
174
+ onIdleLogout={() => {}}
175
+ >
176
+ <TestComponent />
177
+ </UnifiedAuthProvider>
178
+ );
287
179
  ```
288
180
 
289
- ### Issue 2: Hook Not Found
290
-
291
- **Error**: `useUnifiedAuth must be used within a UnifiedAuthProvider`
292
-
293
- **Solution**: Update the hook import:
294
-
295
- ```tsx
296
- // Change this
297
- import { useUnifiedAuth } from '@core/providers';
298
-
299
- // To this
300
- import { useNewUnifiedAuth } from '@core/providers/services/NewUnifiedAuthProvider';
301
- ```
181
+ ## Common Issues
302
182
 
303
- ### Issue 3: Provider Not Found
183
+ ### Missing Required Props
304
184
 
305
- **Error**: `useNewUnifiedAuth must be used within a NewUnifiedAuthProvider`
185
+ **Error**: `Missing required prop: idleTimeoutMs`
306
186
 
307
- **Solution**: Ensure the component is wrapped in the new provider:
187
+ Add the required inactivity management props:
308
188
 
309
189
  ```tsx
310
- // Make sure your app is wrapped in NewUnifiedAuthProvider
311
- <NewUnifiedAuthProvider {...props}>
190
+ <UnifiedAuthProvider
191
+ supabaseClient={supabase}
192
+ appName="MY_APP"
193
+ idleTimeoutMs={30 * 60 * 1000}
194
+ warnBeforeMs={60 * 1000}
195
+ onIdleLogout={() => window.location.href = '/login'}
196
+ >
312
197
  <YourAppContent />
313
- </NewUnifiedAuthProvider>
198
+ </UnifiedAuthProvider>
314
199
  ```
315
200
 
316
- ## Migration Checklist
317
-
318
- - [ ] Update provider import from `UnifiedAuthProvider` to `NewUnifiedAuthProvider`
319
- - [ ] Add required inactivity management props (`idleTimeoutMs`, `warnBeforeMs`, `onIdleLogout`)
320
- - [ ] Update hook import from `useUnifiedAuth` to `useNewUnifiedAuth`
321
- - [ ] Update test imports and setup
322
- - [ ] Test the application to ensure everything works
323
- - [ ] Consider using individual service hooks for better performance
324
- - [ ] Remove old provider imports once migration is complete
325
-
326
- ## Rollback Plan
327
-
328
- If you need to rollback:
329
-
330
- 1. **Revert imports**: Change back to old provider imports
331
- 2. **Revert provider usage**: Remove the new required props
332
- 3. **Revert hook usage**: Change back to old hook imports
333
- 4. **Test**: Ensure the application works with the old architecture
334
-
335
- ## Support
336
-
337
- If you encounter issues during migration:
338
-
339
- 1. **Check the documentation**: Review the service architecture documentation
340
- 2. **Check the examples**: Look at the updated example app
341
- 3. **Check the tests**: Review the test files for usage examples
342
- 4. **Open an issue**: Report bugs or ask questions
201
+ ## Performance Tips
343
202
 
344
- ## Next Steps
203
+ 1. **Use individual hooks** when you only need specific data
204
+ 2. **Avoid unnecessary re-renders** by selecting only what you need
205
+ 3. **Memoize expensive computations** in components
206
+ 4. **Test services in isolation** for better unit tests
345
207
 
346
- After migration:
208
+ ## Additional Resources
347
209
 
348
- 1. **Explore individual services**: Consider using individual service hooks for better performance
349
- 2. **Write service tests**: Add unit tests for your custom services
350
- 3. **Optimize performance**: Use individual hooks instead of the unified hook where appropriate
351
- 4. **Contribute**: Help improve the service architecture
210
+ - [API Reference](../../api-reference/providers.md)
211
+ - [Architecture Documentation](../../architecture/services.md)
212
+ - [Example Apps](../../getting-started/examples/)