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 },
|
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(
|
router.get(
|
||||||
"/costs",
|
"/costs",
|
||||||
authenticate,
|
authenticate,
|
||||||
@@ -79,9 +86,7 @@ router.post(
|
|||||||
cost += (seasons.length - 1) * (settings?.tvPerSeasonCost || 250);
|
cost += (seasons.length - 1) * (settings?.tvPerSeasonCost || 250);
|
||||||
const dbBalance = user.totalEarned - user.totalSpent;
|
const dbBalance = user.totalEarned - user.totalSpent;
|
||||||
if (dbBalance < cost)
|
if (dbBalance < cost)
|
||||||
return res
|
return res.status(400).json({
|
||||||
.status(400)
|
|
||||||
.json({
|
|
||||||
error: "Insufficient balance",
|
error: "Insufficient balance",
|
||||||
required: cost,
|
required: cost,
|
||||||
current: dbBalance,
|
current: dbBalance,
|
||||||
@@ -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(
|
router.post(
|
||||||
"/webhook",
|
"/webhook",
|
||||||
asyncHandler(async (req, res) => {
|
asyncHandler(async (req, res) => {
|
||||||
@@ -139,12 +194,7 @@ router.post(
|
|||||||
req.body.requestId ??
|
req.body.requestId ??
|
||||||
req.body.id ??
|
req.body.id ??
|
||||||
req.body.overseer_request_id;
|
req.body.overseer_request_id;
|
||||||
const statusRaw = String(req.body.status || "").toUpperCase();
|
const status = mapOverseerStatus(req.body.status);
|
||||||
let status = "PENDING";
|
|
||||||
if (statusRaw === "APPROVED" || statusRaw === "COMPLETED")
|
|
||||||
status = "APPROVED";
|
|
||||||
else if (statusRaw === "DECLINED" || statusRaw === "FAILED")
|
|
||||||
status = "DECLINED";
|
|
||||||
if (!rawId) return res.status(400).json({ error: "Missing fields" });
|
if (!rawId) return res.status(400).json({ error: "Missing fields" });
|
||||||
const request = await prisma.contentRequest.findFirst({
|
const request = await prisma.contentRequest.findFirst({
|
||||||
where: { overseerRequestId: Number(rawId) },
|
where: { overseerRequestId: Number(rawId) },
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
@@ -10,7 +11,6 @@ import {
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
import { api, authApi, overseerApi, userApi } from "@/lib/api";
|
import { api, authApi, overseerApi, userApi } from "@/lib/api";
|
||||||
import { useStore } from "@/lib/store";
|
import { useStore } from "@/lib/store";
|
||||||
@@ -43,6 +43,7 @@ export default function DashboardPage() {
|
|||||||
}
|
}
|
||||||
loadWalletAndPending();
|
loadWalletAndPending();
|
||||||
loadCosts();
|
loadCosts();
|
||||||
|
syncPending();
|
||||||
}, [isAuthenticated, router]);
|
}, [isAuthenticated, router]);
|
||||||
|
|
||||||
const loadWalletAndPending = async () => {
|
const loadWalletAndPending = async () => {
|
||||||
@@ -65,6 +66,12 @@ export default function DashboardPage() {
|
|||||||
setRequestCosts(costsRes.data);
|
setRequestCosts(costsRes.data);
|
||||||
} catch {}
|
} catch {}
|
||||||
};
|
};
|
||||||
|
const syncPending = async () => {
|
||||||
|
try {
|
||||||
|
await api.post("/overseer/sync-pending");
|
||||||
|
await loadWalletAndPending();
|
||||||
|
} catch {}
|
||||||
|
};
|
||||||
const handleLogout = async () => {
|
const handleLogout = async () => {
|
||||||
try {
|
try {
|
||||||
await authApi.logout();
|
await authApi.logout();
|
||||||
@@ -72,9 +79,6 @@ export default function DashboardPage() {
|
|||||||
logout();
|
logout();
|
||||||
router.push("/login");
|
router.push("/login");
|
||||||
};
|
};
|
||||||
const handleRefresh = () => {
|
|
||||||
loadWalletAndPending();
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isLoading) return <div className="p-8">Loading...</div>;
|
if (isLoading) return <div className="p-8">Loading...</div>;
|
||||||
|
|
||||||
@@ -157,7 +161,7 @@ export default function DashboardPage() {
|
|||||||
<WatchHistory />
|
<WatchHistory />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="requests">
|
<TabsContent value="requests">
|
||||||
<RequestHistory onRefresh={handleRefresh} />
|
<RequestHistory onRefresh={syncPending} />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="leaderboard">
|
<TabsContent value="leaderboard">
|
||||||
<Leaderboard />
|
<Leaderboard />
|
||||||
|
|||||||
Reference in New Issue
Block a user