120 lines · 4.8 KB
import { all, first } from "./db";

const DAY_MS = 24 * 60 * 60 * 1000;

type Count = { count: number };

async function count(sql: string, ...params: (string | number)[]): Promise<number> {
  return (await first<Count>(sql, ...params))?.count ?? 0;
}

export type AdminOrgRow = { id: string; name: string; members: number; repos: number; sites: number; reports: number };
export type AdminUserRow = {
  id: string;
  name: string;
  email: string;
  verified: boolean;
  isAdmin: boolean;
  repos: number;
  reports: number;
  createdAt: number;
};

/** Site-wide counters for the admin dashboard; every query is a single indexed aggregate over D1. */
export async function adminOverview() {
  const now = Date.now();
  const week = now - 7 * DAY_MS;
  const month = now - 30 * DAY_MS;
  const [
    users,
    verifiedUsers,
    newUsersWeek,
    newUsersMonth,
    admins,
    twoFactorUsers,
    orgs,
    newOrgsMonth,
    repos,
    publicRepos,
    sites,
    activeSites,