feat: pre-registrant management and invitation system

Admin interface to review, filter, and batch-invite the 95 pre-registrants
from Baby Ghosts. Accept-invitation page pre-fills their data and collects
circle, pronouns, motivation, contribution tier, and agreement before
creating their member record.
This commit is contained in:
Jennie Robinson Faber 2026-04-06 14:46:11 +01:00
parent bab53cec9e
commit 501be10bfe
15 changed files with 1896 additions and 1 deletions

View file

@ -351,6 +351,39 @@ export const memberInviteSchema = z.object({
emailTemplate: z.string().min(1).max(10000)
})
// --- Pre-registrant schemas ---
export const preRegistrantStatusUpdateSchema = z.object({
status: z.enum(['pending', 'selected']),
adminNotes: z.string().max(2000).optional()
})
export const preRegistrantBulkStatusSchema = z.object({
ids: z.array(z.string().min(1)).min(1).max(100),
status: z.enum(['pending', 'selected'])
})
export const preRegistrantInviteSchema = z.object({
preRegistrantIds: z.array(z.string().min(1)).min(1).max(20),
emailTemplate: z.string().min(1).max(10000)
})
export const inviteVerifySchema = z.object({
token: z.string().min(1)
})
export const inviteAcceptSchema = z.object({
preRegistrationId: z.string().min(1),
name: z.string().min(1).max(200),
pronouns: z.string().max(100).optional(),
location: z.string().max(200).optional(),
circle: z.enum(['community', 'founder', 'practitioner']),
motivation: z.string().max(5000).optional(),
contributionTier: z.enum(['0', '5', '15', '30', '50']),
agreedToTerms: z.literal(true),
token: z.string().min(1)
})
// --- Tag schemas ---
export const tagSuggestionSchema = z.object({