46 lines
1.2 KiB
TypeScript
46 lines
1.2 KiB
TypeScript
'use server'
|
|
|
|
import { z } from 'zod'
|
|
import { createClient } from '@/lib/supabase/server'
|
|
|
|
const UpsertScoreSchema = z.object({
|
|
roundId: z.string().uuid(),
|
|
holeId: z.string().uuid(),
|
|
playerId: z.string().uuid(),
|
|
strokes: z.number().int().min(1).max(20),
|
|
})
|
|
|
|
export async function upsertScore(
|
|
roundId: string,
|
|
holeId: string,
|
|
playerId: string,
|
|
strokes: number,
|
|
) {
|
|
const parsed = UpsertScoreSchema.safeParse({ roundId, holeId, playerId, strokes })
|
|
if (!parsed.success) return { error: parsed.error.issues[0]?.message ?? 'Invalid data' }
|
|
|
|
const supabase = await createClient()
|
|
const {
|
|
data: { user },
|
|
} = await supabase.auth.getUser()
|
|
if (!user) return { error: 'Not authenticated' }
|
|
|
|
// Verify round is active and user is a member (RLS also enforces this)
|
|
const { error } = await (supabase as any)
|
|
.from('scores')
|
|
.upsert(
|
|
{
|
|
round_id: parsed.data.roundId,
|
|
hole_id: parsed.data.holeId,
|
|
player_id: parsed.data.playerId,
|
|
strokes: parsed.data.strokes,
|
|
updated_by: user.id,
|
|
updated_at: new Date().toISOString(),
|
|
},
|
|
{ onConflict: 'round_id,hole_id,player_id' },
|
|
)
|
|
|
|
if (error) return { error: error.message }
|
|
return { success: true }
|
|
}
|