import { Hono } from 'hono'; import { supabase } from '../supabase.js'; import { listEntries } from '../files.js'; import { requireAdmin, roleOf } from '../auth.js'; // Kennzahlen für die Admin-Übersicht. Nur Admins; rein lesend. const stats = new Hono(); stats.use('*', requireAdmin); stats.get('/', async (c) => { // Inhalte aus dem Dateisystem zählen. const content = { beitraege: 0, entwuerfe: 0, library: 0, seiten: 0, rubriken: 0 }; try { for (const e of await listEntries()) { if (e.kind === 'beitrag') { content.beitraege++; if (e.draft) content.entwuerfe++; } else if (e.kind === 'biblio') content.library++; else if (e.kind === 'rubrik') content.rubriken++; else content.seiten++; } } catch { /* Filesystem nicht lesbar → 0 */ } // Nutzer nach Rolle. const users = { total: 0, admin: 0, editor: 0, user: 0 }; try { const { data } = await supabase.auth.admin.listUsers(); for (const u of data?.users || []) { users.total++; users[roleOf(u)] = (users[roleOf(u)] || 0) + 1; } } catch { /* GoTrue nicht erreichbar */ } // Dialog-Zähler (effizient: head + count, keine Zeilen laden). const count = async (table, filter) => { try { let q = supabase.from(table).select('*', { count: 'exact', head: true }); if (filter) q = filter(q); const { count: n } = await q; return n || 0; } catch { return 0; } }; const [forums, threads, comments] = await Promise.all([ count('forums'), count('threads', (q) => q.eq('deleted', false)), count('comments', (q) => q.eq('deleted', false)), ]); return c.json({ content, users, dialog: { forums, threads, comments } }); }); export default stats;