chore: sync WIP (admin routes, dashboard components, compose files)

This commit is contained in:
2026-08-03 00:03:38 -04:00
parent a022e0f7b7
commit e1623c3a17
13 changed files with 2555 additions and 92 deletions
+4
View File
@@ -23,6 +23,10 @@ TAUTULLI_URL=http://172.20.1.255:8181
TAUTULLI_API_KEY=""
TAUTULLI_WEBHOOK_SECRET=""
# Audiobookshelf
ABS_URL=http://172.20.1.225:13378
ABS_API_TOKEN=""
# Overseer
OVERSEER_URL=http://172.20.1.225:5055
OVERSEER_API_KEY=""
+1 -1
View File
@@ -39,7 +39,7 @@
"@types/bcryptjs": "^2.4.6",
"@types/bs58": "^4.0.4",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/express": "^4.17.25",
"@types/jsonwebtoken": "^9.0.5",
"@types/morgan": "^1.9.9",
"@types/node": "^20.10.5",
+26 -3
View File
@@ -9,6 +9,7 @@ import {
import { asyncHandler } from "../middleware/errorHandler";
import { getSmsLogs, sendSms, sendSmsToUsers } from "../services/plivo";
import { backfillUserHistory } from "../services/tautulli";
import { backfillAudiobookHistory } from "../services/audiobookshelf";
import { prisma } from "../utils/prisma";
const router = Router();
@@ -56,7 +57,10 @@ router.put(
const tvRequestCost = Number(req.body.tvRequestCost);
const tvPerSeasonCost = Number(req.body.tvPerSeasonCost);
const newReleaseMultiplier = Number(req.body.newReleaseMultiplier);
const bonusMultiplier = Number(req.body.bonusMultiplier);
const bonuses = Number(req.body.bonusMultiplier);
// Audiobookshelf settings
const audiobookCreditsPerMinute = Number(req.body.audiobookCreditsPerMinute);
const audiobookMinListenMinutes = Number(req.body.audiobookMinListenMinutes);
if (
isNaN(creditsPerMinute) || creditsPerMinute < 0 ||
@@ -66,7 +70,9 @@ router.put(
isNaN(tvRequestCost) || tvRequestCost < 0 ||
isNaN(tvPerSeasonCost) || tvPerSeasonCost < 0 ||
isNaN(newReleaseMultiplier) || newReleaseMultiplier < 0 ||
isNaN(bonusMultiplier) || bonusMultiplier < 0
isNaN(bonuses) || bonuses < 0 ||
isNaN(audiobookCreditsPerMinute) || audiobookCreditsPerMinute < 0 ||
isNaN(audiobookMinListenMinutes) || audiobookMinListenMinutes < 0
) {
return res.status(400).json({ error: "Invalid numeric values in settings" });
}
@@ -82,7 +88,9 @@ router.put(
tvPerSeasonCost,
newReleaseMultiplier,
bonusMultiplierActive: !!req.body.bonusMultiplierActive,
bonusMultiplier,
bonusMultiplier: bonuses,
audiobookCreditsPerMinute,
audiobookMinListenMinutes,
updatedBy: req.user!.id,
},
});
@@ -232,6 +240,21 @@ router.post(
}),
);
router.post(
"/users/:id/backfill-audiobooks",
authenticate,
requireAdmin,
asyncHandler(async (req: AuthenticatedRequest, res) => {
const user = await prisma.user.findUnique({ where: { id: req.params.id } });
if (!user) return res.status(404).json({ error: "User not found" });
await backfillAudiobookHistory(user);
const updatedUser = await prisma.user.findUnique({
where: { id: user.id },
});
res.json({ success: true, user: updatedUser });
}),
);
router.get(
"/analytics",
authenticate,