import { defaultGqlPermission, defaultPermission } from "@tailor-platform/erp-kit/core"; import { db, type TailorAnyDBType } from "@tailor-platform/sdk"; import { approvalPolicy } from "./approvalPolicy"; import { approvalRequestLifecycle } from "./approvalRequest.lifecycle.generated"; export interface CreateApprovalRequestTypeParams { userType?: TailorAnyDBType; } export function createApprovalRequestType(params: CreateApprovalRequestTypeParams) { const requesterId = db.uuid().description("Foreign key to User who originated the request"); return db .table("ApprovalRequest", { name: db.string().description("Human-readable request label"), purpose: db.string().description("Action-shaped intent (e.g. PRODUCT_ACTIVATION)"), targetEntityType: db .string() .description("Polymorphic target type tag (free string, no FK enforcement)"), targetEntityId: db.uuid().description("Polymorphic target row id (no FK enforcement)"), requesterId: params.userType ? requesterId.relation({ type: "n-1", toward: { type: params.userType, as: "requester" }, backward: "approvalRequestsRequested", }) : requesterId, sourcePolicyId: db .uuid({ optional: true }) .relation({ type: "n-1", toward: { type: approvalPolicy, as: "sourcePolicy" }, backward: "requests", }) .description("Source ApprovalPolicy snapshot reference; null in direct mode"), status: db .enum(approvalRequestLifecycle.states) .description( "Lifecycle status: PENDING, APPROVED, REJECTED, REVISION_REQUESTED, CANCELLED, WITHDRAWN", ), rejectionReason: db .string({ optional: true }) .description("Reason copied from rejecting ApprovalDecision.comment"), resolvedAt: db .datetime({ optional: true }) .description("Set when status reaches any terminal state"), ...db.fields.timestamps(), }) .permission(defaultPermission) .gqlPermission(defaultGqlPermission); } export const approvalRequest = createApprovalRequestType({});