Files
FrenoCorp/server/trpc/beta-router.ts
Michael Freno bef1d7f829 FRE-750: Break infinite recovery cascade, reassign FRE-620 to Founding Engineer
- Cancelled 700+ runaway recovery issues (FRE-767 through FRE-2000+)
- Reassigned FRE-620 (analytics setup) from error-state Senior Engineer to available Founding Engineer
- Removed blocker chain that was preventing FRE-620 from progressing
- Documented system bug: recovery system creates recovery issues for cancelled recovery issues

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-27 01:22:34 -04:00

86 lines
3.0 KiB
TypeScript

import { publicProcedure } from './router';
import { z } from 'zod';
import { eq } from 'drizzle-orm';
import { waitlistSignups, waitlistEvents } from '../../src/db/schema';
export const betaRouter = {
signup: publicProcedure
.input(z.object({
name: z.string().min(1).max(200),
email: z.string().email(),
primaryRole: z.string().max(100),
scriptsWritten: z.string().max(50).optional(),
currentSoftware: z.string().max(100).optional(),
softwareLove: z.string().max(2000).optional(),
softwareFrustrate: z.string().max(2000).optional(),
hoursPerWeek: z.string().max(50).optional(),
willingFeedback: z.string().max(100).optional(),
joinDiscord: z.string().max(100).optional(),
discordUsername: z.string().max(100).optional(),
excitedFeatures: z.array(z.string()).optional(),
heardAbout: z.string().max(100).optional(),
additionalInfo: z.string().max(2000).optional(),
utmSource: z.string().max(100).optional(),
utmMedium: z.string().max(100).optional(),
utmCampaign: z.string().max(100).optional(),
utmContent: z.string().max(100).optional(),
utmTerm: z.string().max(100).optional(),
}))
.mutation(async ({ input, ctx }) => {
const existingRows = await ctx.db!.select()
.from(waitlistSignups)
.where(eq(waitlistSignups.email, input.email.toLowerCase()));
const existing = existingRows[0];
if (existing) {
return { success: true, alreadyApplied: true, id: existing.id };
}
const betaData = {
primaryRole: input.primaryRole,
scriptsWritten: input.scriptsWritten,
currentSoftware: input.currentSoftware,
softwareLove: input.softwareLove,
softwareFrustrate: input.softwareFrustrate,
hoursPerWeek: input.hoursPerWeek,
willingFeedback: input.willingFeedback,
joinDiscord: input.joinDiscord,
discordUsername: input.discordUsername,
excitedFeatures: input.excitedFeatures?.join(', ') || '',
heardAbout: input.heardAbout,
additionalInfo: input.additionalInfo,
utmSource: input.utmSource,
utmMedium: input.utmMedium,
utmCampaign: input.utmCampaign,
utmContent: input.utmContent,
utmTerm: input.utmTerm,
};
const metadata: Record<string, unknown> = {
isBetaApplication: true,
...betaData,
};
const result = await ctx.db!.insert(waitlistSignups)
.values({
email: input.email.toLowerCase(),
name: input.name,
source: 'beta',
status: 'beta-pending',
metadata: JSON.stringify(metadata),
})
.returning();
const signup = result[0];
await ctx.db!.insert(waitlistEvents)
.values({
signupId: signup!.id,
eventType: 'beta-application',
eventData: JSON.stringify(betaData),
});
return { success: true, alreadyApplied: false, id: signup!.id };
}),
};