WIP: Unified Housekeeping rebuild / Gecombineerde Housekeeping-herbouw #53
No files matched your search
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -9,7 +9,7 @@ export const contentManifest = {
|
||||
labelKey: "pages.housekeeping.domains.content.title",
|
||||
descriptionKey: "pages.housekeeping.domains.content.description",
|
||||
iconId: "file-text",
|
||||
previewHref: "/admin-next/content",
|
||||
previewHref: "/ase-next/content",
|
||||
capability: anyCapability(
|
||||
PERMS.NEWS_VIEW,
|
||||
PERMS.PAGES_VIEW,
|
||||
|
||||
@@ -9,7 +9,7 @@ export const economyManifest = {
|
||||
labelKey: "pages.housekeeping.domains.economy.title",
|
||||
descriptionKey: "pages.housekeeping.domains.economy.description",
|
||||
iconId: "gem",
|
||||
previewHref: "/admin-next/economy",
|
||||
previewHref: "/ase-next/economy",
|
||||
capability: anyCapability(
|
||||
PERMS.CATALOG_VIEW,
|
||||
PERMS.SHOP_VIEW,
|
||||
|
||||
@@ -9,7 +9,7 @@ export const hotelManifest = {
|
||||
labelKey: "pages.housekeeping.domains.hotel.title",
|
||||
descriptionKey: "pages.housekeeping.domains.hotel.description",
|
||||
iconId: "hotel",
|
||||
previewHref: "/admin-next/hotel",
|
||||
previewHref: "/ase-next/hotel",
|
||||
capability: anyCapability(
|
||||
PERMS.ROOMS_VIEW,
|
||||
PERMS.RADIO_VIEW,
|
||||
|
||||
@@ -9,7 +9,7 @@ export const operationsManifest = {
|
||||
labelKey: "pages.housekeeping.domains.operations.title",
|
||||
descriptionKey: "pages.housekeeping.domains.operations.description",
|
||||
iconId: "inbox",
|
||||
previewHref: "/admin-next/operations",
|
||||
previewHref: "/ase-next/operations",
|
||||
capability: anyCapability(PERMS.ADMIN_DASHBOARD),
|
||||
routes: [],
|
||||
searchProviders: [],
|
||||
|
||||
@@ -9,7 +9,7 @@ export const peopleManifest = {
|
||||
labelKey: "pages.housekeeping.domains.people.title",
|
||||
descriptionKey: "pages.housekeeping.domains.people.description",
|
||||
iconId: "users",
|
||||
previewHref: "/admin-next/people",
|
||||
previewHref: "/ase-next/people",
|
||||
capability: anyCapability(
|
||||
PERMS.USERS_VIEW,
|
||||
PERMS.MODERATION_VIEW,
|
||||
|
||||
@@ -9,7 +9,7 @@ export const systemManifest = {
|
||||
labelKey: "pages.housekeeping.domains.system.title",
|
||||
descriptionKey: "pages.housekeeping.domains.system.description",
|
||||
iconId: "settings",
|
||||
previewHref: "/admin-next/system",
|
||||
previewHref: "/ase-next/system",
|
||||
capability: anyCapability(
|
||||
PERMS.SETTINGS_VIEW,
|
||||
PERMS.LOGS_VIEW,
|
||||
|
||||
@@ -28,7 +28,7 @@ const workItem = {
|
||||
occurredAt: "2026-08-24T12:00:00.000Z",
|
||||
titleKey: "pages.housekeeping.items.ticket",
|
||||
context: { ticketId: "42" },
|
||||
href: "/admin-next/people/tickets/42",
|
||||
href: "/ase-next/people/tickets/42",
|
||||
freshness: "fresh",
|
||||
} satisfies HousekeepingWorkItem;
|
||||
|
||||
@@ -36,7 +36,7 @@ const searchResult = {
|
||||
id: "user-42",
|
||||
domain: "people",
|
||||
title: "operator",
|
||||
href: "/admin-next/people/users/42",
|
||||
href: "/ase-next/people/users/42",
|
||||
} satisfies HousekeepingSearchResult;
|
||||
|
||||
const searchProvider: HousekeepingSearchProvider = {
|
||||
@@ -87,7 +87,7 @@ const manifest: HousekeepingDomainManifest = {
|
||||
labelKey: "pages.housekeeping.domains.people.title",
|
||||
descriptionKey: "pages.housekeeping.domains.people.description",
|
||||
iconId: "users",
|
||||
previewHref: "/admin-next/people",
|
||||
previewHref: "/ase-next/people",
|
||||
capability,
|
||||
routes: [],
|
||||
searchProviders: [searchProvider],
|
||||
|
||||
@@ -17,7 +17,7 @@ export interface HousekeepingDomainManifest {
|
||||
labelKey: string;
|
||||
descriptionKey: string;
|
||||
iconId: "inbox" | "users" | "file-text" | "gem" | "hotel" | "settings";
|
||||
previewHref: `/admin-next/${HousekeepingDomainId}`;
|
||||
previewHref: `/ase-next/${HousekeepingDomainId}`;
|
||||
capability: CapabilityRequirement;
|
||||
routes: readonly HousekeepingRouteDefinition[];
|
||||
searchProviders: readonly HousekeepingSearchProvider[];
|
||||
|
||||
@@ -555,7 +555,7 @@ describe("housekeeping foundation completion contracts", () => {
|
||||
for (const path of [
|
||||
"src/app/admin/layout.tsx",
|
||||
"src/app/mod/layout.tsx",
|
||||
"src/app/admin-next/layout.tsx",
|
||||
"src/app/ase-next/layout.tsx",
|
||||
]) {
|
||||
expect(existsSync(path), path).toBe(true);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ describe("housekeeping navigation", () => {
|
||||
labelKey: "pages.housekeeping.domains.people.title",
|
||||
descriptionKey: "pages.housekeeping.domains.people.description",
|
||||
iconId: "users",
|
||||
previewHref: "/admin-next/people",
|
||||
previewHref: "/ase-next/people",
|
||||
capability: anyCapability(PERMS.MOD_CFH_VIEW),
|
||||
routes: [],
|
||||
searchProviders: [],
|
||||
@@ -35,7 +35,7 @@ describe("housekeeping navigation", () => {
|
||||
labelKey: "pages.housekeeping.domains.economy.title",
|
||||
descriptionKey: "pages.housekeeping.domains.economy.description",
|
||||
iconId: "gem",
|
||||
previewHref: "/admin-next/economy",
|
||||
previewHref: "/ase-next/economy",
|
||||
capability: anyCapability(PERMS.CATALOG_VIEW),
|
||||
routes: [],
|
||||
searchProviders: [],
|
||||
@@ -53,7 +53,7 @@ describe("housekeeping navigation", () => {
|
||||
expect(navigation).toEqual([
|
||||
{
|
||||
id: "people",
|
||||
href: "/admin-next/people",
|
||||
href: "/ase-next/people",
|
||||
iconId: "users",
|
||||
label: "pages.housekeeping.domains.people.title",
|
||||
description: "pages.housekeeping.domains.people.description",
|
||||
@@ -69,19 +69,19 @@ describe("housekeeping navigation", () => {
|
||||
labelKey: "people.title",
|
||||
descriptionKey: "people.description",
|
||||
iconId: "users",
|
||||
previewHref: "/admin-next/people",
|
||||
previewHref: "/ase-next/people",
|
||||
capability: anyCapability(PERMS.USERS_VIEW),
|
||||
routes: [
|
||||
{
|
||||
id: "users",
|
||||
labelKey: "people.users",
|
||||
href: "/admin-next/people/users",
|
||||
href: "/ase-next/people/users",
|
||||
capability: anyCapability(PERMS.USERS_VIEW),
|
||||
},
|
||||
{
|
||||
id: "bans",
|
||||
labelKey: "people.bans",
|
||||
href: "/admin-next/people/bans",
|
||||
href: "/ase-next/people/bans",
|
||||
capability: anyCapability(PERMS.BANS_VIEW),
|
||||
},
|
||||
],
|
||||
@@ -94,7 +94,7 @@ describe("housekeeping navigation", () => {
|
||||
labelKey: "system.title",
|
||||
descriptionKey: "system.description",
|
||||
iconId: "settings",
|
||||
previewHref: "/admin-next/system",
|
||||
previewHref: "/ase-next/system",
|
||||
capability: anyCapability(PERMS.SETTINGS_VIEW),
|
||||
routes: [],
|
||||
searchProviders: [],
|
||||
@@ -113,14 +113,14 @@ describe("housekeeping navigation", () => {
|
||||
expect(navigation).toEqual([
|
||||
{
|
||||
id: "people",
|
||||
href: "/admin-next/people",
|
||||
href: "/ase-next/people",
|
||||
iconId: "users",
|
||||
label: "translated:people.title",
|
||||
description: "translated:people.description",
|
||||
items: [
|
||||
{
|
||||
id: "users",
|
||||
href: "/admin-next/people/users",
|
||||
href: "/ase-next/people/users",
|
||||
label: "translated:people.users",
|
||||
},
|
||||
],
|
||||
|
||||
@@ -75,12 +75,12 @@ describe("HousekeepingPageState", () => {
|
||||
state="error"
|
||||
title="Could not load"
|
||||
description="Try again later"
|
||||
retryAction={<a href="/admin-next/operations">Retry preview</a>}
|
||||
retryAction={<a href="/ase-next/operations">Retry preview</a>}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(html).toContain('role="alert"');
|
||||
expect(html).toContain('href="/admin-next/operations"');
|
||||
expect(html).toContain('href="/ase-next/operations"');
|
||||
expect(html).toContain(">Retry preview<");
|
||||
});
|
||||
});
|
||||
@@ -92,7 +92,7 @@ describe("HousekeepingPageShell", () => {
|
||||
title="People"
|
||||
description="Review operator-facing people data"
|
||||
context={<span>Preview context</span>}
|
||||
primaryAction={<a href="/admin-next/people/new">Create preview</a>}
|
||||
primaryAction={<a href="/ase-next/people/new">Create preview</a>}
|
||||
>
|
||||
<p>Page body</p>
|
||||
</HousekeepingPageShell>,
|
||||
@@ -102,7 +102,7 @@ describe("HousekeepingPageShell", () => {
|
||||
expect(html).toContain(">People<");
|
||||
expect(html).toContain(">Review operator-facing people data<");
|
||||
expect(html).toContain(">Preview context<");
|
||||
expect(html).toContain('href="/admin-next/people/new"');
|
||||
expect(html).toContain('href="/ase-next/people/new"');
|
||||
expect(html).toContain(">Create preview<");
|
||||
expect(html).toContain(">Page body</p>");
|
||||
});
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
describe("Housekeeping preview namespace", () => {
|
||||
it("uses /ase-next and removes the previous runtime namespace", () => {
|
||||
const removedNamespace = ["/admin", "-next"].join("");
|
||||
const files = execFileSync("git", ["ls-files", "src", ".env.example"], {
|
||||
encoding: "utf8",
|
||||
})
|
||||
.trim()
|
||||
.split(/\r?\n/)
|
||||
.filter(Boolean);
|
||||
|
||||
const offenders = files.filter((file) =>
|
||||
readFileSync(file, "utf8").includes(removedNamespace),
|
||||
);
|
||||
|
||||
expect(offenders).toEqual([]);
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -34,7 +34,7 @@ export function createHousekeepingRegistry(
|
||||
}
|
||||
domainIds.add(manifest.id);
|
||||
|
||||
if (manifest.previewHref !== `/admin-next/${manifest.id}`) {
|
||||
if (manifest.previewHref !== `/ase-next/${manifest.id}`) {
|
||||
throw new Error(`invalid preview href: ${manifest.previewHref}`);
|
||||
}
|
||||
validateNonEmpty(manifest.labelKey, "label key");
|
||||
|
||||
@@ -17,17 +17,17 @@ const labels = {
|
||||
const domains: readonly HousekeepingNavigationDomain[] = [
|
||||
{
|
||||
id: "operations",
|
||||
href: "/admin-next/operations",
|
||||
href: "/ase-next/operations",
|
||||
iconId: "inbox",
|
||||
label: "Operations",
|
||||
description: "Manage operations",
|
||||
items: [
|
||||
{ id: "queue", href: "/admin-next/operations/queue", label: "Queue" },
|
||||
{ id: "queue", href: "/ase-next/operations/queue", label: "Queue" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "people",
|
||||
href: "/admin-next/people",
|
||||
href: "/ase-next/people",
|
||||
iconId: "users",
|
||||
label: "People",
|
||||
description: "Manage people",
|
||||
@@ -35,7 +35,7 @@ const domains: readonly HousekeepingNavigationDomain[] = [
|
||||
},
|
||||
{
|
||||
id: "content",
|
||||
href: "/admin-next/content",
|
||||
href: "/ase-next/content",
|
||||
iconId: "file-text",
|
||||
label: "Content",
|
||||
description: "Manage content",
|
||||
@@ -43,7 +43,7 @@ const domains: readonly HousekeepingNavigationDomain[] = [
|
||||
},
|
||||
{
|
||||
id: "economy",
|
||||
href: "/admin-next/economy",
|
||||
href: "/ase-next/economy",
|
||||
iconId: "gem",
|
||||
label: "Economy",
|
||||
description: "Manage economy",
|
||||
@@ -51,7 +51,7 @@ const domains: readonly HousekeepingNavigationDomain[] = [
|
||||
},
|
||||
{
|
||||
id: "hotel",
|
||||
href: "/admin-next/hotel",
|
||||
href: "/ase-next/hotel",
|
||||
iconId: "hotel",
|
||||
label: "Hotel",
|
||||
description: "Manage hotel",
|
||||
@@ -59,7 +59,7 @@ const domains: readonly HousekeepingNavigationDomain[] = [
|
||||
},
|
||||
{
|
||||
id: "system",
|
||||
href: "/admin-next/system",
|
||||
href: "/ase-next/system",
|
||||
iconId: "settings",
|
||||
label: "System",
|
||||
description: "Manage system",
|
||||
@@ -178,7 +178,7 @@ describe("HousekeepingShell", () => {
|
||||
expect(html).toContain('<nav aria-label="Operations navigation"');
|
||||
expect(html).toContain('<main id="housekeeping-content"');
|
||||
expect(html).toContain(">Deck body</p>");
|
||||
expect(html).toContain('href="/admin-next/operations/queue"');
|
||||
expect(html).toContain('href="/ase-next/operations/queue"');
|
||||
expect(html).toContain(">Queue<");
|
||||
expect(html).toContain(">Nora<");
|
||||
expect(html).toContain(">6<");
|
||||
@@ -196,7 +196,7 @@ describe("HousekeepingShell", () => {
|
||||
const activeAnchors = allAnchors.filter((anchor) =>
|
||||
anchor.includes('aria-current="page"'),
|
||||
);
|
||||
const peopleAnchor = anchorForHref(html, "/admin-next/people");
|
||||
const peopleAnchor = anchorForHref(html, "/ase-next/people");
|
||||
for (const iconClass of [
|
||||
"lucide-inbox",
|
||||
"lucide-users",
|
||||
@@ -222,7 +222,7 @@ describe("HousekeepingShell", () => {
|
||||
);
|
||||
expect(() => renderShell("system", domainsWithoutSystem)).not.toThrow();
|
||||
const html = renderShell("system", domainsWithoutSystem);
|
||||
expect(html).not.toContain('href="/admin-next/operations/queue"');
|
||||
expect(html).not.toContain('href="/ase-next/operations/queue"');
|
||||
expect(html).not.toContain(">Queue<");
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { describe, expect, it } from "vitest";
|
||||
const ROOTS = [
|
||||
"src/app/admin",
|
||||
"src/components/admin",
|
||||
"src/app/admin-next",
|
||||
"src/app/ase-next",
|
||||
"src/features/housekeeping",
|
||||
];
|
||||
const GRAPHICAL_ALLOWLIST = [
|
||||
|
||||
Reference in new issue
Block a user