Files
EpicNext-Cms/src/actions/tickets.ts
T

86 lines
2.1 KiB
TypeScript

"use server";
import {
createPeopleMutationInvocation,
peopleMutationService,
} from "@/features/housekeeping/domains/people/services/mutations";
import { createCorrelationId } from "@/features/housekeeping/foundation/contracts";
import { PERMS } from "@/lib/permissions";
import { adminAction } from "@/lib/safe-action";
import { ActionError, actionOk } from "@/lib/safe-action-shared";
import {
assignTicketSchema,
replyTicketSchema,
updateTicketPrioritySchema,
updateTicketStatusSchema,
} from "@/lib/validators/ticket";
async function execute(
staff: { readonly id: number },
operation:
| "ticket.reply"
| "ticket.assign"
| "ticket.status"
| "ticket.priority",
input: unknown,
) {
const result = await peopleMutationService.execute(
createPeopleMutationInvocation(staff, createCorrelationId()),
operation,
input,
);
if (!result.ok) {
throw new ActionError(
result.error.code === "NOT_FOUND"
? "Ticket not found"
: "Ticket update failed",
);
}
}
// ── User actions (authenticated, no admin perms needed) ──────────────
export const adminReplyTicket = adminAction(
{
permission: [PERMS.TICKETS_EDIT, PERMS.MOD_TICKETS_EDIT],
schema: replyTicketSchema,
},
async (ctx) => {
await execute(ctx.session.user, "ticket.reply", ctx.data);
return actionOk();
},
);
export const updateTicketStatus = adminAction(
{
permission: [PERMS.TICKETS_EDIT, PERMS.MOD_TICKETS_EDIT],
schema: updateTicketStatusSchema,
},
async (ctx) => {
await execute(ctx.session.user, "ticket.status", ctx.data);
return actionOk();
},
);
export const assignTicket = adminAction(
{
permission: [PERMS.TICKETS_EDIT, PERMS.MOD_TICKETS_EDIT],
schema: assignTicketSchema,
},
async (ctx) => {
await execute(ctx.session.user, "ticket.assign", ctx.data);
return actionOk();
},
);
export const updateTicketPriority = adminAction(
{
permission: [PERMS.TICKETS_EDIT, PERMS.MOD_TICKETS_EDIT],
schema: updateTicketPrioritySchema,
},
async (ctx) => {
await execute(ctx.session.user, "ticket.priority", ctx.data);
return actionOk();
},
);