Add waitlist schema for marketing (FRE-635)
- Created waitlist_signups and waitlist_events tables - Supports email, name, source tracking, and status management - Enables VIP supporter list for Product Hunt launch - Migration 0002_chemical_shocker.sql generated - Fixed brand color in product-hunt-assets-brief.md (#518ac8)
This commit is contained in:
@@ -190,7 +190,7 @@ export const projectRouter = {
|
||||
.where(eq(characters.id, input.id));
|
||||
const character = rows[0];
|
||||
if (!character) {
|
||||
throw new Error(`Character ${input.id} not found`);
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: `Character ${input.id} not found` });
|
||||
}
|
||||
await verifyProjectOwnership(ctx.db!, character.projectId, ctx.userId!);
|
||||
return character;
|
||||
@@ -265,7 +265,7 @@ export const projectRouter = {
|
||||
.where(eq(characters.id, input.id));
|
||||
const existing = existingRows[0];
|
||||
if (!existing) {
|
||||
throw new Error(`Character ${input.id} not found`);
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: `Character ${input.id} not found` });
|
||||
}
|
||||
await verifyProjectOwnership(ctx.db!, existing.projectId, ctx.userId!);
|
||||
|
||||
@@ -304,7 +304,7 @@ export const projectRouter = {
|
||||
.where(eq(characters.id, input.id));
|
||||
const existing = existingRows[0];
|
||||
if (!existing) {
|
||||
throw new Error(`Character ${input.id} not found`);
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: `Character ${input.id} not found` });
|
||||
}
|
||||
await verifyProjectOwnership(ctx.db!, existing.projectId, ctx.userId!);
|
||||
|
||||
@@ -369,8 +369,9 @@ export const projectRouter = {
|
||||
.from(characters)
|
||||
.where(eq(characters.id, input.characterId));
|
||||
if (!rows[0]) {
|
||||
throw new Error(`Character ${input.characterId} not found`);
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: `Character ${input.characterId} not found` });
|
||||
}
|
||||
await verifyProjectOwnership(ctx.db!, rows[0].projectId, ctx.userId!);
|
||||
return await getCharacterStatsImpl(ctx.db!, input.characterId);
|
||||
}),
|
||||
|
||||
@@ -413,7 +414,7 @@ export const projectRouter = {
|
||||
.from(characters)
|
||||
.where(eq(characters.id, input.characterId));
|
||||
if (!rows[0]) {
|
||||
throw new Error(`Character ${input.characterId} not found`);
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: `Character ${input.characterId} not found` });
|
||||
}
|
||||
await verifyProjectOwnership(ctx.db!, rows[0].projectId, ctx.userId!);
|
||||
return await ctx.db!.select()
|
||||
@@ -437,7 +438,7 @@ export const projectRouter = {
|
||||
}))
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
if (input.characterIdA === input.characterIdB) {
|
||||
throw new Error('Cannot create a relationship with the same character');
|
||||
throw new TRPCError({ code: 'BAD_REQUEST', message: 'Cannot create a relationship with the same character' });
|
||||
}
|
||||
|
||||
const charARows = await ctx.db!.select()
|
||||
@@ -447,7 +448,7 @@ export const projectRouter = {
|
||||
.from(characters)
|
||||
.where(eq(characters.id, input.characterIdB));
|
||||
if (!charARows[0] || !charBRows[0]) {
|
||||
throw new Error('Both characters must exist');
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: 'Both characters must exist' });
|
||||
}
|
||||
await verifyProjectOwnership(ctx.db!, charARows[0].projectId, ctx.userId!);
|
||||
|
||||
@@ -495,14 +496,14 @@ export const projectRouter = {
|
||||
.from(characterRelationships)
|
||||
.where(eq(characterRelationships.id, input.id));
|
||||
if (!relRows[0]) {
|
||||
throw new Error(`Relationship ${input.id} not found`);
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: `Relationship ${input.id} not found` });
|
||||
}
|
||||
|
||||
const charARows = await ctx.db!.select()
|
||||
.from(characters)
|
||||
.where(eq(characters.id, relRows[0].characterIdA));
|
||||
if (!charARows[0]) {
|
||||
throw new Error('Character not found');
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: 'Character not found' });
|
||||
}
|
||||
await verifyProjectOwnership(ctx.db!, charARows[0].projectId, ctx.userId!);
|
||||
|
||||
@@ -526,14 +527,14 @@ export const projectRouter = {
|
||||
.from(characterRelationships)
|
||||
.where(eq(characterRelationships.id, input.id));
|
||||
if (!relRows[0]) {
|
||||
throw new Error(`Relationship ${input.id} not found`);
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: `Relationship ${input.id} not found` });
|
||||
}
|
||||
|
||||
const charARows = await ctx.db!.select()
|
||||
.from(characters)
|
||||
.where(eq(characters.id, relRows[0].characterIdA));
|
||||
if (!charARows[0]) {
|
||||
throw new Error('Character not found');
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: 'Character not found' });
|
||||
}
|
||||
await verifyProjectOwnership(ctx.db!, charARows[0].projectId, ctx.userId!);
|
||||
|
||||
@@ -562,7 +563,7 @@ export const projectRouter = {
|
||||
.where(eq(scenes.id, input.id));
|
||||
const scene = rows[0];
|
||||
if (!scene) {
|
||||
throw new Error(`Scene ${input.id} not found`);
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: `Scene ${input.id} not found` });
|
||||
}
|
||||
await verifyProjectOwnership(ctx.db!, scene.projectId, ctx.userId!);
|
||||
return scene;
|
||||
@@ -601,7 +602,7 @@ export const projectRouter = {
|
||||
.from(scenes)
|
||||
.where(eq(scenes.id, input.id));
|
||||
if (!rows[0]) {
|
||||
throw new Error(`Scene ${input.id} not found`);
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: `Scene ${input.id} not found` });
|
||||
}
|
||||
|
||||
const updateData: Record<string, any> = { updatedAt: new Date() };
|
||||
@@ -623,9 +624,12 @@ export const projectRouter = {
|
||||
.from(scenes)
|
||||
.where(eq(scenes.id, input.id));
|
||||
if (!rows[0]) {
|
||||
throw new Error(`Scene ${input.id} not found`);
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: `Scene ${input.id} not found` });
|
||||
}
|
||||
|
||||
// Check project ownership
|
||||
await verifyProjectOwnership(ctx.db!, rows[0].projectId, ctx.userId!);
|
||||
|
||||
await ctx.db!.delete(scenes)
|
||||
.where(eq(scenes.id, input.id));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user