"use server"; import config from "@payload-config"; import { getPayload } from "payload"; import type { LeadershipTransfer } from "@/payload-types"; import { isPayloadUser } from "@/utils/access-control/isPayloadUser"; import { cancelLeadershipTransfer as cancelLeadershipTransferCore, requestLeadershipTransfer as requestLeadershipTransferCore, resolveLeadershipTransfer as resolveLeadershipTransferCore, } from "@/lib/transfers/leadership"; export interface ActionResult { readonly success: boolean; readonly error?: string; readonly data?: T; } /** * Web actions for leadership-initiated removals. The roster page's client * components call requestDivisionRemoval/cancelDivisionRemoval; the transfers * page's leadership section calls resolveLeadershipTransfer. The lib re-validates * every guard (leader authority, pending-only transitions, superuser-only * resolution), so these actions only authenticate and delegate. */ async function authenticate() { const payloadConfig = await config; const payload = await getPayload({ config: payloadConfig }); const { headers } = await import("next/headers"); const hdrs = await headers(); const { user } = await payload.auth({ headers: hdrs, canSetHeaders: false }); if (!isPayloadUser(user)) { throw new Error("Unauthorized"); } return { payload, user }; } function actionFailure(caughtError: unknown): ActionResult { const message = caughtError instanceof Error ? caughtError.message : "Unknown error"; return { success: false, error: message === "Unauthorized" ? "You must be logged in." : message, }; } export async function requestDivisionRemoval(input: { readonly subjectId: number; readonly fromAssignmentId: number; readonly reason?: string; }): Promise> { try { const { payload, user } = await authenticate(); const transfer = await requestLeadershipTransferCore(payload, user, { subjectId: input.subjectId, fromAssignmentId: input.fromAssignmentId, ...(input.reason !== undefined ? { reason: input.reason } : {}), }); return { success: true, data: transfer }; } catch (caughtError) { return actionFailure(caughtError); } } export async function cancelDivisionRemoval( transferId: number, ): Promise> { try { const { payload, user } = await authenticate(); const transfer = await cancelLeadershipTransferCore(payload, user, transferId); return { success: true, data: transfer }; } catch (caughtError) { return actionFailure(caughtError); } } export async function resolveLeadershipTransfer( transferId: number, approve: boolean, note?: string, ): Promise> { try { const { payload, user } = await authenticate(); const transfer = await resolveLeadershipTransferCore(payload, user, transferId, { approve, ...(note !== undefined ? { note } : {}), }); return { success: true, data: transfer }; } catch (caughtError) { return actionFailure(caughtError); } }