'use server'; import { Result } from '@/lib/contracts/Result'; import { CompleteOnboardingMutation } from '@/lib/mutations/onboarding/CompleteOnboardingMutation'; import { GenerateAvatarsMutation } from '@/lib/mutations/onboarding/GenerateAvatarsMutation'; import { CompleteOnboardingInputDTO } from '@/lib/types/generated/CompleteOnboardingInputDTO'; import { revalidatePath } from 'next/cache'; import { routes } from '@/lib/routing/RouteConfig'; /** * Complete onboarding - thin wrapper around mutation * * Pattern: Server Action → Mutation → Service → API Client * * Authentication is handled automatically by the API via cookies. * The BaseApiClient includes credentials: 'include', so cookies are sent automatically. * If authentication fails, the API returns 401/403 which gets converted to domain errors. */ export async function completeOnboardingAction( input: CompleteOnboardingInputDTO ): Promise> { const mutation = new CompleteOnboardingMutation(); const result = await mutation.execute(input); if (result.isErr()) { return Result.err(result.getError()); } revalidatePath(routes.protected.dashboard); return Result.ok({ success: true }); } /** * Generate avatars - thin wrapper around mutation * * Note: This action requires userId to be passed from the client. * The client should get userId from session and pass it as a parameter. */ export async function generateAvatarsAction(params: { userId: string; facePhotoData: string; suitColor: string; }): Promise> { const mutation = new GenerateAvatarsMutation(); const result = await mutation.execute(params); if (result.isErr()) { return Result.err(result.getError()); } const data = result.unwrap(); return Result.ok({ success: data.success, avatarUrls: data.avatarUrls }); }