feat(onboarding): detect UUID username and add completeProfile layout action

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-19 00:17:20 +08:00
parent 5754c163d7
commit cb325692f7

View File

@@ -1,11 +1,45 @@
import { redirect } from '@sveltejs/kit';
import type { LayoutServerLoad } from './$types';
import { redirect, fail } from '@sveltejs/kit';
import { isErr, unwrapErr } from 'option-t/plain_result';
import { zod, type ZodObjectType } from 'sveltekit-superforms/adapters';
import { setError, superValidate } from 'sveltekit-superforms';
import { patchUserUpdate } from '$lib/api';
import { createApiClient } from '$lib/server/api';
import { callSdk } from '$lib/server/errors';
import { onboardingSchema } from '$lib/schemas/onboarding';
import type { LayoutServerLoad, Actions } from './$types';
export const load: LayoutServerLoad = ({ locals, url, cookies }) => {
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
// onboardingSchema fields are required strings but don't satisfy ZodObjectType's
// Record<string,unknown> index signature — same cast pattern as profile page.
const schema = onboardingSchema as unknown as ZodObjectType;
export const load: LayoutServerLoad = async ({ locals, url, cookies }) => {
if (!locals.user) {
const redirectTo = encodeURIComponent(url.pathname + url.search);
throw redirect(303, `/app/authorize?redirect_to=${redirectTo}`);
}
const theme = (cookies.get('theme') as 'dark' | 'light') ?? 'dark';
return { user: locals.user, theme };
const needsOnboarding = UUID_RE.test(locals.user.username);
const onboardingForm = await superValidate(zod(schema));
return { user: locals.user, theme, needsOnboarding, onboardingForm };
};
export const actions: Actions = {
completeProfile: async (event) => {
const onboardingForm = await superValidate(event.request, zod(schema));
if (!onboardingForm.valid) return fail(400, { onboardingForm });
const api = createApiClient(event);
const result = await callSdk(() =>
patchUserUpdate({
client: api,
body: {
username: onboardingForm.data.username as string,
nickname: onboardingForm.data.nickname as string
}
})
);
if (isErr(result)) return setError(onboardingForm, '', unwrapErr(result).message);
return { onboardingForm };
}
};