From f2b08ecb21538a8e9d4f9b518e6e0f80d3f0554c Mon Sep 17 00:00:00 2001 From: "bert.hausmans" Date: Tue, 5 May 2026 21:25:24 +0200 Subject: [PATCH] refactor(auth): merge usePortalAuthStore into useAuthStore with context-aware getters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit usePortalAuthStore is deleted — its 114 lines were a slim wrapper over the same /auth/me endpoint useAuthStore already consumes. The merged store gains the full set of additions Bert specified for B2a: State: - availableContexts / defaultContext (from /auth/me contexts block) - lastContext (localStorage-persisted) - portalToken (in-memory only, for the bearer-axios flavour) Getters: isPortalUser, isOrganizerUser, isPlatformAdmin (alias of isSuperAdmin), showContextSwitcher, hasRole(), hasAnyRole(). Actions: login(), verifyMfa() — both return typed discriminated unions so login.vue (Phase H) consumes results without branching on raw API response shapes. setLastContext, setPortalToken, resolveLandingRoute, clearAll. clearAll dynamically imports usePortalStore.reset() to clear portal sessionStorage on session-end — this is the canonical session-cleanup hub now that the merge has happened. 5 source files migrated from usePortalAuthStore → useAuthStore. The PortalLayout.spec.ts mock follows. The boundaries matrix gains a single new edge (`stores → stores-portal`) replacing the deleted stores-portal/usePortalAuthStore which previously owned that cross-zone call. Adds 16 vitest specs in src/stores/__tests__/useAuthStore.spec.ts covering setUser context hydration, hasRole/hasAnyRole, lastContext localStorage persistence, resolveLandingRoute precedence (portal/organizer/super_admin/multi-role/forceContext/forbidden fallback), portalToken state, and clearAll cleanup. Test count 162 → 178 (16 new). Frontend lint + typecheck clean. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/app/.eslintrc.cjs | 8 +- .../src/components/portal/UserAvatarMenu.vue | 4 +- apps/app/src/layouts/PortalLayout.vue | 4 +- .../layouts/__tests__/PortalLayout.spec.ts | 4 +- apps/app/src/pages/portal/profiel.vue | 4 +- apps/app/src/pages/portal/shifts/index.vue | 4 +- .../src/stores/__tests__/useAuthStore.spec.ts | 233 +++++++++++++++++ .../src/stores/portal/usePortalAuthStore.ts | 114 --------- apps/app/src/stores/useAuthStore.ts | 234 +++++++++++++++++- apps/app/src/types/auth.ts | 57 +++++ 10 files changed, 537 insertions(+), 129 deletions(-) create mode 100644 apps/app/src/stores/__tests__/useAuthStore.spec.ts delete mode 100644 apps/app/src/stores/portal/usePortalAuthStore.ts diff --git a/apps/app/.eslintrc.cjs b/apps/app/.eslintrc.cjs index 4c9a83d6..8da0dda4 100644 --- a/apps/app/.eslintrc.cjs +++ b/apps/app/.eslintrc.cjs @@ -230,7 +230,13 @@ module.exports = { { from: 'composables-forms', allow: ['types', 'utils', 'lib', 'composables-forms'] }, { from: 'composables', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'stores-portal'] }, { from: 'stores-portal', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'stores-portal'] }, - { from: 'stores', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores'] }, + + // useAuthStore.clearAll() / .logout() invokes usePortalStore.reset() + // via dynamic import to clear portal sessionStorage on session-end. + // The merged auth store is the canonical session-cleanup hub — this + // edge replaces the deleted stores-portal/usePortalAuthStore which + // previously owned the cross-zone call (WS-3 PR-B2a). + { from: 'stores', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'stores-portal'] }, { from: 'navigation', allow: ['types', 'utils', 'navigation'] }, { from: 'components-shared', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'components-shared'] }, { from: 'components-portal', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'stores-portal', 'components-shared', 'components-portal'] }, diff --git a/apps/app/src/components/portal/UserAvatarMenu.vue b/apps/app/src/components/portal/UserAvatarMenu.vue index 8c7ed491..2949d239 100644 --- a/apps/app/src/components/portal/UserAvatarMenu.vue +++ b/apps/app/src/components/portal/UserAvatarMenu.vue @@ -1,7 +1,7 @@