feat(housekeeping): unify complete rebuild in gated preview
CI / check (pull_request) Failing after 10s
CI / deploy (pull_request) Skipped
CI / release (pull_request) Skipped

This commit is contained in:
Simo committed 2026-08-31 20:37:51 +02:00
1 parent 4ad007d241
commit 43470ebf82
402 files changed
+78313 -1663

No files matched your search

@@ -0,0 +1,211 @@
import { PERMS } from "@/lib/permission-slugs";
import {
anyCapability,
type CanonicalHousekeepingHref,
type HousekeepingRouteDefinition,
} from "../../foundation/contracts";
export const CONTENT_ROUTE_GROUPS = [
"editorial",
"media",
"engagement",
"help",
"brand",
"localization",
] as const;
export type ContentRouteGroup = (typeof CONTENT_ROUTE_GROUPS)[number];
export const CONTENT_ROUTE_IDS = [
"content.editorial.articles",
"content.editorial.article-create",
"content.editorial.article-detail",
"content.media.photos",
"content.media.library",
"content.media.banners",
"content.media.ads",
"content.media.ad-create",
"content.media.ad-detail",
"content.engagement.events",
"content.engagement.event-create",
"content.engagement.event-types",
"content.engagement.event-detail",
"content.engagement.polls",
"content.engagement.poll-create",
"content.engagement.poll-detail",
"content.help.questions",
"content.help.question-create",
"content.help.question-detail",
"content.editorial.tags",
"content.engagement.prefixes",
"content.editorial.writeable-boxes",
"content.help.email-templates",
"content.brand.theme",
"content.brand.theme-builder",
"content.brand.favicon",
"content.localization.overview",
"content.localization.client",
"content.localization.cms",
"content.localization.emulator",
] as const;
export type ContentRouteId = (typeof CONTENT_ROUTE_IDS)[number];
function contentRoute(
id: ContentRouteId,
href: CanonicalHousekeepingHref,
capabilities: readonly string[],
): HousekeepingRouteDefinition {
return {
id,
labelKey: `pages.housekeeping.routes.${id}`,
href,
capability: anyCapability(...capabilities),
};
}
export const CONTENT_ROUTES = [
contentRoute(
"content.editorial.articles",
"/ase-next/content/editorial/articles",
[PERMS.NEWS_VIEW],
),
contentRoute(
"content.editorial.article-create",
"/ase-next/content/editorial/articles/new",
[PERMS.NEWS_EDIT],
),
contentRoute(
"content.editorial.article-detail",
"/ase-next/content/editorial/articles/:id",
[PERMS.NEWS_VIEW],
),
contentRoute("content.media.photos", "/ase-next/content/media/photos", [
PERMS.PAGES_VIEW,
]),
contentRoute("content.media.library", "/ase-next/content/media/library", [
PERMS.PAGES_VIEW,
]),
contentRoute("content.media.banners", "/ase-next/content/media/banners", [
PERMS.BANNERS_VIEW,
]),
contentRoute("content.media.ads", "/ase-next/content/media/ads", [
PERMS.PAGES_VIEW,
]),
contentRoute("content.media.ad-create", "/ase-next/content/media/ads/new", [
PERMS.PAGES_EDIT,
]),
contentRoute("content.media.ad-detail", "/ase-next/content/media/ads/:id", [
PERMS.PAGES_VIEW,
]),
contentRoute("content.engagement.events", "/ase-next/content/engagement/events", [
PERMS.EVENTS_VIEW,
]),
contentRoute(
"content.engagement.event-create",
"/ase-next/content/engagement/events/create",
[PERMS.EVENTS_EDIT],
),
contentRoute(
"content.engagement.event-types",
"/ase-next/content/engagement/events/types",
[PERMS.EVENTS_EDIT],
),
contentRoute(
"content.engagement.event-detail",
"/ase-next/content/engagement/events/:id",
[PERMS.EVENTS_EDIT],
),
contentRoute("content.engagement.polls", "/ase-next/content/engagement/polls", [
PERMS.POLLS_VIEW,
]),
contentRoute(
"content.engagement.poll-create",
"/ase-next/content/engagement/polls/create",
[PERMS.POLLS_EDIT],
),
contentRoute(
"content.engagement.poll-detail",
"/ase-next/content/engagement/polls/:id",
[PERMS.POLLS_EDIT],
),
contentRoute("content.help.questions", "/ase-next/content/help/questions", [
PERMS.PAGES_VIEW,
]),
contentRoute(
"content.help.question-create",
"/ase-next/content/help/questions/new",
[PERMS.PAGES_EDIT],
),
contentRoute(
"content.help.question-detail",
"/ase-next/content/help/questions/:id",
[PERMS.PAGES_VIEW],
),
contentRoute("content.editorial.tags", "/ase-next/content/editorial/tags", [
PERMS.PAGES_VIEW,
]),
contentRoute(
"content.engagement.prefixes",
"/ase-next/content/engagement/prefixes",
[PERMS.PREFIXES_VIEW],
),
contentRoute(
"content.editorial.writeable-boxes",
"/ase-next/content/editorial/writeable-boxes",
[PERMS.PAGES_VIEW],
),
contentRoute(
"content.help.email-templates",
"/ase-next/content/help/email-templates",
[PERMS.PAGES_VIEW],
),
contentRoute("content.brand.theme", "/ase-next/content/brand/theme", [
PERMS.SETTINGS_VIEW,
]),
contentRoute(
"content.brand.theme-builder",
"/ase-next/content/brand/theme-builder",
[PERMS.SETTINGS_VIEW],
),
contentRoute("content.brand.favicon", "/ase-next/content/brand/favicon", [
PERMS.SETTINGS_VIEW,
]),
contentRoute("content.localization.overview", "/ase-next/content/localization", [
PERMS.SETTINGS_VIEW,
]),
contentRoute(
"content.localization.client",
"/ase-next/content/localization/client",
[PERMS.SETTINGS_VIEW],
),
contentRoute("content.localization.cms", "/ase-next/content/localization/cms", [
PERMS.SETTINGS_VIEW,
]),
contentRoute(
"content.localization.emulator",
"/ase-next/content/localization/emulator",
[PERMS.SETTINGS_VIEW],
),
] as const satisfies readonly HousekeepingRouteDefinition[];
const routeGroups = new Map<ContentRouteId, ContentRouteGroup>(
CONTENT_ROUTE_IDS.map((routeId) => [
routeId,
routeId.split(".")[1] as ContentRouteGroup,
]),
);
export function contentRouteGroup(routeId: ContentRouteId): ContentRouteGroup {
const group = routeGroups.get(routeId);
if (!group) throw new Error(`unknown Content route: ${routeId}`);
return group;
}
export function contentRouteById(
routeId: ContentRouteId,
): (typeof CONTENT_ROUTES)[number] {
const route = CONTENT_ROUTES.find((candidate) => candidate.id === routeId);
if (!route) throw new Error(`unknown Content route: ${routeId}`);
return route;
}