132 lines
3.8 KiB
TypeScript
132 lines
3.8 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { prisma } from "@/lib/prisma";
|
|
import { requireAuth } from "@/lib/auth";
|
|
import { getUserTier, HALAL_LIMITS } from "@/lib/tiers";
|
|
|
|
export async function GET(request: NextRequest) {
|
|
try {
|
|
const auth = await requireAuth(request);
|
|
if (!auth) {
|
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
}
|
|
|
|
const user = await prisma.user.findUnique({
|
|
where: { id: auth.userId },
|
|
include: { halalUsage: true },
|
|
});
|
|
if (!user) {
|
|
return NextResponse.json({ error: "User not found" }, { status: 404 });
|
|
}
|
|
|
|
const tier = getUserTier(user.isPremium, user.isPro);
|
|
const limits = HALAL_LIMITS[tier];
|
|
|
|
// If no usage record exists yet, return defaults
|
|
const usage = user.halalUsage;
|
|
const queriesUsed = usage?.queriesUsed ?? 0;
|
|
const queriesLimit = usage?.queriesLimit ?? limits.queriesPerDay;
|
|
const periodEnd = usage?.periodEnd?.toISOString() ?? null;
|
|
|
|
const remaining = Math.max(0, queriesLimit - queriesUsed);
|
|
|
|
return NextResponse.json({
|
|
queriesUsed,
|
|
queriesLimit,
|
|
remaining,
|
|
periodEnd,
|
|
tier,
|
|
scope: limits.scope,
|
|
});
|
|
} catch (error) {
|
|
console.error("GET /api/halal/usage error:", error);
|
|
return NextResponse.json(
|
|
{ error: "Internal server error" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const auth = await requireAuth(request);
|
|
if (!auth) {
|
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
}
|
|
|
|
const user = await prisma.user.findUnique({
|
|
where: { id: auth.userId },
|
|
include: { halalUsage: true },
|
|
});
|
|
if (!user) {
|
|
return NextResponse.json({ error: "User not found" }, { status: 404 });
|
|
}
|
|
|
|
const tier = getUserTier(user.isPremium, user.isPro);
|
|
const limits = HALAL_LIMITS[tier];
|
|
|
|
// Get or create usage record
|
|
let usage = user.halalUsage;
|
|
|
|
// Check if period has expired — reset if so
|
|
const now = new Date();
|
|
if (usage && usage.periodEnd && new Date(usage.periodEnd) < now) {
|
|
usage = await prisma.halalUsage.update({
|
|
where: { userId: user.id },
|
|
data: {
|
|
queriesUsed: 0,
|
|
queriesLimit: limits.queriesPerDay,
|
|
periodEnd: new Date(now.getTime() + 24 * 60 * 60 * 1000),
|
|
},
|
|
});
|
|
}
|
|
|
|
if (!usage) {
|
|
const queryLimit = limits.queriesPerDay === Infinity ? 999999 : limits.queriesPerDay;
|
|
usage = await prisma.halalUsage.create({
|
|
data: {
|
|
userId: user.id,
|
|
queriesUsed: 0,
|
|
queriesLimit: queryLimit,
|
|
periodEnd: new Date(now.getTime() + 24 * 60 * 60 * 1000),
|
|
},
|
|
});
|
|
}
|
|
|
|
// Check if allowed
|
|
const effectiveLimit = limits.queriesPerDay === Infinity ? 999999 : usage.queriesLimit;
|
|
if (usage.queriesUsed >= effectiveLimit && limits.queriesPerDay !== Infinity) {
|
|
return NextResponse.json(
|
|
{
|
|
allowed: false,
|
|
remaining: 0,
|
|
queriesUsed: usage.queriesUsed,
|
|
queriesLimit: usage.queriesLimit,
|
|
error: "Daily query limit reached. Upgrade to Premium for unlimited queries.",
|
|
},
|
|
{ status: 429 }
|
|
);
|
|
}
|
|
|
|
// Increment usage
|
|
const updated = await prisma.halalUsage.update({
|
|
where: { userId: user.id },
|
|
data: { queriesUsed: { increment: 1 } },
|
|
});
|
|
|
|
const remaining = Math.max(0, updated.queriesLimit - updated.queriesUsed);
|
|
|
|
return NextResponse.json({
|
|
allowed: true,
|
|
remaining,
|
|
queriesUsed: updated.queriesUsed,
|
|
queriesLimit: updated.queriesLimit,
|
|
});
|
|
} catch (error) {
|
|
console.error("POST /api/halal/usage error:", error);
|
|
return NextResponse.json(
|
|
{ error: "Internal server error" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|