Restructure /admin into tabbed area with password gate

Backups moves under /admin/backups; new Reports and Categories tabs join
it (categories migrated from the top-level /categories route). The
dashboard's SKU/low-stock/inventory-value cards move into Reports, which
also adds sales totals and a top-selling parts list.

A 5-minute sliding-cookie password gate (27182818) now wraps every
/admin request, including the backup download endpoint, via a
hooks.server.js auth check. The login page sits at /admin/login and
escapes the admin tab chrome via a layout reset.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Beccue
2026-05-16 15:47:42 +05:00
parent df64de4255
commit c882ab5d43
17 changed files with 517 additions and 207 deletions

View File

@ -1,5 +1,12 @@
import { redirect } from '@sveltejs/kit';
import { getDb } from '$lib/server/db.js';
import { startBackupScheduler } from '$lib/server/backup.js';
import {
isAdminAuthed,
isAdminPath,
isLoginPath,
refreshAdminCookie
} from '$lib/server/admin-auth.js';
// Open (and warm) the database on server startup so the first request
// doesn't pay the cost.
@ -8,5 +15,14 @@ startBackupScheduler();
/** @type {import('@sveltejs/kit').Handle} */
export async function handle({ event, resolve }) {
const path = event.url.pathname;
if (isAdminPath(path) && !isLoginPath(path)) {
if (!isAdminAuthed(event)) {
const next = path + event.url.search;
throw redirect(303, `/admin/login?next=${encodeURIComponent(next)}`);
}
// Sliding 5-minute expiry: any request under /admin extends the session.
refreshAdminCookie(event);
}
return resolve(event);
}