import 'server-only'; import { cache } from 'react'; import { redirect } from 'next/navigation'; import { readSessionToken } from '@/lib/auth/session'; import { verifySessionToken } from '@/lib/auth/session-token'; import { fetchAdminById } from '@/lib/data/repositories/auth-repository'; import type { AdminUser } from '@/lib/domain/admin-user'; /** * 공식 가이드의 Data Access Layer(DAL) — 인증·인가 판단을 이 파일에 집중시킨다. * `cache()`로 렌더 패스당 세션 조회를 1회로 dedupe한다. * * 이후 모든 mutation(Server Action)은 Repository를 직접 호출하기 전에 반드시 * `verifySession()`(또는 `getSessionAdmin()`)을 거쳐야 한다 — Server Action은 UI를 거치지 않고 * 직접 호출될 수 있으므로 이 검증이 유일한 최종 방어선이다. */ /** 세션 검증 결과를 null 허용으로 반환 — redirect 없이 상태만 알고 싶을 때 사용 (예: 로그인 페이지). */ export const getSessionAdmin = cache(async (): Promise => { const token = await readSessionToken(); if (!token) { return null; } const verified = verifySessionToken(token); if (!verified) { return null; } return fetchAdminById(verified.adminId); }); /** 보호 라우트·Server Action 진입점 — 세션이 없으면 `/login`으로 redirect한다. */ export async function verifySession(): Promise { const admin = await getSessionAdmin(); if (!admin) { redirect('/login'); } return admin; }