-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathapproval.zod.ts
More file actions
105 lines (87 loc) · 3.53 KB
/
approval.zod.ts
File metadata and controls
105 lines (87 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import { z } from 'zod';
import { SnakeCaseIdentifierSchema } from '../shared/identifiers.zod';
/**
* Approval Step Approver Type
*/
export const ApproverType = z.enum([
'user', // Specific user(s)
'role', // Users with specific role
'manager', // Submitter's manager
'field', // User ID defined in a record field
'queue' // Data ownership queue
]);
/**
* Approval Action Type
* Actions to execute on transition
*/
export const ApprovalActionType = z.enum([
'field_update',
'email_alert',
'webhook',
'script',
'connector_action' // Added for Zapier-style integrations
]);
/**
* definition of an action to perform
*/
export const ApprovalActionSchema = z.object({
type: ApprovalActionType,
name: z.string().describe('Action name'),
config: z.record(z.string(), z.unknown()).describe('Action configuration'),
/** For connector actions */
connectorId: z.string().optional(),
actionId: z.string().optional(),
});
/**
* Approval Process Step
*/
export const ApprovalStepSchema = z.object({
name: SnakeCaseIdentifierSchema.describe('Step machine name'),
label: z.string().describe('Step display label'),
description: z.string().optional(),
/** Entry criteria for this step */
entryCriteria: z.string().optional().describe('Formula expression to enter this step'),
/** Who can approve */
approvers: z.array(z.object({
type: ApproverType,
value: z.string().describe('User ID, Role Name, or Field Name')
})).min(1).describe('List of allowed approvers'),
/** Approval Logic */
behavior: z.enum(['first_response', 'unanimous']).default('first_response')
.describe('How to handle multiple approvers'),
/** Rejection behavior */
rejectionBehavior: z.enum(['reject_process', 'back_to_previous'])
.default('reject_process').describe('What happens if rejected'),
/** Actions */
onApprove: z.array(ApprovalActionSchema).optional().describe('Actions on step approval'),
onReject: z.array(ApprovalActionSchema).optional().describe('Actions on step rejection'),
});
/**
* Approval Process Protocol
*
* Defines a complex review and approval cycle for a record.
* Manages state locking, notifications, and transition logic.
*/
export const ApprovalProcessSchema = z.object({
name: SnakeCaseIdentifierSchema.describe('Unique process name'),
label: z.string().describe('Human readable label'),
object: z.string().describe('Target Object Name'),
active: z.boolean().default(false),
description: z.string().optional(),
/** Entry Criteria for the entire process */
entryCriteria: z.string().optional().describe('Formula to allow submission'),
/** Record Locking */
lockRecord: z.boolean().default(true).describe('Lock record from editing during approval'),
/** Steps */
steps: z.array(ApprovalStepSchema).min(1).describe('Sequence of approval steps'),
/** Global Actions */
onSubmit: z.array(ApprovalActionSchema).optional().describe('Actions on initial submission'),
onFinalApprove: z.array(ApprovalActionSchema).optional().describe('Actions on final approval'),
onFinalReject: z.array(ApprovalActionSchema).optional().describe('Actions on final rejection'),
onRecall: z.array(ApprovalActionSchema).optional().describe('Actions on recall'),
});
export const ApprovalProcess = Object.assign(ApprovalProcessSchema, {
create: <T extends z.input<typeof ApprovalProcessSchema>>(config: T) => config,
});
export type ApprovalProcess = z.infer<typeof ApprovalProcessSchema>;
export type ApprovalStep = z.infer<typeof ApprovalStepSchema>;