← back to Dear Bubbe Nextjs
app/api/chat-v2/route.ts
106 lines
/**
* Chat API v2 - With Feature Checking
*
* This is a parallel implementation that adds feature checking
* without modifying the existing /api/chat endpoint
* You can switch to this when ready, or run both in parallel
*/
import { NextRequest, NextResponse } from 'next/server';
import { checkChatFeatures, logFeatureAttempt } from '@/lib/feature-middleware';
import { getUserSession } from '@/lib/user-session';
// Import the existing chat handler (we'll wrap it)
// This assumes your existing chat logic is modularized
// If not, you can copy the existing chat logic here
export async function POST(req: NextRequest) {
try {
const body = await req.json();
const { message, userId: providedUserId } = body;
// Get or generate user ID
const userId = providedUserId ||
req.cookies.get('userId')?.value ||
req.headers.get('x-user-id') ||
`user_${Date.now()}`;
// Get user session to know their plan
const session = getUserSession(userId);
// Check if the message requests any premium features
const featureCheck = checkChatFeatures(message, userId);
// Log feature attempts for analytics
if (featureCheck.blockedFeatures) {
featureCheck.blockedFeatures.forEach(feature => {
logFeatureAttempt(userId, feature, false);
});
}
// If user is trying to use premium features they don't have access to,
// we can either:
// 1. Block the request entirely (harsh)
// 2. Respond with a Bubbe upsell message (better UX)
// 3. Give partial response with upsell (best UX)
if (featureCheck.hasRestriction && featureCheck.bubbeResponse) {
// Option 2: Respond with Bubbe-style upsell
return NextResponse.json({
response: featureCheck.bubbeResponse,
plan: session.plan,
blockedFeatures: featureCheck.blockedFeatures,
showUpgrade: true
});
}
// No restrictions, proceed with normal chat
// Here you would call your existing chat handler
// For now, returning a placeholder
const normalResponse = await processNormalChat(message, userId);
// Set cookie to persist user ID
const response = NextResponse.json({
response: normalResponse,
plan: session.plan,
showUpgrade: false
});
response.cookies.set('userId', userId, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 60 * 60 * 24 * 365 // 1 year
});
return response;
} catch (error) {
console.error('Chat v2 API error:', error);
return NextResponse.json(
{ error: 'Failed to process chat request' },
{ status: 500 }
);
}
}
/**
* Process normal chat without restrictions
* This is where you'd integrate with your existing chat logic
*/
async function processNormalChat(message: string, userId: string): Promise<string> {
// TODO: Call your existing chat handler here
// For now, returning a placeholder response
// Example integration:
// const response = await fetch('http://localhost:3011/api/chat', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify({ message, userId })
// });
// const data = await response.json();
// return data.response;
return "This is where your normal Bubbe response would go. Oy vey, such a setup!";
}