import { defaultGqlPermission, defaultPermission } from "@tailor-platform/erp-kit/core"; import { db, type TailorAnyDBType } from "@tailor-platform/sdk"; import { approvalRequest } from "./approvalRequest"; import { approvalStep } from "./approvalStep"; const APPROVAL_DECISION_TYPES = [ "APPROVE", "REJECT", "SEND_BACK", "DELEGATE", "WITHDRAW", "CANCEL", "RESUBMIT", ] as const; export interface CreateApprovalDecisionTypeParams { userType?: TailorAnyDBType; } export function createApprovalDecisionType(params: CreateApprovalDecisionTypeParams) { const decidedByUserId = db .uuid() .description("Foreign key to User who recorded the decision (set from ctx.actorId)"); const delegatedToUserId = db .uuid({ optional: true }) .description("Delegate user; non-null on DELEGATE rows only"); return db .table("ApprovalDecision", { approvalRequestId: db .uuid() .relation({ type: "n-1", toward: { type: approvalRequest, as: "approvalRequest" }, backward: "decisions", }) .description("Foreign key to parent ApprovalRequest (always required)"), approvalStepId: db .uuid({ optional: true }) .relation({ type: "n-1", toward: { type: approvalStep, as: "approvalStep" }, backward: "decisions", }) .description( "Foreign key to ApprovalStep; set on APPROVE/REJECT/SEND_BACK/DELEGATE, null on WITHDRAW/CANCEL/RESUBMIT", ), sentBackToStepId: db .uuid({ optional: true }) .relation({ type: "n-1", toward: { type: approvalStep, as: "sentBackToStep" }, backward: "sendBacks", }) .description( "Foreign key to the ApprovalStep a step-mode SEND_BACK rewound to; null on requester-mode send-backs and all other decision types", ), decision: db .enum(APPROVAL_DECISION_TYPES) .description( "Decision type: APPROVE, REJECT, SEND_BACK, DELEGATE, WITHDRAW, CANCEL, or RESUBMIT", ), decidedByUserId: params.userType ? decidedByUserId.relation({ type: "n-1", toward: { type: params.userType, as: "decidedByUser" }, backward: "approvalDecisionsDecided", }) : decidedByUserId, delegatedToUserId: params.userType ? delegatedToUserId.relation({ type: "n-1", toward: { type: params.userType, as: "delegatedToUser" }, backward: "approvalDecisionsDelegatedTo", }) : delegatedToUserId, comment: db .string({ optional: true }) .description( "Optional free-text on APPROVE/DELEGATE/WITHDRAW/RESUBMIT; required on REJECT/SEND_BACK/CANCEL as reason", ), decidedAt: db .datetime() .description("Decision timestamp; chronological key for getApprovalDecisionHistory"), ...db.fields.timestamps(), }) .permission(defaultPermission) .gqlPermission(defaultGqlPermission); } export const approvalDecision = createApprovalDecisionType({});