kintex/mobile/lib/roleTrack.ts
2026-07-13 05:16:35 +09:00

79 lines
2.9 KiB
TypeScript

/*
* 역할별 랜딩·트랙 판정 (모바일) — 웹 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(관람객) → 티켓 지갑(/tickets) — B2C 진입
*/
export function landingPathForTrack(track: Track): string {
switch (track) {
case 'agency':
return '/(tabs)/field';
case 'visitor':
return '/tickets';
case 'admin':
case 'ops':
case 'business':
default:
return '/(tabs)';
}
}
/** 입력으로부터 랜딩 라우트 계산(예외 시 탭 홈 폴백). */
export function landingPathFor(input: LandingInput): string {
try {
return landingPathForTrack(resolveLandingTrack(input));
} catch {
return '/(tabs)';
}
}