'use server'; import { revalidatePath } from 'next/cache'; import { verifySession } from '@/lib/auth/dal'; import { fetchStudentMemberById, updateStudentMemberActiveStatus, } from '@/lib/data/repositories/student-member-repository'; import { STUDENT_MEMBERS_PATH } from '@/lib/domain/student-member-query'; export type UpdateStudentActiveStatusState = | { status: 'idle' } | { status: 'error'; error: string } | { status: 'success' }; const GENERIC_ERROR = '요청을 처리할 수 없습니다. 잠시 후 다시 시도해 주세요.'; /** * 학생 회원 사용여부 변경 Server Action — 조회 팝업에서 유일하게 수정 가능한 필드다. * Server Action은 UI를 거치지 않고 직접 POST될 수 있으므로 인증 확인과 입력 검증을 이 * 함수 내부에서 직접 수행한다(§3 SRP 체크). 성공 시 목록 화면을 재검증해 변경된 사용여부가 * 즉시 반영되게 한다. */ export async function updateStudentActiveStatus( _prevState: UpdateStudentActiveStatusState, formData: FormData ): Promise { await verifySession(); const id = formData.get('id'); const isActiveRaw = formData.get('isActive'); if (typeof id !== 'string' || id.trim().length === 0) { return { status: 'error', error: GENERIC_ERROR }; } if (isActiveRaw !== 'true' && isActiveRaw !== 'false') { return { status: 'error', error: GENERIC_ERROR }; } const member = await fetchStudentMemberById(id); if (!member) { return { status: 'error', error: '존재하지 않는 학생 회원입니다.' }; } await updateStudentMemberActiveStatus(id, isActiveRaw === 'true'); revalidatePath(STUDENT_MEMBERS_PATH); return { status: 'success' }; }