usePortalStore now persists state in sessionStorage instead of localStorage. Tab-close clears the session implicitly; explicit logout + 401 paths invoke reset() which iterates the `crewli:portal:` prefix and removes every key (forward-compatible for future portal-namespaced state). Storage keys are renamed under the canonical prefix: - crewli_portal_user_events_v1 → crewli:portal:events - crewli_portal_active_event_id_v1 → crewli:portal:activeEventId The single new prefix-clear function (clearStoragePrefix) replaces the hand-listed key removals, so future portal-namespaced state additions need no reset() change. useAuthStore.handleUnauthorized() (the 401 interceptor target) is now async and invokes clearAll() — the canonical session-cleanup hub — restoring the portal-storage cleanup that the deleted usePortalAuthStore.handleUnauthorized previously owned. The merge in Phase E left this gap; this commit closes it. Adds 7 vitest specs in stores/portal/__tests__/usePortalStore.spec.ts covering: sessionStorage persistence, reset() prefix-iteration, non-prefixed-key isolation, reactive state reset, useAuthStore.clearAll + handleUnauthorized integration. Test count 198 → 205. Lint + typecheck clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Crewli — Organizer SPA
Main product UI for organisation and event staff (Vue 3 + Vuexy + Vuetify). Lives in this repo; only re-copy from Vuexy when upgrading the template.
Setup
- Install dependencies:
pnpm install
- Create
.env.local:
VITE_API_URL=http://localhost:8000/api/v1
VITE_APP_NAME="Crewli Organizer"
- Dev server uses port 5174 (see
vite.config.tsor run from repo root:make app).
pnpm dev --port 5174
Port
Runs on http://localhost:5174
Production: e.g. VITE_API_URL=https://api.crewli.app/api/v1 and host the SPA at https://crewli.app (see api/.env.example for FRONTEND_APP_URL and SANCTUM_STATEFUL_DOMAINS).