sendou.ink/app/features/badges/actions/badges.$id.edit.server.ts
Kalle 9e0f36d90c Refactor requireRole/requirePermission to resolve user internally
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:02:37 +02:00

82 lines
2.0 KiB
TypeScript

import type { ActionFunction } from "react-router";
import { redirect } from "react-router";
import { z } from "zod";
import { notify } from "~/features/notifications/core/notify.server";
import {
requirePermission,
requireRole,
} from "~/modules/permissions/guards.server";
import { diff } from "~/utils/arrays";
import { notFoundIfFalsy, parseRequestPayload } from "~/utils/remix.server";
import { assertUnreachable } from "~/utils/types";
import { badgePage } from "~/utils/urls";
import { actualNumber } from "~/utils/zod";
import * as BadgeRepository from "../BadgeRepository.server";
import { editBadgeActionSchema } from "../badges-schemas.server";
export const action: ActionFunction = async ({ request, params }) => {
const data = await parseRequestPayload({
request,
schema: editBadgeActionSchema,
});
const badgeId = z.preprocess(actualNumber, z.number()).parse(params.id);
const badge = notFoundIfFalsy(await BadgeRepository.findById(badgeId));
switch (data._action) {
case "MANAGERS": {
requireRole("STAFF");
const oldManagers = badge.managers;
await BadgeRepository.replaceManagers({
badgeId,
managerIds: data.managerIds,
});
const newManagers = data.managerIds.filter(
(newManagerId) =>
!oldManagers.some((oldManager) => oldManager.userId === newManagerId),
);
notify({
userIds: newManagers,
notification: {
type: "BADGE_MANAGER_ADDED",
meta: {
badgeId,
badgeName: badge.displayName,
},
},
});
break;
}
case "OWNERS": {
requirePermission(badge, "MANAGE");
const oldOwners: number[] = badge.owners.flatMap((owner) =>
new Array(owner.count).fill(owner.id),
);
await BadgeRepository.replaceOwners({ badgeId, ownerIds: data.ownerIds });
notify({
userIds: diff(oldOwners, data.ownerIds),
notification: {
type: "BADGE_ADDED",
meta: {
badgeName: badge.displayName,
badgeId,
},
},
});
break;
}
default: {
assertUnreachable(data);
}
}
throw redirect(badgePage(badgeId));
};