feat(housekeeping): deliver content vertical
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import "server-only";
|
||||
|
||||
import { z } from "zod";
|
||||
import { PERMS } from "@/lib/permission-slugs";
|
||||
import type { HousekeepingCommand } from "../../../foundation/commands/registry";
|
||||
import { anyCapability } from "../../../foundation/contracts";
|
||||
import {
|
||||
type ContentMutationOperation,
|
||||
type ContentMutationService,
|
||||
contentMutationService,
|
||||
} from "../services/mutations";
|
||||
|
||||
const CONTENT_COMMAND_DEFINITIONS = [
|
||||
["content.editorial.article.change", "article.change", PERMS.NEWS_EDIT],
|
||||
["content.media.ad.change", "ad.change", PERMS.PAGES_EDIT],
|
||||
["content.media.banner.change", "banner.change", PERMS.BANNERS_EDIT],
|
||||
["content.engagement.event-type.change", "event-type.change", PERMS.EVENTS_EDIT],
|
||||
["content.engagement.event.change", "event.change", PERMS.EVENTS_EDIT],
|
||||
["content.engagement.event-prize.change", "event-prize.change", PERMS.EVENTS_EDIT],
|
||||
["content.engagement.event-winner.add", "event-winner.add", PERMS.EVENTS_EDIT],
|
||||
["content.engagement.poll.change", "poll.change", PERMS.POLLS_EDIT],
|
||||
["content.engagement.poll-question.change", "poll-question.change", PERMS.POLLS_EDIT],
|
||||
["content.media.photo.delete", "photo.delete", PERMS.PAGES_EDIT],
|
||||
["content.media.asset.upload", "media.upload", PERMS.PAGES_EDIT],
|
||||
["content.media.asset.delete", "media.delete", PERMS.PAGES_EDIT],
|
||||
["content.editorial.navigation.update", "navigation.update", PERMS.SETTINGS_EDIT],
|
||||
["content.editorial.tag.change", "tag.change", PERMS.PAGES_EDIT],
|
||||
["content.engagement.prefix.change", "prefix.change", PERMS.PREFIXES_EDIT],
|
||||
["content.engagement.prefix-blacklist.change", "prefix-blacklist.change", PERMS.PREFIXES_EDIT],
|
||||
["content.engagement.prefix-settings.update", "prefix-settings.update", PERMS.PREFIXES_EDIT],
|
||||
["content.help.question.change", "help-question.change", PERMS.PAGES_EDIT],
|
||||
["content.editorial.writeable-box.change", "writeable-box.change", PERMS.PAGES_EDIT],
|
||||
["content.help.email-template.change", "email-template.change", PERMS.PAGES_EDIT],
|
||||
["content.brand.theme.update", "theme.update", PERMS.SETTINGS_EDIT],
|
||||
["content.brand.theme.apply-preset", "theme.apply-preset", PERMS.SETTINGS_EDIT],
|
||||
["content.brand.theme.custom-change", "theme.custom-change", PERMS.SETTINGS_EDIT],
|
||||
["content.brand.theme.apply-custom", "theme.apply-custom", PERMS.SETTINGS_EDIT],
|
||||
["content.brand.favicon.save", "favicon.save", PERMS.SETTINGS_EDIT],
|
||||
["content.brand.favicon.delete", "favicon.delete", PERMS.SETTINGS_EDIT],
|
||||
["content.brand.logo.save", "logo.save", PERMS.SETTINGS_EDIT],
|
||||
["content.localization.cms.save", "translation.cms.save", PERMS.SETTINGS_EDIT],
|
||||
["content.localization.client.save", "translation.client.save", PERMS.SETTINGS_EDIT],
|
||||
["content.localization.emulator.save", "translation.emulator.save", PERMS.SETTINGS_EDIT],
|
||||
] as const;
|
||||
|
||||
export const CONTENT_COMMAND_IDS = CONTENT_COMMAND_DEFINITIONS.map(
|
||||
([id]) => id,
|
||||
) as ReadonlyArray<(typeof CONTENT_COMMAND_DEFINITIONS)[number][0]>;
|
||||
|
||||
type ContentCommand = HousekeepingCommand<Record<string, unknown>, unknown> & {
|
||||
readonly operation: ContentMutationOperation;
|
||||
};
|
||||
|
||||
const commandInput = z.object({}).catchall(z.unknown());
|
||||
|
||||
export function createContentCommands(
|
||||
service: Pick<ContentMutationService, "execute">,
|
||||
): readonly ContentCommand[] {
|
||||
return CONTENT_COMMAND_DEFINITIONS.map(
|
||||
([id, operation, permission]): ContentCommand => ({
|
||||
id,
|
||||
owner: "content",
|
||||
operation,
|
||||
risk: "sensitive",
|
||||
capability: anyCapability(permission),
|
||||
input: commandInput,
|
||||
requiresReason:
|
||||
id.startsWith("content.brand.") ||
|
||||
id.startsWith("content.localization."),
|
||||
rateLimit: { attempts: 10, windowMs: 60_000 },
|
||||
execute: (context, input) =>
|
||||
service.execute(
|
||||
{
|
||||
correlationId: context.correlationId,
|
||||
expectedActorId: context.capability.actor.id,
|
||||
},
|
||||
operation,
|
||||
input,
|
||||
),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
export const CONTENT_COMMANDS = createContentCommands(contentMutationService);
|
||||
Reference in New Issue
Block a user