feat(analytics): Umami integration with per-port admin settings
Adds /[portSlug]/website-analytics dashboard page (pageviews, top pages, top referrers) and a per-port admin config UI for the Umami URL / website-ID / API token. Settings live in system_settings keyed per-port so a future second port has its own Umami account. Adds a website glance tile to the main dashboard, a server-side test-credentials endpoint, and a stable cache key for the active- visitor poll so React Query doesn't fragment the cache per range. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
24
src/app/api/v1/admin/umami/test/route.ts
Normal file
24
src/app/api/v1/admin/umami/test/route.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
import { withAuth, withPermission } from '@/lib/api/helpers';
|
||||
import { testConnection } from '@/lib/services/umami.service';
|
||||
|
||||
/**
|
||||
* POST /api/v1/admin/umami/test - admin-only Umami connection check.
|
||||
*
|
||||
* Returns `{ data: { ok: true, visitors } }` on success or
|
||||
* `{ data: { ok: false, error } }` on failure. Mirrors the shape used by
|
||||
* the Documenso health endpoint so the existing test-button UI pattern
|
||||
* just works.
|
||||
*/
|
||||
export const POST = withAuth(
|
||||
withPermission('admin', 'manage_settings', async (_req, ctx) => {
|
||||
try {
|
||||
const result = await testConnection(ctx.portId);
|
||||
return NextResponse.json({ data: result });
|
||||
} catch (err) {
|
||||
const error = err instanceof Error ? err.message : 'Unknown error';
|
||||
return NextResponse.json({ data: { ok: false, error } });
|
||||
}
|
||||
}),
|
||||
);
|
||||
Reference in New Issue
Block a user