BusyBee3333 4e6467ffb0 Add CRESync CRM application with Setup page
- Build complete Next.js CRM for commercial real estate
- Add authentication with JWT sessions and role-based access
- Add GoHighLevel API integration for contacts, conversations, opportunities
- Add AI-powered Control Center with tool calling
- Add Setup page with onboarding checklist (/setup)
- Add sidebar navigation with Setup menu item
- Fix type errors in onboarding API, GHL services, and control center tools
- Add Prisma schema with SQLite for local development
- Add UI components with clay morphism design system

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 17:30:55 -05:00

57 lines
1.5 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/db';
import { getSession, isAdmin } from '@/lib/auth';
import { Role } from '@/types';
export async function GET(request: NextRequest) {
const session = await getSession();
if (!session || !isAdmin(session.user.role as Role)) {
return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
}
try {
const [
totalUsers,
recentSignups,
pendingDFY,
usersWithOnboarding,
] = await Promise.all([
prisma.user.count(),
prisma.user.count({
where: {
createdAt: {
gte: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
},
},
}),
prisma.dFYRequest.count({ where: { status: 'PENDING' } }),
prisma.user.findMany({
include: { onboarding: true, setupStatus: true },
}),
]);
// Calculate high GCI users
const highGCIUsers = usersWithOnboarding.filter(u =>
u.onboarding?.gciLast12Months?.includes('100') ||
u.onboarding?.gciLast12Months?.includes('250')
).length;
// Calculate incomplete setup
const incompleteSetup = usersWithOnboarding.filter(u =>
!u.setupStatus?.smsConfigured || !u.setupStatus?.emailConfigured
).length;
return NextResponse.json({
stats: {
totalUsers,
highGCIUsers,
incompleteSetup,
dfyRequestsPending: pendingDFY,
recentSignups,
},
});
} catch (error) {
return NextResponse.json({ error: 'Failed to fetch stats' }, { status: 500 });
}
}