feat (Worker): add a worker to check and adjust the TikTok graph
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { auth } from "@/lib/auth";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
|
||||
const PLAN_RANK: Record<string, number> = { free: 0, pro: 1, elite: 2, team: 3 };
|
||||
|
||||
const PERIOD_MIN_PLAN: Record<string, string> = {
|
||||
"7d": "free",
|
||||
"30d": "pro",
|
||||
"90d": "pro",
|
||||
"all": "elite",
|
||||
};
|
||||
|
||||
const PERIOD_DAYS: Record<string, number | null> = {
|
||||
"7d": 7,
|
||||
"30d": 30,
|
||||
"90d": 90,
|
||||
"all": null,
|
||||
};
|
||||
|
||||
// Plan max history cap (even for "all")
|
||||
const PLAN_MAX_DAYS: Record<string, number | null> = {
|
||||
free: 7,
|
||||
pro: 90,
|
||||
elite: null, // illimité
|
||||
team: null,
|
||||
};
|
||||
|
||||
async function getAuthedUserId() {
|
||||
const session = await auth();
|
||||
if (!session?.user) return null;
|
||||
return (session.user as { id?: string }).id ?? null;
|
||||
}
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
const userId = await getAuthedUserId();
|
||||
if (!userId) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
|
||||
const period = req.nextUrl.searchParams.get("period") ?? "7d";
|
||||
|
||||
const user = await prisma.user.findUnique({ where: { id: userId } });
|
||||
if (!user) return NextResponse.json({ error: "User not found" }, { status: 404 });
|
||||
|
||||
const plan = (user as any).plan ?? "free";
|
||||
|
||||
// Vérif accès à la période demandée
|
||||
const requiredPlan = PERIOD_MIN_PLAN[period] ?? "free";
|
||||
if (PLAN_RANK[plan] < PLAN_RANK[requiredPlan]) {
|
||||
return NextResponse.json({ error: "Plan insuffisant pour cette période" }, { status: 403 });
|
||||
}
|
||||
|
||||
const account = await prisma.trackedAccount.findFirst({
|
||||
where: { userId, platform: "tiktok" },
|
||||
});
|
||||
if (!account) return NextResponse.json([], { status: 200 });
|
||||
|
||||
// Calcul de la date de début
|
||||
const periodDays = PERIOD_DAYS[period];
|
||||
const planMaxDays = PLAN_MAX_DAYS[plan];
|
||||
|
||||
let since: Date | undefined;
|
||||
if (periodDays !== null) {
|
||||
since = new Date(Date.now() - periodDays * 86_400_000);
|
||||
} else if (planMaxDays !== null) {
|
||||
since = new Date(Date.now() - planMaxDays * 86_400_000);
|
||||
}
|
||||
// sinon : illimité (team/elite + all)
|
||||
|
||||
const snapshots = await prisma.snapshot.findMany({
|
||||
where: {
|
||||
accountId: account.id,
|
||||
...(since ? { createdAt: { gte: since } } : {}),
|
||||
},
|
||||
orderBy: { createdAt: "asc" },
|
||||
select: {
|
||||
createdAt: true,
|
||||
followers: true,
|
||||
likes: true,
|
||||
videoCount: true,
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json(snapshots);
|
||||
}
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
const userId = await getAuthedUserId();
|
||||
if (!userId) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
|
||||
const body = await req.json();
|
||||
const { followers, likes, videoCount, displayName, openId } = body;
|
||||
|
||||
if (followers === undefined) {
|
||||
return NextResponse.json({ error: "Champ 'followers' requis" }, { status: 400 });
|
||||
}
|
||||
|
||||
// Upsert TrackedAccount
|
||||
let account = await prisma.trackedAccount.findFirst({
|
||||
where: { userId, platform: "tiktok" },
|
||||
});
|
||||
if (!account) {
|
||||
account = await prisma.trackedAccount.create({
|
||||
data: {
|
||||
userId,
|
||||
platform: "tiktok",
|
||||
username: displayName ?? openId ?? "unknown",
|
||||
accountId: openId ?? userId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const snapshot = await prisma.snapshot.create({
|
||||
data: {
|
||||
accountId: account.id,
|
||||
followers: followers ?? 0,
|
||||
likes: likes ?? 0,
|
||||
videoCount: videoCount ?? 0,
|
||||
views: 0,
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json(snapshot, { status: 201 });
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user