import { reconcileStaffSessionFromToken, useAuthStore, type StaffUser, type StaffUserType, } from '../stores/auth'; let hydratePromise: Promise | null = null; function isStaffUserType(value: unknown): value is StaffUserType { return value === 'ADMIN' || value === 'AGENT'; } export function resetStaffSessionHydration() { hydratePromise = null; } function hasCompleteStaffUser(u: StaffUser | null | undefined): u is StaffUser { return !!(u?.id && u.username && u.userType); } /** Sync manage_user from JWT + /manage/auth/me (fixes stale localStorage userType). */ export async function hydrateStaffSession(): Promise { const auth = useAuthStore(); if (!auth.token.value) return false; if (hydratePromise) return hydratePromise; hydratePromise = (async () => { reconcileStaffSessionFromToken(); if (!hasCompleteStaffUser(auth.user.value)) { auth.clearStaffSession(); return false; } try { const { default: api } = await import('../api'); const { data } = await api.get('/manage/auth/me'); const raw = data.data as Partial; if (!raw?.id || !raw.username || !isStaffUserType(raw.userType)) { return true; } auth.setSession(auth.token.value, { id: raw.id, username: raw.username, userType: raw.userType, locale: raw.locale, role: raw.role, agentLevel: typeof raw.agentLevel === 'number' ? raw.agentLevel : null, maxAgentLevel: typeof raw.maxAgentLevel === 'number' ? raw.maxAgentLevel : null, canManageSubAgents: raw.canManageSubAgents === true, inviteCode: raw.inviteCode ?? null, }); return true; } catch (e: unknown) { const status = (e as { response?: { status?: number } })?.response?.status; if (status === 401) { auth.clearStaffSession(); return false; } return hasCompleteStaffUser(auth.user.value); } finally { hydratePromise = null; } })(); return hydratePromise; } /** Run before any authenticated route — JWT reconcile + optional /me refresh. */ export async function ensureStaffSession(): Promise { reconcileStaffSessionFromToken(); const auth = useAuthStore(); if (!auth.token.value) return false; if (!hasCompleteStaffUser(auth.user.value)) { reconcileStaffSessionFromToken(); } if (!hasCompleteStaffUser(auth.user.value)) { return false; } return hydrateStaffSession(); }