/* * 역할별 랜딩·트랙 판정 (모바일) — 웹 src/frontend/src/lib/roleTrack.ts 로직 이식(패리티). * 우선순위: admin > ops > business > agency > visitor. 판정 불가 시 visitor(관람객) 기본. * * 웹과의 차이(모바일 계약 적응): * · roleCode는 공유 백엔드 /api/auth/login 이 웹과 동일하게 반환한다(AuthUser.roleCode). * roleCode('ADMIN'/'MANAGER')를 우선 사용하고, 누락 시 hallManager=true를 ops 신호로 폴백한다. * · 랜딩 경로는 웹 라우트(/admin·/contractor/dashboard·/visitor·/home) 대신 모바일 라우트로 매핑. */ import type { AuthUser, EventRole, WorkspaceDto } from './types'; export type Track = 'visitor' | 'business' | 'agency' | 'ops' | 'admin'; /** 워크스페이스 역할 → 트랙(스코프 판정용). 웹 trackOf와 동일. */ export function trackOf(role: EventRole | null | undefined): Track { switch (role) { case 'ORGANIZER': case 'EXHIBITOR': return 'business'; case 'CONTRACTOR': return 'agency'; case 'HALL_MANAGER': return 'ops'; default: return 'visitor'; } } /** 랜딩 판정 입력 — 로그인 응답 user(roleCode 포함) + workspaces. */ export interface LandingInput { user?: AuthUser | null; workspaces?: WorkspaceDto[] | null; } /** * 로그인 랜딩 트랙 결정(primaryTrack 우선순위). 웹 resolveLandingTrack 이식. * roleCode('ADMIN'/'MANAGER')를 알면 웹과 동일하게 판정하고, 없으면 hallManager로 ops를 추론한다. */ export function resolveLandingTrack({ user, workspaces }: LandingInput): Track { const role = (user?.roleCode ?? '').toUpperCase(); const ws = workspaces ?? []; if (role === 'ADMIN') return 'admin'; if (role === 'MANAGER' || user?.hallManager || ws.some((w) => w.myRole === 'HALL_MANAGER')) { return 'ops'; } if (ws.some((w) => w.myRole === 'ORGANIZER' || w.myRole === 'EXHIBITOR')) return 'business'; if (ws.some((w) => w.myRole === 'CONTRACTOR')) return 'agency'; return 'visitor'; } /** * 트랙 → 로그인 직후 랜딩 라우트(모바일). * · admin/ops/business → 탭 홈(/(tabs)) — 모바일엔 별도 admin 화면 없음, 홈이 역할 진입 허브 * · agency(장치·시공) → 현장 탭(/(tabs)/field) — 체크리스트 허브 * · visitor(관람객) → 관람객(B2C) 탭 셸(/(visitor)) — 홈·행사·티켓·현장·마이 */ export function landingPathForTrack(track: Track): string { switch (track) { case 'agency': return '/(tabs)/field'; case 'visitor': return '/(visitor)'; case 'admin': case 'ops': case 'business': default: return '/(tabs)'; } } /** 입력으로부터 랜딩 라우트 계산(예외 시 탭 홈 폴백). */ export function landingPathFor(input: LandingInput): string { try { return landingPathForTrack(resolveLandingTrack(input)); } catch { return '/(tabs)'; } }