import Link from 'next/link' import { redirect } from 'next/navigation' import { detectMultiAccounts, type MultiAccountCluster } from '@/actions/multi-account-detect' import { Badge } from '@/components/ui/badge' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { canAccess, getAdminContext, PERMS } from '@/lib/permissions' export default async function MultiAccountsPage({ searchParams, }: { searchParams: Promise> }) { const { session, permissions } = await getAdminContext() if (!canAccess(permissions, PERMS.USERS_VIEW, session.user.rank)) redirect('/admin') const params = await searchParams const minAccounts = Math.max(2, Number(params.min) || 2) const limit = Math.min(200, Number(params.limit) || 50) const result = await detectMultiAccounts({ minAccounts, limit }) const clusters: MultiAccountCluster[] = result.ok ? ((result.data as { clusters: MultiAccountCluster[] }).clusters ?? []) : [] return (

Multi-account detector

Clusters of users sharing a registration IP, current IP, or machine ID. Detection is passive — no AI, just a GROUP BY with index support.

{clusters.length === 0 ? ( No clusters found at the current thresholds. ) : (
{clusters.map((cluster) => ( {cluster.label} {cluster.accountCount} accounts share this identifier
{cluster.accounts.map((acc) => ( {acc.username} #{acc.id} {acc.rank >= 5 && staff} {acc.online === '1' && ( )} ))} {cluster.accountCount > cluster.accounts.length && ( … and {cluster.accountCount - cluster.accounts.length} more )}
))}
)}
) }