908-line lib/actions/classes.ts → lib/actions/classes/{definitions,sessions,
signups,instructor}.ts ('use server') + _guard.ts (requirePermission/Gate) +
_forms.ts (findSpaceForm/hasFormSubmission) + a plain index.ts barrel. All 14
actions preserved verbatim; lib/actions/index.ts unchanged. Helpers stay
internal (not re-exported). tsc 0, tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
41 lines
1.2 KiB
TypeScript
41 lines
1.2 KiB
TypeScript
import { createAdminClient } from '@/lib/supabase/admin'
|
|
|
|
// A class manager need not hold forms.manage, so form lookups + the
|
|
// submission gate use the service client (scoped by space_id) and never
|
|
// return form answers -- only existence/metadata.
|
|
export async function findSpaceForm(
|
|
admin: ReturnType<typeof createAdminClient>,
|
|
spaceId: string,
|
|
formId: string,
|
|
): Promise<{ id: string; status: string; title: string; slug: string } | null> {
|
|
const { data } = await admin
|
|
.from('forms')
|
|
.select('id, status, title, slug')
|
|
.eq('id', formId)
|
|
.eq('space_id', spaceId)
|
|
.maybeSingle()
|
|
return data
|
|
? {
|
|
id: data.id as string,
|
|
status: data.status as string,
|
|
title: data.title as string,
|
|
slug: data.slug as string,
|
|
}
|
|
: null
|
|
}
|
|
|
|
export async function hasFormSubmission(
|
|
admin: ReturnType<typeof createAdminClient>,
|
|
spaceId: string,
|
|
memberId: string,
|
|
formId: string,
|
|
): Promise<boolean> {
|
|
const { count } = await admin
|
|
.from('form_submissions')
|
|
.select('id', { count: 'exact', head: true })
|
|
.eq('space_id', spaceId)
|
|
.eq('form_id', formId)
|
|
.eq('member_id', memberId)
|
|
return (count ?? 0) > 0
|
|
}
|