e16fb16987
SUPER_ADMIN 토큰(company_code=*)이면 등록 회사들 DB 를 순회해 결과를 집계해 돌려주는 CrossTenantAggregator/Controller 추가. 사용자/권한그룹/ 배치/다국어 키 4개 도메인의 list API 가 cross-tenant 모드 지원. UserTable + ResponsiveDataView 에 compact/scrollContainer prop 추가. 페이지 헤더/툴바/페이지네이션은 고정, 테이블만 자체 스크롤. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
47 lines
1.6 KiB
TypeScript
47 lines
1.6 KiB
TypeScript
/**
|
|
* SUPER_ADMIN 의 cross-tenant(전사) 모드 판정 유틸.
|
|
*
|
|
* 백엔드 cross-tenant 엔드포인트가 동작하려면:
|
|
* 1. JWT.user_type === "SUPER_ADMIN"
|
|
* 2. 현재 컨텍스트 == META DB
|
|
* 둘 다 만족해야 함. 프론트는 (1) + (2)를 직접 못 보지만,
|
|
* SUPER_ADMIN 이 회사 도메인으로 switch 하면 JWT.company_code 가 그 회사 코드로 바뀐다.
|
|
* 그러므로 (user_type === "SUPER_ADMIN" && company_code === "*") 가 메타 컨텍스트의 정확한 신호.
|
|
*
|
|
* 회사 도메인으로 switch 한 SUPER_ADMIN 은 JWT.company_code 가 회사 코드로 바뀌어 false 가 됨
|
|
* → 자연스럽게 단일 회사 모드로 복귀.
|
|
*
|
|
* @see notes/gbpark/2026-04-27-cross-tenant-admin-aggregation.md §8.1
|
|
*/
|
|
|
|
interface JwtClaims {
|
|
user_type?: string;
|
|
company_code?: string;
|
|
user_id?: string;
|
|
}
|
|
|
|
/**
|
|
* 토큰의 Base64 페이로드만 디코드. 무결성 검증은 백엔드 책임.
|
|
*/
|
|
export function decodeJwtClaims(): JwtClaims | null {
|
|
if (typeof window === "undefined") return null;
|
|
const token = localStorage.getItem("authToken");
|
|
if (!token) return null;
|
|
try {
|
|
const payload = token.split(".")[1];
|
|
return JSON.parse(atob(payload));
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 현재 SUPER_ADMIN cross-tenant(전사) 모드인가?
|
|
* 어드민 14개 메뉴 API 클라이언트는 이걸로 분기해서
|
|
* /admin/cross-tenant/* 엔드포인트 또는 단일 회사 엔드포인트를 골라 호출.
|
|
*/
|
|
export function isCrossTenantMode(): boolean {
|
|
const c = decodeJwtClaims();
|
|
return c?.user_type === "SUPER_ADMIN" && c?.company_code === "*";
|
|
}
|