/** * GET /api/stats * Public stats endpoint — proxies Umami for cross-instance federation / observatoires. * Each librodrome instance exposes its own metrics here. * Observatoires call this endpoint on each instance and aggregate. * * Env vars required (private, server-side): * NUXT_UMAMI_API_KEY — Umami API key (read-only) * NUXT_UMAMI_WEBSITE_ID — Umami website ID (internal, server-side) * NUXT_PUBLIC_UMAMI_URL — Umami base URL * NUXT_PUBLIC_TENANT_ID — e.g. "librodrome" or "librodrome-bordeaux" */ export default defineEventHandler(async () => { const config = useRuntimeConfig() const { umamiApiKey } = config const { umamiUrl, umamiWebsiteId, tenantId } = config.public if (!umamiApiKey || !umamiUrl || !umamiWebsiteId) { return { tenant: tenantId, configured: false } } const endAt = Date.now() const startAt = endAt - 30 * 24 * 60 * 60 * 1000 // 30 days const [stats, pageviews] = await Promise.all([ $fetch>(`${umamiUrl}/api/websites/${umamiWebsiteId}/stats`, { headers: { 'x-umami-api-key': umamiApiKey }, query: { startAt, endAt }, }).catch(() => null), $fetch>(`${umamiUrl}/api/websites/${umamiWebsiteId}/pageviews`, { headers: { 'x-umami-api-key': umamiApiKey }, query: { startAt, endAt, unit: 'day', timezone: 'Europe/Paris' }, }).catch(() => null), ]) return { tenant: tenantId, configured: true, period: '30d', stats, pageviews, } })