chore(ops): strip redundant force-dynamic and probe Redis in ops health

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-07-30 21:33:40 +02:00
1 parent 3e584aadaf
commit 3ac5d6f4f6
60 files changed
+95 -114

No files matched your search

-2
View File
@@ -8,8 +8,6 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import { EditAdDeleteButton } from "../ads-table";
export const dynamic = "force-dynamic";
export default async function EditAd({
params,
}: {
-2
View File
@@ -8,8 +8,6 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import { AdsTable } from "./ads-table";
export const dynamic = "force-dynamic";
export default async function AdminAds() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.PAGES_VIEW, session.user.rank)) {
-2
View File
@@ -8,8 +8,6 @@ import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
type ApplicationRow = {
id: bigint;
userId: number;
-2
View File
@@ -8,8 +8,6 @@ import { Button } from "@/components/ui/button";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function EditArticle({
params,
searchParams,
-2
View File
@@ -10,8 +10,6 @@ import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function AdminArticles({
searchParams,
}: {
-2
View File
@@ -6,8 +6,6 @@ import { Button } from "@/components/ui/button";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export const metadata = { title: "Badges" };
export default async function AdminBadges({
-2
View File
@@ -10,8 +10,6 @@ import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function AdminBans() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.BANS_VIEW, session.user.rank)) {
-2
View File
@@ -5,8 +5,6 @@ import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
type Campaign = {
id: number;
name: string;
-2
View File
@@ -6,8 +6,6 @@ import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
type Campaign = {
id: number;
name: string;
-2
View File
@@ -8,8 +8,6 @@ import { loadCatalogItemsData } from "@/lib/services/catalog-items-loader";
import { getAncestors } from "@/lib/services/catalog-tree";
import { CatalogDetailTabs } from "./catalog-detail-tabs";
export const dynamic = "force-dynamic";
export default async function CatalogEditPage({
params,
}: {
+18 -2
View File
@@ -17,8 +17,6 @@ import { prisma } from "@/lib/prisma";
import { siteSettings } from "@/lib/services/site-settings";
import { CommandocentrumControls } from "./commandocentrum-controls";
export const dynamic = "force-dynamic";
function decodeStacktrace(raw: unknown): string {
if (raw == null) return "";
try {
@@ -66,6 +64,7 @@ export default async function CommandoCentrum() {
]);
const dbOk = health.dbOk;
const redisOk = health.redisOk;
const emulatorOnline = health.emulatorOk;
const onlineCount = onlineRoster.count;
const onlineUsers = onlineRoster.users;
@@ -175,6 +174,23 @@ export default async function CommandoCentrum() {
detail={dbOk ? t("connectionHealthy") : t("unreachable")}
state={dbOk ? "ok" : "danger"}
/>
<DiagnosticRow
label="Redis"
detail={
redisOk === true
? "PONG"
: redisOk === false
? "Unreachable"
: "REDIS_URL not configured"
}
state={
redisOk === true
? "ok"
: redisOk === false
? "danger"
: "warn"
}
/>
<DiagnosticRow
label={t("emulatorRcon")}
detail={
+29 -1
View File
@@ -30,6 +30,7 @@ async function getDevOpsData() {
return {
dbStatus: health.dbOk ? ("healthy" as const) : ("error" as const),
dbLatency: health.dbLatencyMs,
redisOk: health.redisOk,
recentErrors,
errorsToday,
emuVersion: emuVersion?.value ?? "Unknown",
@@ -49,7 +50,7 @@ export default async function DevOpsPage() {
return (
<div className="space-y-6">
{/* Status cards */}
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-5">
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Database</CardTitle>
@@ -67,6 +68,33 @@ export default async function DevOpsPage() {
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Redis</CardTitle>
<Server className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<Badge
variant={
data.redisOk === false
? "destructive"
: data.redisOk === true
? "default"
: "secondary"
}
>
{data.redisOk === true
? "Healthy"
: data.redisOk === false
? "Error"
: "Not configured"}
</Badge>
<p className="text-xs text-muted-foreground mt-1">
Cache / rate limits / sessions
</p>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Emulator</CardTitle>
-2
View File
@@ -9,8 +9,6 @@ import { Button } from "@/components/ui/button";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
const TEXTS_LIMIT = 300;
export default async function AdminEmulator() {
-2
View File
@@ -7,8 +7,6 @@ import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function AdminGuildDetailPage({
params,
}: {
-2
View File
@@ -11,8 +11,6 @@ import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function AdminGuildsPage({
searchParams,
}: {
@@ -6,8 +6,6 @@ import { Button } from "@/components/ui/button";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function EditHelpQuestion({
params,
searchParams,
-2
View File
@@ -6,8 +6,6 @@ import { Button } from "@/components/ui/button";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function AdminHelpQuestions() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.PAGES_VIEW, session.user.rank)) {
-2
View File
@@ -8,8 +8,6 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import { AdminHelpTicketDetail } from "./admin-help-ticket-detail";
export const dynamic = "force-dynamic";
export default async function AdminHelpTicketDetailPage({
params,
}: {
-2
View File
@@ -10,8 +10,6 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import { type HelpTicketRow, HelpTicketsTable } from "./help-tickets-table";
export const dynamic = "force-dynamic";
export default async function AdminHelpTicketsPage({
searchParams,
}: {
-2
View File
@@ -6,8 +6,6 @@ import { prisma } from "@/lib/prisma";
import { getAuditLogs } from "@/lib/services/audit";
import { AuditSection, ExportSection } from "./client";
export const dynamic = "force-dynamic";
export default async function AdminHousekeeping({
searchParams,
}: {
-2
View File
@@ -12,8 +12,6 @@ import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
type IpRow = {
id: bigint;
ipAddress: string;
-2
View File
@@ -6,8 +6,6 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import { ItemsBaseEditForm } from "./items-base-edit-form";
export const dynamic = "force-dynamic";
export default async function ItemsBaseDetailPage({
params,
}: {
-2
View File
@@ -10,8 +10,6 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import { StaffActivitiesTable } from "./staff-activities-table";
export const dynamic = "force-dynamic";
const SORT_MAP: Record<string, "createdAt" | "userId" | "action"> = {
when: "createdAt",
staff: "userId",
-2
View File
@@ -6,8 +6,6 @@ import { Button } from "@/components/ui/button";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
const KEYS = [
"maintenance_enabled",
"maintenance_message",
-2
View File
@@ -12,8 +12,6 @@ import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function AdminMarketplacePage({
searchParams,
}: {
-2
View File
@@ -7,8 +7,6 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import { type CfhRow, CfhTable } from "./cfh-table";
export const dynamic = "force-dynamic";
export default async function CfhListPage({
searchParams,
}: {
-2
View File
@@ -13,8 +13,6 @@ import { activeBanWhere } from "@/lib/bans";
import { formatDate } from "@/lib/format-date";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
type RankCount = { rank: number; count: number };
export default async function AdminDashboard() {
-2
View File
@@ -10,8 +10,6 @@ import { calcPagination, parseListParams } from "@/lib/admin-helpers";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function AdminPhotos({
searchParams,
}: {
-2
View File
@@ -9,8 +9,6 @@ import { Button } from "@/components/ui/button";
import { formatDate } from "@/lib/format-date";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export const metadata = { title: "Radio API Keys" };
type ApiKey = {
-2
View File
@@ -10,8 +10,6 @@ import { Button } from "@/components/ui/button";
import { formatDate } from "@/lib/format-date";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export const metadata = { title: "Radio AutoDJ" };
type Track = {
-2
View File
@@ -10,8 +10,6 @@ import { Button } from "@/components/ui/button";
import { formatDate } from "@/lib/format-date";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
type Banner = {
id: bigint;
userId: bigint;
-2
View File
@@ -6,8 +6,6 @@ import { resolveHotelName } from "@/lib/hotel-name";
import { siteSettings } from "@/lib/services/site-settings";
import { EmbedSnippet } from "./embed-snippet";
export const dynamic = "force-dynamic";
export const metadata = { title: "Radio Embed" };
export default async function AdminRadioEmbedPage() {
-2
View File
@@ -3,8 +3,6 @@ import { StatusCard } from "@/components/admin/dashboard";
import { formatDate } from "@/lib/format-date";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
type History = {
id: bigint;
userId: bigint;
-2
View File
@@ -5,8 +5,6 @@ import { Button } from "@/components/ui/button";
import { formatDate } from "@/lib/format-date";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
type Shout = {
id: bigint;
userId: bigint;
-2
View File
@@ -2,8 +2,6 @@ import { getTranslations } from "next-intl/server";
import { DiagnosticRow, StatusCard } from "@/components/admin/dashboard";
import { siteSettings } from "@/lib/services/site-settings";
export const dynamic = "force-dynamic";
export const metadata = { title: "Radio Monitoring" };
const FETCH_TIMEOUT_MS = 4000;
-2
View File
@@ -5,8 +5,6 @@ import { Button } from "@/components/ui/button";
import { formatDate } from "@/lib/format-date";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
type Shout = {
id: bigint;
userId: bigint;
-2
View File
@@ -4,8 +4,6 @@ import { StatusCard } from "@/components/admin/dashboard";
import { Button } from "@/components/ui/button";
import { siteSettings } from "@/lib/services/site-settings";
export const dynamic = "force-dynamic";
export const metadata = { title: "Radio Points" };
const DEFAULTS = {
-2
View File
@@ -8,8 +8,6 @@ import { StatusCard } from "@/components/admin/dashboard";
import { Button } from "@/components/ui/button";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
type Rank = {
id: bigint;
name: string;
-2
View File
@@ -7,8 +7,6 @@ import { StatusCard } from "@/components/admin/dashboard";
import { Button } from "@/components/ui/button";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
type Field = { key: string; comment: string };
type Group = { title: string; fields: Field[] };
-2
View File
@@ -11,8 +11,6 @@ import { Button } from "@/components/ui/button";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
const CURRENCY_TYPES = ["diamonds", "credits", "duckets", "points"];
export default async function AdminRareValues() {
-1
View File
@@ -8,7 +8,6 @@ import { AdvancedSettingsPanel } from "./advanced-settings-panel";
import { FIELD_DEFAULTS, MANAGED_SETTING_KEYS } from "./cms-settings-config";
import { CmsSettingsForm } from "./cms-settings-form";
export const dynamic = "force-dynamic";
export const metadata = { title: "CMS Settings" };
export default async function AdminSettings() {
-2
View File
@@ -7,8 +7,6 @@ import { Button } from "@/components/ui/button";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function EditShopArticle({
params,
}: {
-2
View File
@@ -12,8 +12,6 @@ import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
const PAID_STATUS = new Set(["completed", "paid", "success", "approved"]);
const RECENT_ORDERS = 25;
-2
View File
@@ -6,8 +6,6 @@ import { Button } from "@/components/ui/button";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
type TeamRow = {
id: bigint;
rankName: string;
-1
View File
@@ -15,7 +15,6 @@ import { listCustomThemes } from "@/lib/theme-custom-store";
import { FONTS, PRESETS } from "@/lib/theme-presets";
import { ColorField } from "./color-field";
export const dynamic = "force-dynamic";
export const metadata = { title: "Theme" };
const COLOR_FIELDS: {
-2
View File
@@ -10,8 +10,6 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import { type TicketRow, TicketsTable } from "./tickets-table";
export const dynamic = "force-dynamic";
export default async function AdminTicketsPage({
searchParams,
}: {
-2
View File
@@ -8,8 +8,6 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import { type TransactionRow, TransactionsTable } from "./transactions-table";
export const dynamic = "force-dynamic";
const PAID_STATUS = ["completed", "paid", "success", "approved"] as const;
const FAILED_STATUS = [
"failed",
-2
View File
@@ -1,7 +1,5 @@
import { redirect } from "next/navigation";
export const dynamic = "force-dynamic";
/**
* Legacy URL — the canonical edit UI lives at /admin/users/edit/[id]
* and is gated by PERMS.USERS_EDIT.
-1
View File
@@ -7,7 +7,6 @@ import { Button } from "@/components/ui/button";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { siteSettings } from "@/lib/services/site-settings";
export const dynamic = "force-dynamic";
export const metadata = { title: "VPN" };
const PROVIDERS: { value: string; label: string }[] = [
-2
View File
@@ -11,8 +11,6 @@ import { Button } from "@/components/ui/button";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export const metadata = { title: "Writeable boxes" };
export default async function AdminWriteableBoxes() {
+1
View File
@@ -9,6 +9,7 @@ export const GET = withAdmin({ permission: PERMS.DEVOPS_VIEW }, async () => {
return NextResponse.json({
database: health.dbOk,
dbLatency: health.dbLatencyMs,
redis: health.redisOk,
emulator: health.emulatorOk,
onlineUsers: health.onlineUsers,
timestamp: new Date().toISOString(),
-2
View File
@@ -6,8 +6,6 @@ import { formatDate } from "@/lib/format-date";
import { PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function ModBansPage() {
await requireModPermission([PERMS.MOD_BANS_VIEW, PERMS.BANS_VIEW]);
-2
View File
@@ -6,8 +6,6 @@ import { calcPagination, parseListParams } from "@/lib/admin-helpers";
import { PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function ModCfhListPage({
searchParams,
}: {
-2
View File
@@ -6,8 +6,6 @@ import { positiveBigInt } from "@/lib/api";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function ModHelpTicketDetailPage({
params,
}: {
-2
View File
@@ -13,8 +13,6 @@ import { formatDate } from "@/lib/format-date";
import { PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function ModHelpTicketsPage({
searchParams,
}: {
-2
View File
@@ -13,8 +13,6 @@ import { formatDate } from "@/lib/format-date";
import { PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function ModTicketsPage({
searchParams,
}: {
-2
View File
@@ -8,8 +8,6 @@ import { getAvatarUrl } from "@/lib/imager";
import { PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function ModUserDetailPage({
params,
}: {
-2
View File
@@ -9,8 +9,6 @@ import { PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import type { DataTableColumn } from "@/types/common";
export const dynamic = "force-dynamic";
type ModUserRow = {
id: number;
username: string;
+18 -3
View File
@@ -1,21 +1,25 @@
import "server-only";
import { env } from "@/env";
import { prisma } from "@/lib/prisma";
import { redis } from "@/lib/redis";
import { rcon } from "@/lib/services/rcon";
export type OpsHealth = {
dbOk: boolean;
dbLatencyMs: number;
/** null = REDIS_URL unset (optional); true/false = probe result */
redisOk: boolean | null;
emulatorOk: boolean;
onlineUsers: number;
};
/**
* Shared DB + emulator health probe for CommandoCentrum, DevOps, and APIs.
* Emulator = real RCON `ping` (same semantics as CommandoCentrum /public health).
* Shared DB + Redis + emulator health probe for CommandoCentrum, DevOps, and APIs.
* Semantics match `/api/health` for Redis (null when not configured).
*/
export async function fetchOpsHealth(): Promise<OpsHealth> {
const [db, emulatorOk, onlineUsers] = await Promise.all([
const [db, redisOk, emulatorOk, onlineUsers] = await Promise.all([
(async () => {
try {
const start = Date.now();
@@ -25,6 +29,16 @@ export async function fetchOpsHealth(): Promise<OpsHealth> {
return { dbOk: false, dbLatencyMs: 0 };
}
})(),
(async (): Promise<boolean | null> => {
if (!env.REDIS_URL) return null;
if (!redis) return false;
try {
const pong = await redis.ping();
return pong === "PONG";
} catch {
return false;
}
})(),
rcon.send("ping", null).catch(() => false),
prisma.user.count({ where: { online: "1" } }).catch(() => 0),
]);
@@ -32,6 +46,7 @@ export async function fetchOpsHealth(): Promise<OpsHealth> {
return {
dbOk: db.dbOk,
dbLatencyMs: db.dbLatencyMs,
redisOk,
emulatorOk: Boolean(emulatorOk),
onlineUsers,
};
+29 -1
View File
@@ -1,4 +1,5 @@
import { existsSync, readFileSync } from "node:fs";
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
describe("staff smoke contract", () => {
@@ -50,10 +51,37 @@ describe("staff smoke contract", () => {
it("ships shared ops + ticket queue helpers", () => {
expect(existsSync("src/lib/admin/ops-health.ts")).toBe(true);
const ops = readFileSync("src/lib/admin/ops-health.ts", "utf8");
expect(ops).toContain("redisOk");
expect(ops).toContain("redis.ping");
expect(existsSync("src/lib/admin/ticket-queue-counts.ts")).toBe(true);
expect(existsSync("src/lib/admin/ops-online-users.ts")).toBe(true);
});
it("keeps force-dynamic only on admin/mod layouts", () => {
const hits: string[] = [];
function walk(dir: string) {
for (const name of readdirSync(dir)) {
const p = join(dir, name);
if (statSync(p).isDirectory()) walk(p);
else if (/\.(tsx?|jsx?)$/.test(name)) {
const src = readFileSync(p, "utf8");
if (
/export\s+const\s+dynamic\s*=\s*["']force-dynamic["']/.test(src)
) {
hits.push(p.replace(/\\/g, "/"));
}
}
}
}
walk("src/app/admin");
walk("src/app/mod");
expect(hits.sort()).toEqual([
"src/app/admin/layout.tsx",
"src/app/mod/layout.tsx",
]);
});
it("caches analytics via redisCache", () => {
for (const path of [
"src/app/admin/analytics/page.tsx",