import { all, first } from "./db";
import { allSites } from "./sites/store";
import { siteDirectoryReady, siteDirectoryStats, type SiteStats } from "./sites/directory";
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;
};
/** Until the directory is backfilled: every site row, read from its scope. */
async function scannedSiteStats(now: number, week: number): Promise<SiteStats> {
const allSiteRows = await allSites();
const siteCount = (keep: (site: (typeof allSiteRows)[number]) => boolean) => allSiteRows.filter(keep).length;
const siteOwner = new Map(allSiteRows.map((site) => [site.id, site.owner_id]));
const sitesByOwner = new Map<string, number>();
for (const site of allSiteRows) {
if (site.owner_id) sitesByOwner.set(site.owner_id, (sitesByOwner.get(site.owner_id) ?? 0) + 1);
}
const openSiteReports = await all<{ site_id: string }>(
"SELECT site_id FROM abuse_reports WHERE status = 'open' AND site_id IS NOT NULL",
);
const reportsByOwner = new Map<string, number>();
for (const report of openSiteReports) {
const owner = siteOwner.get(report.site_id);
if (owner) reportsByOwner.set(owner, (reportsByOwner.get(owner) ?? 0) + 1);