feat(housekeeping): dispatch canonical domain routes

This commit is contained in:
Simo committed 2026-08-28 21:35:08 +02:00
1 parent 2970dff563
commit e5c230ba35
13 files changed
+680 -82

No files matched your search

@@ -0,0 +1,43 @@
import { notFound } from "next/navigation";
import { satisfiesCapability } from "@/features/housekeeping/foundation/capability-context";
import { createHousekeepingRegistry } from "@/features/housekeeping/foundation/registry";
import { matchHousekeepingRoute } from "@/features/housekeeping/foundation/routing/match-route";
import { getHousekeepingCapabilityContext } from "@/features/housekeeping/foundation/server-capability-context";
import { HOUSEKEEPING_MANIFESTS } from "@/features/housekeeping/manifests";
import { HOUSEKEEPING_ROUTE_HANDLERS } from "@/features/housekeeping/route-handlers";
export default async function HousekeepingPreviewRoutePage({
params,
}: {
params: Promise<{ domain: string; segments?: readonly string[] }>;
}) {
const { domain, segments = [] } = await params;
const registry = createHousekeepingRegistry(HOUSEKEEPING_MANIFESTS);
const activeDomain = registry.domains.find((entry) => entry.id === domain);
if (!activeDomain) notFound();
const suffix = segments
.map((segment) => encodeURIComponent(segment))
.join("/");
const canonicalPath = suffix
? `${activeDomain.canonicalHref}/${suffix}`
: activeDomain.canonicalHref;
const match = matchHousekeepingRoute(registry, canonicalPath);
if (!match || match.domain !== activeDomain.id) notFound();
const route = activeDomain.routes.find((entry) => entry.id === match.routeId);
const handler = HOUSEKEEPING_ROUTE_HANDLERS.find(
(entry) => entry.routeId === match.routeId,
);
if (!route || !handler) notFound();
const context = await getHousekeepingCapabilityContext();
if (
!satisfiesCapability(context, activeDomain.capability) ||
!satisfiesCapability(context, route.capability)
) {
notFound();
}
return handler.render({ context, match });
}
+1 -1
View File
@@ -18,7 +18,7 @@ function namespaceKey(key: string): string {
return key.slice(MESSAGE_PREFIX.length);
}
export default async function AdminNextDomainLayout({
export default async function HousekeepingPreviewDomainLayout({
children,
params,
}: {
-45
View File
@@ -1,45 +0,0 @@
import { notFound } from "next/navigation";
import { getTranslations } from "next-intl/server";
import { HousekeepingPageShell } from "@/features/housekeeping/foundation/page/housekeeping-page-shell";
import { HousekeepingPageState } from "@/features/housekeeping/foundation/page/housekeeping-page-state";
import { createHousekeepingRegistry } from "@/features/housekeeping/foundation/registry";
import { HOUSEKEEPING_MANIFESTS } from "@/features/housekeeping/manifests";
const MESSAGE_PREFIX = "pages.housekeeping.";
function namespaceKey(key: string): string {
if (!key.startsWith(MESSAGE_PREFIX)) {
throw new Error(`invalid housekeeping message key: ${key}`);
}
return key.slice(MESSAGE_PREFIX.length);
}
export default async function AdminNextDomainPage({
params,
}: {
params: Promise<{ domain: string }>;
}) {
const { domain } = await params;
const registry = createHousekeepingRegistry(HOUSEKEEPING_MANIFESTS);
const activeDomain = registry.domains.find((entry) => entry.id === domain);
if (!activeDomain) notFound();
const translate = await getTranslations("pages.housekeeping");
return (
<HousekeepingPageShell
title={translate(namespaceKey(activeDomain.labelKey) as never)}
description={translate(
namespaceKey(activeDomain.descriptionKey) as never,
)}
>
<HousekeepingPageState
state="empty"
title={translate("states.empty.title")}
description={translate("states.empty.description")}
/>
</HousekeepingPageShell>
);
}