feat(web): add profile management
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
37
apps/web/server/api/v1/profile.patch.ts
Normal file
37
apps/web/server/api/v1/profile.patch.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { z } from 'zod'
|
||||
import { requireStageTwoSafeText, requireStageTwoUser, stageTwoApiError, stageTwoDatabase } from '~/server/utils/stage-two-supabase'
|
||||
import { visibleProfile, type ProfileRecord } from '~/server/utils/profile'
|
||||
|
||||
const ProfileUpdateSchema = z.object({
|
||||
displayName: z.string().trim().min(1).max(80).optional(),
|
||||
description: z.string().trim().max(500).optional(),
|
||||
avatarPath: z.string().nullable().optional(),
|
||||
}).strict().refine(value => Object.keys(value).length > 0, 'At least one profile field is required.')
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const user = await requireStageTwoUser(event)
|
||||
const update = ProfileUpdateSchema.parse(await readBody(event))
|
||||
const expectedAvatarPath = `${user.id}/avatar`
|
||||
if (update.avatarPath !== undefined && update.avatarPath !== null && update.avatarPath !== expectedAvatarPath) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Invalid profile picture path.' })
|
||||
}
|
||||
if (update.displayName !== undefined) requireStageTwoSafeText(update.displayName)
|
||||
if (update.description !== undefined) requireStageTwoSafeText(update.description)
|
||||
|
||||
const changes: Record<string, unknown> = { updated_at: new Date().toISOString() }
|
||||
if (update.displayName !== undefined) changes.display_name = update.displayName
|
||||
if (update.description !== undefined) changes.description = update.description
|
||||
if (update.avatarPath !== undefined) changes.avatar_path = update.avatarPath
|
||||
|
||||
const profiles = await stageTwoDatabase<ProfileRecord[]>(`profiles?id=eq.${user.id}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(changes),
|
||||
prefer: 'return=representation',
|
||||
})
|
||||
if (!profiles[0]) throw createError({ statusCode: 404, statusMessage: 'Profile not found.' })
|
||||
return { profile: visibleProfile(profiles[0], useRuntimeConfig().supabaseUrl) }
|
||||
} catch (error) {
|
||||
stageTwoApiError(error)
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user