feat(admin): redirect legacy section-anchor paths to dynamic routes

Adds a `LEGACY_ADMIN_ANCHORS` map in proxy.ts that 301-redirects any
`/admin/section-<id>` path to its v1.5 dynamic-route equivalent. Pure
URL fragments (`#foo`) never reach the server, so this only catches
path-style legacy URLs (a referrer rewriter could promote a fragment
to a path segment, or someone might bookmark a hand-crafted form). The
in-app callsites that previously emitted `/admin#section-*` anchors
have all been rewritten to use the new routes directly — see the
status-card-grid commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marc-André BombeckandClaude Opus 4.7 committed 2026-05-09 17:00:29 +02:00
1 parent 961e2a9a5c
commit 7a47532231
1 file changed
+34
+34
View File
@@ -49,6 +49,34 @@ const LEGACY_REDIRECTS: Record<string, string> = {
"/zielwerte": "/targets",
};
/**
* v1.5 admin refactor — sections moved from `/admin#section-<id>` anchors
* to per-section dynamic routes under `/admin/<slug>`. Pure URL fragments
* (`#foo`) are never sent to the server, so we cannot redirect those
* here; the in-app callsites (status-card-grid, anything else linking
* into admin) have all been rewritten to use the new routes directly.
*
* What we *can* redirect server-side is the path-style form, in case
* anyone bookmarked `/admin/section-XYZ` (which never existed but is a
* plausible mis-typing) or is following an old URL where the fragment
* was somehow promoted to a path segment by a referrer rewriter.
*/
const LEGACY_ADMIN_ANCHORS: Record<string, string> = {
"/admin/section-system-status": "/admin/system-status",
"/admin/section-admin-general": "/admin/general",
"/admin/section-admin-services": "/admin/services",
"/admin/section-admin-umami": "/admin/integrations",
"/admin/section-admin-glitchtip": "/admin/integrations",
"/admin/section-admin-webpush": "/admin/integrations",
"/admin/section-admin-bugreport": "/admin/integrations",
"/admin/section-admin-feedback": "/admin/feedback",
"/admin/section-admin-reminders": "/admin/reminders",
"/admin/section-user-management": "/admin/users",
"/admin/section-api-tokens": "/admin/api-tokens",
"/admin/section-login-overview": "/admin/login-overview",
"/admin/section-danger-zone": "/admin/danger-zone",
};
export function proxy(request: NextRequest) {
const { pathname } = request.nextUrl;
@@ -72,6 +100,12 @@ export function proxy(request: NextRequest) {
return NextResponse.redirect(new URL(redirect, request.url), 301);
}
// 301 for the v1.5 admin section-anchor → dynamic-route migration.
const legacyAdmin = LEGACY_ADMIN_ANCHORS[pathname];
if (legacyAdmin) {
return NextResponse.redirect(new URL(legacyAdmin, request.url), 301);
}
// Demo mode: block all mutations except login
if (process.env.DEMO_MODE === "true") {
const method = request.method.toUpperCase();