Gmagl
fix: correcciones cr铆ticas y refactorizaci贸n de componentes
3eebcd0
Raw
History Blame Contribute Delete
4.66 kB
import { NextRequest, NextResponse } from "next/server";
import { db } from "@/lib/db";
// GET /api/influencers/report?influencerId=<id>
// Reporting detallado con contabilidad exacta
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url);
const influencerId = searchParams.get("influencerId");
if (!influencerId) return NextResponse.json({ success: false, error: "influencerId es requerido" }, { status: 400 });
// Contar suscriptores por estado
const activeCount = await db.influencerSubscription.count({ where: { influencerId, status: "active" } });
const pausedCount = await db.influencerSubscription.count({ where: { influencerId, status: "paused" } });
const expiredCount = await db.influencerSubscription.count({ where: { influencerId, status: "expired" } });
const cancelledCount = await db.influencerSubscription.count({ where: { influencerId, status: "cancelled" } });
// Obtener todas las suscripciones
const subs = await db.influencerSubscription.findMany({
where: { influencerId },
include: { user: true, earnings: true },
});
// Calcular ingresos exactos desde Earning (contabilidad real)
const earnings = await db.earning.findMany({
where: { subscription: { influencerId } },
});
const totalRevenue = earnings.reduce((sum, e) => sum + (e.status === "completed" ? e.amount : 0), 0);
const pendingRevenue = earnings.reduce((sum, e) => sum + (e.status === "pending" ? e.amount : 0), 0);
const failedRevenue = earnings.reduce((sum, e) => sum + (e.status === "failed" ? e.amount : 0), 0);
return NextResponse.json({
success: true,
influencerId,
summary: {
activeSubscribers: activeCount,
pausedSubscribers: pausedCount,
expiredSubscribers: expiredCount,
cancelledSubscribers: cancelledCount,
totalSubscribers: activeCount + pausedCount + expiredCount + cancelledCount,
},
revenue: {
completed: totalRevenue,
pending: pendingRevenue,
failed: failedRevenue,
total: totalRevenue + pendingRevenue,
},
subscriptions: subs.map((s) => ({
id: s.id,
userId: s.userId,
userName: s.user?.name || "Unknown",
tier: s.tier,
status: s.status,
price: s.price,
joinedAt: s.joinedAt,
nextRenewalDate: s.nextRenewalDate,
autoRenew: s.autoRenew,
})),
paymentDetails: earnings.map((e) => ({
id: e.id,
amount: e.amount,
status: e.status,
type: e.type,
isRecurring: e.isRecurring,
description: e.description,
createdAt: e.createdAt,
})),
});
} catch (error) {
const message = error instanceof Error ? error.message : "Error";
return NextResponse.json({ success: false, error: message }, { status: 500 });
}
}
// POST /api/influencers/report - acciones administrativas
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const { action, subscriptionId } = body;
if (!action || !subscriptionId) return NextResponse.json({ success: false, error: "action y subscriptionId son requeridos" }, { status: 400 });
const sub = await db.influencerSubscription.findUnique({ where: { id: subscriptionId } });
if (!sub) return NextResponse.json({ success: false, error: "Suscripci贸n no encontrada" }, { status: 404 });
if (action === "expire") {
const updated = await db.influencerSubscription.update({
where: { id: subscriptionId },
data: { status: "expired", expiresAt: new Date() },
});
return NextResponse.json({ success: true, message: "Suscripci贸n expirada", subscription: updated });
}
if (action === "pause") {
const updated = await db.influencerSubscription.update({
where: { id: subscriptionId },
data: { status: "paused" },
});
return NextResponse.json({ success: true, message: "Suscripci贸n pausada", subscription: updated });
}
if (action === "resume") {
const updated = await db.influencerSubscription.update({
where: { id: subscriptionId },
data: { status: "active" },
});
return NextResponse.json({ success: true, message: "Suscripci贸n reanudada", subscription: updated });
}
return NextResponse.json({ success: false, error: "action desconocida" }, { status: 400 });
} catch (error) {
const message = error instanceof Error ? error.message : "Error";
return NextResponse.json({ success: false, error: message }, { status: 500 });
}
}