revops + onboarding
This commit is contained in:
@@ -1,14 +1,19 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import { cookies } from 'next/headers';
|
||||
import { db } from '@/lib/db';
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import { db } from '@/lib/db';
|
||||
import { z } from 'zod';
|
||||
import { csrfProtection } from '@/lib/csrf';
|
||||
import { rateLimit, getClientIdentifier, RateLimits } from '@/lib/rateLimit';
|
||||
import { getAuthCookieOptions } from '@/lib/cookieConfig';
|
||||
import { signupSchema, validateRequest } from '@/lib/validationSchemas';
|
||||
import { sendWelcomeEmail } from '@/lib/email';
|
||||
import { sendConversionEvent } from '@/lib/meta';
|
||||
import { getAuthCookieOptions } from '@/lib/cookieConfig';
|
||||
import { signupSchema, validateRequest } from '@/lib/validationSchemas';
|
||||
import { sendWelcomeEmail } from '@/lib/email';
|
||||
import { sendConversionEvent } from '@/lib/meta';
|
||||
import {
|
||||
ATTRIBUTION_COOKIE_NAME,
|
||||
getEmailDomain,
|
||||
parseAttributionCookie,
|
||||
} from '@/lib/revops';
|
||||
import { triggerLifecycleScoring } from '@/lib/revops-server';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
@@ -67,14 +72,29 @@ export async function POST(request: NextRequest) {
|
||||
// Hash password
|
||||
const hashedPassword = await bcrypt.hash(password, 12);
|
||||
|
||||
// Create user
|
||||
const user = await db.user.create({
|
||||
data: {
|
||||
name,
|
||||
email,
|
||||
password: hashedPassword,
|
||||
},
|
||||
});
|
||||
const firstTouch = parseAttributionCookie(request.cookies.get(ATTRIBUTION_COOKIE_NAME)?.value);
|
||||
const onboardingStartedAt = new Date();
|
||||
|
||||
// Create user
|
||||
const user = await db.user.create({
|
||||
data: {
|
||||
name,
|
||||
email,
|
||||
password: hashedPassword,
|
||||
onboardingStartedAt,
|
||||
emailDomain: getEmailDomain(email),
|
||||
signupSource: firstTouch?.signupSource || null,
|
||||
signupMedium: firstTouch?.signupMedium || null,
|
||||
signupCampaign: firstTouch?.signupCampaign || null,
|
||||
signupContent: firstTouch?.signupContent || null,
|
||||
signupTerm: firstTouch?.signupTerm || null,
|
||||
signupReferrer: firstTouch?.signupReferrer || null,
|
||||
signupLandingPath: firstTouch?.signupLandingPath || '/signup',
|
||||
signupFirstSeenAt: firstTouch?.signupFirstSeenAt ? new Date(firstTouch.signupFirstSeenAt) : onboardingStartedAt,
|
||||
},
|
||||
});
|
||||
|
||||
triggerLifecycleScoring(user.id, 'signup');
|
||||
|
||||
// Send welcome email (fire-and-forget — never block signup)
|
||||
try {
|
||||
@@ -97,20 +117,22 @@ export async function POST(request: NextRequest) {
|
||||
}).catch(console.error);
|
||||
|
||||
// Create response
|
||||
const response = NextResponse.json({
|
||||
success: true,
|
||||
user: {
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
plan: 'FREE',
|
||||
const response = NextResponse.json({
|
||||
success: true,
|
||||
needsOnboarding: true,
|
||||
user: {
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
plan: 'FREE',
|
||||
},
|
||||
});
|
||||
|
||||
// Set cookie for auto-login after signup
|
||||
response.cookies.set('userId', user.id, getAuthCookieOptions());
|
||||
|
||||
return response;
|
||||
|
||||
// Set cookie for auto-login after signup
|
||||
response.cookies.set('userId', user.id, getAuthCookieOptions());
|
||||
response.cookies.delete(ATTRIBUTION_COOKIE_NAME);
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
return NextResponse.json(
|
||||
@@ -125,4 +147,4 @@ export async function POST(request: NextRequest) {
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user