fix: sync pending requests from overseer
This commit is contained in:
@@ -13,6 +13,13 @@ const overseerClient = axios.create({
|
||||
headers: { "X-Api-Key": OVERSEER_API_KEY },
|
||||
});
|
||||
|
||||
const mapOverseerStatus = (status: any) => {
|
||||
const s = Number(status);
|
||||
if (s >= 5) return "APPROVED";
|
||||
if (s === 4) return "DECLINED";
|
||||
return "PENDING";
|
||||
};
|
||||
|
||||
router.get(
|
||||
"/costs",
|
||||
authenticate,
|
||||
@@ -79,13 +86,11 @@ router.post(
|
||||
cost += (seasons.length - 1) * (settings?.tvPerSeasonCost || 250);
|
||||
const dbBalance = user.totalEarned - user.totalSpent;
|
||||
if (dbBalance < cost)
|
||||
return res
|
||||
.status(400)
|
||||
.json({
|
||||
error: "Insufficient balance",
|
||||
required: cost,
|
||||
current: dbBalance,
|
||||
});
|
||||
return res.status(400).json({
|
||||
error: "Insufficient balance",
|
||||
required: cost,
|
||||
current: dbBalance,
|
||||
});
|
||||
const overseerRequest = await overseerClient.post("/request", {
|
||||
mediaType,
|
||||
mediaId,
|
||||
@@ -130,6 +135,56 @@ router.post(
|
||||
});
|
||||
}),
|
||||
);
|
||||
router.post(
|
||||
"/sync-pending",
|
||||
authenticate,
|
||||
asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const pending = await prisma.contentRequest.findMany({
|
||||
where: { userId: req.user!.id, status: "PENDING" },
|
||||
});
|
||||
const updated: any[] = [];
|
||||
for (const request of pending) {
|
||||
try {
|
||||
const response = await overseerClient.get(
|
||||
`/request/${request.overseerRequestId}`,
|
||||
);
|
||||
const mapped = mapOverseerStatus(response.data?.status);
|
||||
if (mapped !== "PENDING") {
|
||||
const result = await prisma.contentRequest.update({
|
||||
where: { id: request.id },
|
||||
data: { status: mapped as any },
|
||||
});
|
||||
if (mapped === "DECLINED") {
|
||||
await prisma.transaction.create({
|
||||
data: {
|
||||
userId: request.userId,
|
||||
type: "ADJUSTMENT",
|
||||
amount: request.creditsCost,
|
||||
description: `Refunded: ${request.title}`,
|
||||
contentTitle: request.title,
|
||||
},
|
||||
});
|
||||
await prisma.user.update({
|
||||
where: { id: request.userId },
|
||||
data: { totalSpent: { decrement: request.creditsCost } },
|
||||
});
|
||||
}
|
||||
io.to(`user:${request.userId}`).emit("request_updated", {
|
||||
id: request.id,
|
||||
status: result.status,
|
||||
title: request.title,
|
||||
});
|
||||
updated.push({
|
||||
id: request.id,
|
||||
status: result.status,
|
||||
title: request.title,
|
||||
});
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
res.json({ success: true, updated });
|
||||
}),
|
||||
);
|
||||
router.post(
|
||||
"/webhook",
|
||||
asyncHandler(async (req, res) => {
|
||||
@@ -139,12 +194,7 @@ router.post(
|
||||
req.body.requestId ??
|
||||
req.body.id ??
|
||||
req.body.overseer_request_id;
|
||||
const statusRaw = String(req.body.status || "").toUpperCase();
|
||||
let status = "PENDING";
|
||||
if (statusRaw === "APPROVED" || statusRaw === "COMPLETED")
|
||||
status = "APPROVED";
|
||||
else if (statusRaw === "DECLINED" || statusRaw === "FAILED")
|
||||
status = "DECLINED";
|
||||
const status = mapOverseerStatus(req.body.status);
|
||||
if (!rawId) return res.status(400).json({ error: "Missing fields" });
|
||||
const request = await prisma.contentRequest.findFirst({
|
||||
where: { overseerRequestId: Number(rawId) },
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
@@ -10,7 +11,6 @@ import {
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { api, authApi, overseerApi, userApi } from "@/lib/api";
|
||||
import { useStore } from "@/lib/store";
|
||||
@@ -43,6 +43,7 @@ export default function DashboardPage() {
|
||||
}
|
||||
loadWalletAndPending();
|
||||
loadCosts();
|
||||
syncPending();
|
||||
}, [isAuthenticated, router]);
|
||||
|
||||
const loadWalletAndPending = async () => {
|
||||
@@ -65,6 +66,12 @@ export default function DashboardPage() {
|
||||
setRequestCosts(costsRes.data);
|
||||
} catch {}
|
||||
};
|
||||
const syncPending = async () => {
|
||||
try {
|
||||
await api.post("/overseer/sync-pending");
|
||||
await loadWalletAndPending();
|
||||
} catch {}
|
||||
};
|
||||
const handleLogout = async () => {
|
||||
try {
|
||||
await authApi.logout();
|
||||
@@ -72,9 +79,6 @@ export default function DashboardPage() {
|
||||
logout();
|
||||
router.push("/login");
|
||||
};
|
||||
const handleRefresh = () => {
|
||||
loadWalletAndPending();
|
||||
};
|
||||
|
||||
if (isLoading) return <div className="p-8">Loading...</div>;
|
||||
|
||||
@@ -157,7 +161,7 @@ export default function DashboardPage() {
|
||||
<WatchHistory />
|
||||
</TabsContent>
|
||||
<TabsContent value="requests">
|
||||
<RequestHistory onRefresh={handleRefresh} />
|
||||
<RequestHistory onRefresh={syncPending} />
|
||||
</TabsContent>
|
||||
<TabsContent value="leaderboard">
|
||||
<Leaderboard />
|
||||
|
||||
Reference in New Issue
Block a user