@rippling/rippling-sdk 0.2.0-alpha.84 → 0.2.0-alpha.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/examples/manifest/custom-object-creation-workflow/custom-object-creation-workflow.ts +44 -26
  2. package/examples/manifest/dental-practice-management/dental-practice-management.ts +470 -142
  3. package/examples/manifest/dental-practice-management/functions/chair-schedule.ts +23 -13
  4. package/examples/manifest/dental-practice-management/functions/complete-visit.ts +55 -32
  5. package/examples/manifest/dental-practice-management/functions/operatory-list.ts +23 -13
  6. package/examples/manifest/dental-practice-management/functions/patient-list.ts +23 -13
  7. package/examples/manifest/dental-practice-management/functions/treatment-plan-list.ts +23 -13
  8. package/examples/manifest/existing-manifest-mutations/existing-manifest-mutations.ts +23 -68
  9. package/examples/manifest/field-service-dispatch/field-service-dispatch.ts +375 -102
  10. package/examples/manifest/grant-program-management/grant-program-management.ts +419 -125
  11. package/examples/manifest/gym-membership-management/functions/check-in-desk.ts +23 -13
  12. package/examples/manifest/gym-membership-management/functions/member-list.ts +23 -13
  13. package/examples/manifest/gym-membership-management/functions/today-schedule.ts +23 -13
  14. package/examples/manifest/gym-membership-management/functions/trainer-list.ts +23 -13
  15. package/examples/manifest/gym-membership-management/gym-membership-management.ts +442 -92
  16. package/examples/manifest/procurement-approval-hub/procurement-approval-hub.ts +408 -122
  17. package/examples/manifest/simple-todo-app/functions/mark-done.ts +12 -16
  18. package/examples/manifest/simple-todo-app/functions/todo-list.ts +23 -13
  19. package/examples/manifest/simple-todo-app/simple-todo-app.ts +109 -40
  20. package/examples/manifest/todo-app-without-object-list-view/functions/todo-page.ts +193 -166
  21. package/examples/manifest/todo-app-without-object-list-view/todo-app-without-object-list-view.ts +47 -24
  22. package/package.json +13 -7
  23. package/resources/custom-objects/fields.d.mts +1 -40
  24. package/resources/custom-objects/fields.d.mts.map +1 -1
  25. package/resources/custom-objects/fields.d.ts +1 -40
  26. package/resources/custom-objects/fields.d.ts.map +1 -1
  27. package/resources/levels.d.mts +25 -4
  28. package/resources/levels.d.mts.map +1 -1
  29. package/resources/levels.d.ts +25 -4
  30. package/resources/levels.d.ts.map +1 -1
  31. package/src/resources/custom-objects/fields.ts +1 -46
  32. package/src/resources/levels.ts +28 -4
  33. package/src/tsconfig.json +1 -1
  34. package/src/version.ts +1 -1
  35. package/version.d.mts +1 -1
  36. package/version.d.ts +1 -1
  37. package/version.js +1 -1
  38. package/version.mjs +1 -1
  39. package/core/platform/manifest/custom-objects/action.d.mts +0 -58
  40. package/core/platform/manifest/custom-objects/action.d.mts.map +0 -1
  41. package/core/platform/manifest/custom-objects/action.d.ts +0 -58
  42. package/core/platform/manifest/custom-objects/action.d.ts.map +0 -1
  43. package/core/platform/manifest/custom-objects/action.js +0 -44
  44. package/core/platform/manifest/custom-objects/action.js.map +0 -1
  45. package/core/platform/manifest/custom-objects/action.mjs +0 -40
  46. package/core/platform/manifest/custom-objects/action.mjs.map +0 -1
  47. package/core/platform/manifest/custom-objects/conditions.d.mts +0 -240
  48. package/core/platform/manifest/custom-objects/conditions.d.mts.map +0 -1
  49. package/core/platform/manifest/custom-objects/conditions.d.ts +0 -240
  50. package/core/platform/manifest/custom-objects/conditions.d.ts.map +0 -1
  51. package/core/platform/manifest/custom-objects/conditions.js +0 -326
  52. package/core/platform/manifest/custom-objects/conditions.js.map +0 -1
  53. package/core/platform/manifest/custom-objects/conditions.mjs +0 -321
  54. package/core/platform/manifest/custom-objects/conditions.mjs.map +0 -1
  55. package/core/platform/manifest/custom-objects/existing.d.mts +0 -87
  56. package/core/platform/manifest/custom-objects/existing.d.mts.map +0 -1
  57. package/core/platform/manifest/custom-objects/existing.d.ts +0 -87
  58. package/core/platform/manifest/custom-objects/existing.d.ts.map +0 -1
  59. package/core/platform/manifest/custom-objects/existing.js +0 -113
  60. package/core/platform/manifest/custom-objects/existing.js.map +0 -1
  61. package/core/platform/manifest/custom-objects/existing.mjs +0 -109
  62. package/core/platform/manifest/custom-objects/existing.mjs.map +0 -1
  63. package/core/platform/manifest/custom-objects/field-resolution.d.mts +0 -48
  64. package/core/platform/manifest/custom-objects/field-resolution.d.mts.map +0 -1
  65. package/core/platform/manifest/custom-objects/field-resolution.d.ts +0 -48
  66. package/core/platform/manifest/custom-objects/field-resolution.d.ts.map +0 -1
  67. package/core/platform/manifest/custom-objects/field-resolution.js +0 -61
  68. package/core/platform/manifest/custom-objects/field-resolution.js.map +0 -1
  69. package/core/platform/manifest/custom-objects/field-resolution.mjs +0 -58
  70. package/core/platform/manifest/custom-objects/field-resolution.mjs.map +0 -1
  71. package/core/platform/manifest/custom-objects/function-file.d.mts +0 -87
  72. package/core/platform/manifest/custom-objects/function-file.d.mts.map +0 -1
  73. package/core/platform/manifest/custom-objects/function-file.d.ts +0 -87
  74. package/core/platform/manifest/custom-objects/function-file.d.ts.map +0 -1
  75. package/core/platform/manifest/custom-objects/function-file.js +0 -76
  76. package/core/platform/manifest/custom-objects/function-file.js.map +0 -1
  77. package/core/platform/manifest/custom-objects/function-file.mjs +0 -69
  78. package/core/platform/manifest/custom-objects/function-file.mjs.map +0 -1
  79. package/core/platform/manifest/custom-objects/list-view.d.mts +0 -65
  80. package/core/platform/manifest/custom-objects/list-view.d.mts.map +0 -1
  81. package/core/platform/manifest/custom-objects/list-view.d.ts +0 -65
  82. package/core/platform/manifest/custom-objects/list-view.d.ts.map +0 -1
  83. package/core/platform/manifest/custom-objects/list-view.js +0 -33
  84. package/core/platform/manifest/custom-objects/list-view.js.map +0 -1
  85. package/core/platform/manifest/custom-objects/list-view.mjs +0 -30
  86. package/core/platform/manifest/custom-objects/list-view.mjs.map +0 -1
  87. package/core/platform/manifest/custom-objects/object-list-page.d.mts +0 -43
  88. package/core/platform/manifest/custom-objects/object-list-page.d.mts.map +0 -1
  89. package/core/platform/manifest/custom-objects/object-list-page.d.ts +0 -43
  90. package/core/platform/manifest/custom-objects/object-list-page.d.ts.map +0 -1
  91. package/core/platform/manifest/custom-objects/object-list-page.js +0 -54
  92. package/core/platform/manifest/custom-objects/object-list-page.js.map +0 -1
  93. package/core/platform/manifest/custom-objects/object-list-page.mjs +0 -50
  94. package/core/platform/manifest/custom-objects/object-list-page.mjs.map +0 -1
  95. package/core/platform/manifest/custom-objects/page-layout.d.mts +0 -142
  96. package/core/platform/manifest/custom-objects/page-layout.d.mts.map +0 -1
  97. package/core/platform/manifest/custom-objects/page-layout.d.ts +0 -142
  98. package/core/platform/manifest/custom-objects/page-layout.d.ts.map +0 -1
  99. package/core/platform/manifest/custom-objects/page-layout.js +0 -184
  100. package/core/platform/manifest/custom-objects/page-layout.js.map +0 -1
  101. package/core/platform/manifest/custom-objects/page-layout.mjs +0 -180
  102. package/core/platform/manifest/custom-objects/page-layout.mjs.map +0 -1
  103. package/core/platform/manifest/custom-objects/register.d.mts +0 -87
  104. package/core/platform/manifest/custom-objects/register.d.mts.map +0 -1
  105. package/core/platform/manifest/custom-objects/register.d.ts +0 -87
  106. package/core/platform/manifest/custom-objects/register.d.ts.map +0 -1
  107. package/core/platform/manifest/custom-objects/register.js +0 -395
  108. package/core/platform/manifest/custom-objects/register.js.map +0 -1
  109. package/core/platform/manifest/custom-objects/register.mjs +0 -391
  110. package/core/platform/manifest/custom-objects/register.mjs.map +0 -1
  111. package/core/platform/manifest/custom-objects/rule.d.mts +0 -113
  112. package/core/platform/manifest/custom-objects/rule.d.mts.map +0 -1
  113. package/core/platform/manifest/custom-objects/rule.d.ts +0 -113
  114. package/core/platform/manifest/custom-objects/rule.d.ts.map +0 -1
  115. package/core/platform/manifest/custom-objects/rule.js +0 -49
  116. package/core/platform/manifest/custom-objects/rule.js.map +0 -1
  117. package/core/platform/manifest/custom-objects/rule.mjs +0 -45
  118. package/core/platform/manifest/custom-objects/rule.mjs.map +0 -1
  119. package/core/platform/manifest/custom-objects/sdui-page.d.mts +0 -214
  120. package/core/platform/manifest/custom-objects/sdui-page.d.mts.map +0 -1
  121. package/core/platform/manifest/custom-objects/sdui-page.d.ts +0 -214
  122. package/core/platform/manifest/custom-objects/sdui-page.d.ts.map +0 -1
  123. package/core/platform/manifest/custom-objects/sdui-page.js +0 -194
  124. package/core/platform/manifest/custom-objects/sdui-page.js.map +0 -1
  125. package/core/platform/manifest/custom-objects/sdui-page.mjs +0 -182
  126. package/core/platform/manifest/custom-objects/sdui-page.mjs.map +0 -1
  127. package/core/platform/manifest/custom-objects/typed-condition.d.mts +0 -28
  128. package/core/platform/manifest/custom-objects/typed-condition.d.mts.map +0 -1
  129. package/core/platform/manifest/custom-objects/typed-condition.d.ts +0 -28
  130. package/core/platform/manifest/custom-objects/typed-condition.d.ts.map +0 -1
  131. package/core/platform/manifest/custom-objects/typed-condition.js +0 -434
  132. package/core/platform/manifest/custom-objects/typed-condition.js.map +0 -1
  133. package/core/platform/manifest/custom-objects/typed-condition.mjs +0 -431
  134. package/core/platform/manifest/custom-objects/typed-condition.mjs.map +0 -1
  135. package/core/platform/manifest/custom-objects/types.d.mts +0 -29
  136. package/core/platform/manifest/custom-objects/types.d.mts.map +0 -1
  137. package/core/platform/manifest/custom-objects/types.d.ts +0 -29
  138. package/core/platform/manifest/custom-objects/types.d.ts.map +0 -1
  139. package/core/platform/manifest/custom-objects/types.js +0 -3
  140. package/core/platform/manifest/custom-objects/types.js.map +0 -1
  141. package/core/platform/manifest/custom-objects/types.mjs +0 -2
  142. package/core/platform/manifest/custom-objects/types.mjs.map +0 -1
  143. package/core/platform/manifest/custom-objects/validation.d.mts +0 -44
  144. package/core/platform/manifest/custom-objects/validation.d.mts.map +0 -1
  145. package/core/platform/manifest/custom-objects/validation.d.ts +0 -44
  146. package/core/platform/manifest/custom-objects/validation.d.ts.map +0 -1
  147. package/core/platform/manifest/custom-objects/validation.js +0 -30
  148. package/core/platform/manifest/custom-objects/validation.js.map +0 -1
  149. package/core/platform/manifest/custom-objects/validation.mjs +0 -27
  150. package/core/platform/manifest/custom-objects/validation.mjs.map +0 -1
  151. package/core/platform/manifest/custom-objects/workflow.d.mts +0 -47
  152. package/core/platform/manifest/custom-objects/workflow.d.mts.map +0 -1
  153. package/core/platform/manifest/custom-objects/workflow.d.ts +0 -47
  154. package/core/platform/manifest/custom-objects/workflow.d.ts.map +0 -1
  155. package/core/platform/manifest/custom-objects/workflow.js +0 -38
  156. package/core/platform/manifest/custom-objects/workflow.js.map +0 -1
  157. package/core/platform/manifest/custom-objects/workflow.mjs +0 -34
  158. package/core/platform/manifest/custom-objects/workflow.mjs.map +0 -1
  159. package/core/platform/manifest/custom-objects.d.mts +0 -85
  160. package/core/platform/manifest/custom-objects.d.mts.map +0 -1
  161. package/core/platform/manifest/custom-objects.d.ts +0 -85
  162. package/core/platform/manifest/custom-objects.d.ts.map +0 -1
  163. package/core/platform/manifest/custom-objects.js +0 -84
  164. package/core/platform/manifest/custom-objects.js.map +0 -1
  165. package/core/platform/manifest/custom-objects.mjs +0 -55
  166. package/core/platform/manifest/custom-objects.mjs.map +0 -1
  167. package/examples/manifest/custom-object-creation-workflow/functions/intake-request-created.ts +0 -20
  168. package/examples/manifest/custom-object-creation-workflow/schema.ts +0 -29
  169. package/examples/manifest/dental-practice-management/schema.ts +0 -298
  170. package/examples/manifest/field-service-dispatch/schema.ts +0 -248
  171. package/examples/manifest/grant-program-management/schema.ts +0 -269
  172. package/examples/manifest/gym-membership-management/schema.ts +0 -266
  173. package/examples/manifest/procurement-approval-hub/functions/route-purchase-request.ts +0 -20
  174. package/examples/manifest/procurement-approval-hub/schema.ts +0 -256
  175. package/examples/manifest/simple-todo-app/schema.ts +0 -60
  176. package/examples/manifest/todo-app-without-object-list-view/schema.ts +0 -28
  177. package/src/core/platform/README.md +0 -20
  178. package/src/core/platform/manifest/README.md +0 -26
  179. package/src/core/platform/manifest/custom-objects/action.ts +0 -87
  180. package/src/core/platform/manifest/custom-objects/conditions.ts +0 -762
  181. package/src/core/platform/manifest/custom-objects/existing.ts +0 -221
  182. package/src/core/platform/manifest/custom-objects/field-resolution.ts +0 -116
  183. package/src/core/platform/manifest/custom-objects/function-file.ts +0 -149
  184. package/src/core/platform/manifest/custom-objects/list-view.ts +0 -95
  185. package/src/core/platform/manifest/custom-objects/object-list-page.ts +0 -87
  186. package/src/core/platform/manifest/custom-objects/page-layout.ts +0 -380
  187. package/src/core/platform/manifest/custom-objects/register.ts +0 -555
  188. package/src/core/platform/manifest/custom-objects/rule.ts +0 -192
  189. package/src/core/platform/manifest/custom-objects/sdui-page.ts +0 -515
  190. package/src/core/platform/manifest/custom-objects/typed-condition.ts +0 -617
  191. package/src/core/platform/manifest/custom-objects/types.ts +0 -92
  192. package/src/core/platform/manifest/custom-objects/validation.ts +0 -70
  193. package/src/core/platform/manifest/custom-objects/workflow.ts +0 -71
  194. package/src/core/platform/manifest/custom-objects.ts +0 -203
  195. package/src/pebble-sdui-web-custom-apps-shim.d.ts +0 -3
@@ -1,6 +1,5 @@
1
1
  /*
2
- * Procurement Approval Hub - vendors, contracts, purchase requests, approvals,
3
- * and invoices.
2
+ * Procurement Approval Hub - vendors, contracts, purchase requests, approvals, and invoices.
4
3
  *
5
4
  * pa_vendor__c <- vendor profile and risk tier
6
5
  * pa_contract__c <- vendor agreement and spend ceiling
@@ -13,25 +12,28 @@
13
12
  * > examples/manifest/procurement-approval-hub/manifest.json
14
13
  */
15
14
 
16
- import { toCustomCategoryApiName } from '@rippling/rippling-sdk/core/platform/custom-objects';
17
15
  import {
18
- customObjectLifecycle,
19
- defineBasicTypedPageLayout,
20
- defineTypedListView,
21
- defineTypedRule,
22
- defineTypedValidation,
23
- defineTypedWorkflowFromFunctionFile,
24
- registerManifestCustomObjects,
25
- } from '@rippling/rippling-sdk/core/platform/manifest/custom-objects';
26
- import { Category, ManifestBuilder, SummaryField } from '@rippling/rippling-sdk/lib/manifest';
27
- import {
28
- approvalDefinition,
29
- contractDefinition,
30
- invoiceDefinition,
31
- PROCUREMENT_CATEGORY,
32
- requestDefinition,
33
- vendorDefinition,
34
- } from './schema';
16
+ Category,
17
+ CustomObject,
18
+ CustomObjectFieldSection,
19
+ CustomObjectPageLayout,
20
+ DateField,
21
+ EmailField,
22
+ FormulaField,
23
+ ListViewDef,
24
+ LongTextField,
25
+ LookupField,
26
+ ManifestBuilder,
27
+ ManifestFunction,
28
+ NumberField,
29
+ ParentChildField,
30
+ Rule,
31
+ RadioField,
32
+ SummaryField,
33
+ TextField,
34
+ Validation,
35
+ Workflow,
36
+ } from '@rippling/rippling-sdk/lib/manifest';
35
37
 
36
38
  const manifest = new ManifestBuilder({
37
39
  key: 'procurement_approval_hub',
@@ -40,229 +42,513 @@ const manifest = new ManifestBuilder({
40
42
  });
41
43
 
42
44
  const category = new Category(manifest, {
43
- apiName: toCustomCategoryApiName(PROCUREMENT_CATEGORY),
45
+ apiName: 'procurement__c',
44
46
  name: 'Procurement',
45
47
  description: 'Procurement workflow and vendor governance records',
46
48
  });
47
49
 
48
- const [vendor, contract, request, approval, invoice] = registerManifestCustomObjects(manifest, {
50
+ const vendorObj = new CustomObject(manifest, {
51
+ apiName: 'pa_vendor__c',
52
+ name: 'Vendor',
53
+ pluralLabel: 'Vendors',
54
+ category,
55
+ description: 'Vendor profile, risk tier, and compliance owner',
56
+ });
57
+
58
+ const vendorSection = new CustomObjectFieldSection(vendorObj, {
59
+ name: 'Vendor',
60
+ sectionId: 'sec_pa_vendor',
61
+ });
62
+
63
+ const vendorLegalNameField = new TextField(vendorObj, {
64
+ apiName: 'legal_name__c',
65
+ displayName: 'Legal name',
66
+ description: 'Registered legal vendor name',
67
+ required: true,
68
+ maxLength: 200,
69
+ section: vendorSection,
70
+ });
71
+
72
+ const vendorCategoryField = new RadioField(vendorObj, {
73
+ apiName: 'vendor_category__c',
74
+ displayName: 'Vendor category',
75
+ description: 'Primary spend category',
76
+ options: ['Software', 'Facilities', 'Professional services', 'Marketing', 'Hardware', 'Other'],
77
+ required: true,
78
+ section: vendorSection,
79
+ });
80
+
81
+ const vendorRiskField = new RadioField(vendorObj, {
82
+ apiName: 'risk_tier__c',
83
+ displayName: 'Risk tier',
84
+ description: 'Risk tier from diligence review',
85
+ options: ['Low', 'Medium', 'High', 'Critical'],
86
+ required: true,
87
+ section: vendorSection,
88
+ });
89
+
90
+ const vendorContactEmailField = new EmailField(vendorObj, {
91
+ apiName: 'contact_email__c',
92
+ displayName: 'Contact email',
93
+ description: 'Primary vendor contact email',
94
+ section: vendorSection,
95
+ });
96
+
97
+ const contractObj = new CustomObject(manifest, {
98
+ apiName: 'pa_contract__c',
99
+ name: 'Contract',
100
+ pluralLabel: 'Contracts',
101
+ category,
102
+ description: 'Vendor contract with dates, status, and spend ceiling',
103
+ });
104
+
105
+ const contractSection = new CustomObjectFieldSection(contractObj, {
106
+ name: 'Contract',
107
+ sectionId: 'sec_pa_contract',
108
+ });
109
+
110
+ const contractVendorRef = new ParentChildField(contractObj, {
111
+ apiName: 'vendor_ref__c',
112
+ displayName: 'Vendor',
113
+ target: vendorObj,
114
+ relatedDataLabel: 'Contracts',
115
+ parentChildType: 'PRIMARY',
116
+ enableParentOwnerInheritance: false,
117
+ description: 'Vendor this contract belongs to',
118
+ section: contractSection,
119
+ });
120
+
121
+ const contractStatusField = new RadioField(contractObj, {
122
+ apiName: 'status__c',
123
+ displayName: 'Status',
124
+ description: 'Contract lifecycle status',
125
+ options: ['Draft', 'In review', 'Active', 'Expired', 'Terminated'],
126
+ required: true,
127
+ section: contractSection,
128
+ });
129
+
130
+ const contractStartDateField = new DateField(contractObj, {
131
+ apiName: 'start_date__c',
132
+ displayName: 'Start date',
133
+ description: 'Contract effective date',
134
+ section: contractSection,
135
+ });
136
+
137
+ const contractEndDateField = new DateField(contractObj, {
138
+ apiName: 'end_date__c',
139
+ displayName: 'End date',
140
+ description: 'Contract expiration date',
141
+ section: contractSection,
142
+ });
143
+
144
+ const contractCeilingCentsField = new NumberField(contractObj, {
145
+ apiName: 'spend_ceiling_cents__c',
146
+ displayName: 'Spend ceiling (cents)',
147
+ description: 'Approved maximum spend in cents',
148
+ decimalPlaces: 0,
149
+ section: contractSection,
150
+ });
151
+
152
+ const contractTermsField = new LongTextField(contractObj, {
153
+ apiName: 'key_terms__c',
154
+ displayName: 'Key terms',
155
+ description: 'Renewal, data processing, and termination notes',
156
+ maxLength: 6000,
157
+ section: contractSection,
158
+ });
159
+
160
+ const requestObj = new CustomObject(manifest, {
161
+ apiName: 'pa_purchase_request__c',
162
+ name: 'Purchase request',
163
+ pluralLabel: 'Purchase requests',
49
164
  category,
50
- definitions: [
51
- vendorDefinition,
52
- contractDefinition,
53
- requestDefinition,
54
- approvalDefinition,
55
- invoiceDefinition,
56
- ] as const,
165
+ description: 'Purchase request with business justification and approval state',
57
166
  });
58
167
 
59
- const contractCountOnVendor = new SummaryField(vendor.object, {
168
+ const requestSection = new CustomObjectFieldSection(requestObj, {
169
+ name: 'Purchase request',
170
+ sectionId: 'sec_pa_request',
171
+ });
172
+
173
+ const requestVendorRef = new LookupField(requestObj, {
174
+ apiName: 'vendor_ref__c',
175
+ displayName: 'Vendor',
176
+ target: vendorObj,
177
+ relatedDataLabel: 'Purchase requests',
178
+ description: 'Preferred or selected vendor',
179
+ required: true,
180
+ section: requestSection,
181
+ });
182
+
183
+ const requestContractRef = new LookupField(requestObj, {
184
+ apiName: 'contract_ref__c',
185
+ displayName: 'Contract',
186
+ target: contractObj,
187
+ relatedDataLabel: 'Purchase requests',
188
+ description: 'Contract used for this request, if any',
189
+ section: requestSection,
190
+ });
191
+
192
+ const requestAmountCentsField = new NumberField(requestObj, {
193
+ apiName: 'amount_cents__c',
194
+ displayName: 'Amount (cents)',
195
+ description: 'Requested spend amount in cents',
196
+ decimalPlaces: 0,
197
+ required: true,
198
+ section: requestSection,
199
+ });
200
+
201
+ const requestStatusField = new RadioField(requestObj, {
202
+ apiName: 'status__c',
203
+ displayName: 'Status',
204
+ description: 'Approval status',
205
+ options: ['Draft', 'Submitted', 'In approval', 'Approved', 'Rejected', 'Ordered'],
206
+ required: true,
207
+ section: requestSection,
208
+ });
209
+
210
+ const requestNeedByField = new DateField(requestObj, {
211
+ apiName: 'need_by__c',
212
+ displayName: 'Need by',
213
+ description: 'Requested delivery or purchase date',
214
+ section: requestSection,
215
+ });
216
+
217
+ const requestJustificationField = new LongTextField(requestObj, {
218
+ apiName: 'business_justification__c',
219
+ displayName: 'Business justification',
220
+ description: 'Why the purchase is needed',
221
+ maxLength: 6000,
222
+ section: requestSection,
223
+ });
224
+
225
+ const approvalObj = new CustomObject(manifest, {
226
+ apiName: 'pa_approval_step__c',
227
+ name: 'Approval step',
228
+ pluralLabel: 'Approval steps',
229
+ category,
230
+ description: 'Approval routing line tied to a purchase request',
231
+ });
232
+
233
+ const approvalSection = new CustomObjectFieldSection(approvalObj, {
234
+ name: 'Approval step',
235
+ sectionId: 'sec_pa_approval',
236
+ });
237
+
238
+ const approvalRequestRef = new ParentChildField(approvalObj, {
239
+ apiName: 'purchase_request_ref__c',
240
+ displayName: 'Purchase request',
241
+ target: requestObj,
242
+ relatedDataLabel: 'Approval steps',
243
+ parentChildType: 'PRIMARY',
244
+ enableParentOwnerInheritance: true,
245
+ description: 'Purchase request this approval belongs to',
246
+ section: approvalSection,
247
+ });
248
+
249
+ const approvalSequenceField = new NumberField(approvalObj, {
250
+ apiName: 'sequence__c',
251
+ displayName: 'Sequence',
252
+ description: 'Approval sequence number',
253
+ decimalPlaces: 0,
254
+ required: true,
255
+ section: approvalSection,
256
+ });
257
+
258
+ const approvalRoleField = new RadioField(approvalObj, {
259
+ apiName: 'approval_role__c',
260
+ displayName: 'Approval role',
261
+ description: 'Approval lane',
262
+ options: ['Budget owner', 'Finance', 'Security', 'Legal', 'Procurement'],
263
+ required: true,
264
+ section: approvalSection,
265
+ });
266
+
267
+ const approvalStatusField = new RadioField(approvalObj, {
268
+ apiName: 'status__c',
269
+ displayName: 'Status',
270
+ description: 'Approval step status',
271
+ options: ['Pending', 'Approved', 'Rejected', 'Skipped'],
272
+ required: true,
273
+ section: approvalSection,
274
+ });
275
+
276
+ const invoiceObj = new CustomObject(manifest, {
277
+ apiName: 'pa_invoice__c',
278
+ name: 'Invoice',
279
+ pluralLabel: 'Invoices',
280
+ category,
281
+ description: 'Invoice received against a vendor contract',
282
+ });
283
+
284
+ const invoiceSection = new CustomObjectFieldSection(invoiceObj, {
285
+ name: 'Invoice',
286
+ sectionId: 'sec_pa_invoice',
287
+ });
288
+
289
+ const invoiceContractRef = new ParentChildField(invoiceObj, {
290
+ apiName: 'contract_ref__c',
291
+ displayName: 'Contract',
292
+ target: contractObj,
293
+ relatedDataLabel: 'Invoices',
294
+ parentChildType: 'PRIMARY',
295
+ enableParentOwnerInheritance: false,
296
+ description: 'Contract this invoice is billed against',
297
+ section: invoiceSection,
298
+ });
299
+
300
+ const invoiceNumberField = new TextField(invoiceObj, {
301
+ apiName: 'invoice_number__c',
302
+ displayName: 'Invoice number',
303
+ description: 'Vendor invoice number',
304
+ maxLength: 120,
305
+ required: true,
306
+ section: invoiceSection,
307
+ });
308
+
309
+ const invoiceAmountCentsField = new NumberField(invoiceObj, {
310
+ apiName: 'amount_cents__c',
311
+ displayName: 'Amount (cents)',
312
+ description: 'Invoice amount in cents',
313
+ decimalPlaces: 0,
314
+ required: true,
315
+ section: invoiceSection,
316
+ });
317
+
318
+ const invoiceStatusField = new RadioField(invoiceObj, {
319
+ apiName: 'status__c',
320
+ displayName: 'Status',
321
+ description: 'Invoice processing status',
322
+ options: ['Received', 'Matched', 'Approved', 'Paid', 'Exception'],
323
+ required: true,
324
+ section: invoiceSection,
325
+ });
326
+
327
+ const contractCountOnVendor = new SummaryField(vendorObj, {
60
328
  apiName: 'contract_count__c',
61
329
  displayName: 'Contracts',
62
- aggregates: contract.fields.status,
330
+ aggregates: contractStatusField,
63
331
  using: 'COUNT',
64
- lookup: contract.fields.vendor_ref,
332
+ lookup: contractVendorRef,
65
333
  description: 'Contracts for this vendor',
66
- section: vendor.sections.vendor,
334
+ section: vendorSection,
67
335
  });
68
336
 
69
- const approvalCountOnRequest = new SummaryField(request.object, {
337
+ const approvalCountOnRequest = new SummaryField(requestObj, {
70
338
  apiName: 'approval_step_count__c',
71
339
  displayName: 'Approval steps',
72
- aggregates: approval.fields.approval_role,
340
+ aggregates: approvalRoleField,
73
341
  using: 'COUNT',
74
- lookup: approval.fields.purchase_request_ref,
342
+ lookup: approvalRequestRef,
75
343
  description: 'Approval steps attached to this request',
76
- section: request.sections.request,
344
+ section: requestSection,
77
345
  });
78
346
 
79
- const invoicedAmountOnContract = new SummaryField(contract.object, {
347
+ const invoicedAmountOnContract = new SummaryField(contractObj, {
80
348
  apiName: 'invoiced_amount_cents__c',
81
349
  displayName: 'Invoiced amount (cents)',
82
- aggregates: invoice.fields.amount_cents,
350
+ aggregates: invoiceAmountCentsField,
83
351
  using: 'SUM',
84
- lookup: invoice.fields.contract_ref,
352
+ lookup: invoiceContractRef,
85
353
  description: 'Total invoice amount billed against this contract',
86
- section: contract.sections.contract,
354
+ section: contractSection,
355
+ });
356
+
357
+ const requestLabelField = new FormulaField(requestObj, {
358
+ apiName: 'approval_label__c',
359
+ displayName: 'Approval label',
360
+ description: 'Status and amount for approval queues',
361
+ fieldType: 'TEXT',
362
+ maxLength: 240,
363
+ formula: "CONCATENATE(status__c, ' - ', amount_cents__c)",
364
+ section: requestSection,
87
365
  });
88
366
 
89
- // ── Validations & defaults ────────────────────────────────────────────────
90
- defineTypedValidation(contract, {
367
+ new Validation(contractObj, {
91
368
  ruleId: 'pa_contract_end_after_start',
92
369
  displayName: 'Contract end must be after start',
93
- whenInvalid: (c) => c.where('end_date').lte(c.fields.start_date),
370
+ rqlFormula: '(end_date__c <= start_date__c)',
94
371
  errorMessage: 'Contract end date must be after start date.',
95
372
  ruleDescription: 'Prevents inverted contract terms',
96
373
  state: 'ACTIVE',
97
374
  level: 'FIELD',
98
- field: 'end_date',
375
+ fieldRef: contractEndDateField,
99
376
  });
100
377
 
101
- defineTypedValidation(request, {
378
+ new Validation(requestObj, {
102
379
  ruleId: 'pa_request_amount_positive',
103
380
  displayName: 'Request amount must be positive',
104
- whenInvalid: (c) => c.where('amount_cents').lte(0),
381
+ rqlFormula: '(amount_cents__c <= 0)',
105
382
  errorMessage: 'Amount must be greater than zero.',
106
383
  ruleDescription: 'Blocks zero-value purchase requests',
107
384
  state: 'ACTIVE',
108
385
  level: 'FIELD',
109
- field: 'amount_cents',
386
+ fieldRef: requestAmountCentsField,
110
387
  });
111
388
 
112
- defineTypedRule(request, {
389
+ new Rule(requestObj, {
113
390
  flowId: 'pa_default_request_status',
114
391
  flowName: 'Default purchase request status',
115
392
  triggerType: 'CREATE',
116
393
  description: 'New purchase requests start as Draft',
117
- actions: (rules) => [rules.setField('status').toValue('Draft')],
394
+ actions: [{ targetField: requestStatusField, fixedValue: 'Draft' }],
118
395
  });
119
396
 
120
- defineTypedRule(approval, {
397
+ new Rule(approvalObj, {
121
398
  flowId: 'pa_default_approval_status',
122
399
  flowName: 'Default approval step status',
123
400
  triggerType: 'CREATE',
124
401
  description: 'New approval steps start Pending',
125
- actions: (rules) => [rules.setField('status').toValue('Pending')],
402
+ actions: [{ targetField: approvalStatusField, fixedValue: 'Pending' }],
126
403
  });
127
404
 
128
- // ── List views ─────────────────────────────────────────────────────────────
129
- defineTypedListView(vendor, {
405
+ new ListViewDef(vendorObj, {
130
406
  viewId: 'view_pa_vendors',
131
407
  name: 'Vendors',
132
408
  description: 'Vendor directory with risk and contract count',
133
- fields: ['name', 'legal_name', 'vendor_category', 'risk_tier', 'contact_email', contractCountOnVendor],
134
- orderBy: 'legal_name',
409
+ fields: [
410
+ 'name',
411
+ vendorLegalNameField,
412
+ vendorCategoryField,
413
+ vendorRiskField,
414
+ vendorContactEmailField,
415
+ contractCountOnVendor,
416
+ ],
417
+ orderBy: vendorLegalNameField,
135
418
  sortOrder: 'ASC',
136
419
  isPublic: true,
137
420
  objectScope: 'all',
138
421
  });
139
422
 
140
- defineTypedListView(contract, {
423
+ new ListViewDef(contractObj, {
141
424
  viewId: 'view_pa_contracts',
142
425
  name: 'Contracts',
143
426
  description: 'Contract inventory with dates and invoiced amount',
144
427
  fields: [
145
428
  'name',
146
- 'vendor_ref',
147
- 'status',
148
- 'start_date',
149
- 'end_date',
150
- 'spend_ceiling_cents',
429
+ contractVendorRef,
430
+ contractStatusField,
431
+ contractStartDateField,
432
+ contractEndDateField,
433
+ contractCeilingCentsField,
151
434
  invoicedAmountOnContract,
152
435
  ],
153
- orderBy: 'end_date',
436
+ orderBy: contractEndDateField,
154
437
  sortOrder: 'ASC',
155
438
  isPublic: true,
156
439
  objectScope: 'all',
157
440
  });
158
441
 
159
- defineTypedListView(request, {
442
+ new ListViewDef(requestObj, {
160
443
  viewId: 'view_pa_purchase_requests',
161
444
  name: 'Purchase requests',
162
445
  description: 'Approval queue for purchase requests',
163
446
  fields: [
164
447
  'name',
165
- 'vendor_ref',
166
- 'contract_ref',
167
- 'amount_cents',
168
- 'status',
169
- 'need_by',
448
+ requestVendorRef,
449
+ requestContractRef,
450
+ requestAmountCentsField,
451
+ requestStatusField,
452
+ requestNeedByField,
170
453
  approvalCountOnRequest,
171
- 'approval_label',
454
+ requestLabelField,
172
455
  ],
173
- orderBy: 'need_by',
456
+ orderBy: requestNeedByField,
174
457
  sortOrder: 'ASC',
175
458
  isPublic: true,
176
459
  objectScope: 'all',
177
- filter: (c) => c.where('status').in(['Submitted', 'In approval']),
178
460
  });
179
461
 
180
- defineTypedListView(approval, {
462
+ new ListViewDef(approvalObj, {
181
463
  viewId: 'view_pa_approval_steps',
182
464
  name: 'Approval steps',
183
465
  description: 'Approval routing lines by request',
184
- fields: ['name', 'purchase_request_ref', 'sequence', 'approval_role', 'status'],
185
- orderBy: 'sequence',
466
+ fields: ['name', approvalRequestRef, approvalSequenceField, approvalRoleField, approvalStatusField],
467
+ orderBy: approvalSequenceField,
186
468
  sortOrder: 'ASC',
187
469
  isPublic: true,
188
470
  objectScope: 'all',
189
- filter: (c) => c.where('status').eq('Pending'),
190
471
  });
191
472
 
192
- defineTypedListView(invoice, {
473
+ new ListViewDef(invoiceObj, {
193
474
  viewId: 'view_pa_invoices',
194
475
  name: 'Invoices',
195
476
  description: 'Invoices received against contracts',
196
- fields: ['name', 'contract_ref', 'invoice_number', 'amount_cents', 'status'],
197
- orderBy: 'contract_ref',
477
+ fields: ['name', invoiceContractRef, invoiceNumberField, invoiceAmountCentsField, invoiceStatusField],
478
+ orderBy: invoiceContractRef,
198
479
  sortOrder: 'ASC',
199
480
  isPublic: true,
200
481
  objectScope: 'all',
201
482
  });
202
483
 
203
- // ── Page layouts ───────────────────────────────────────────────────────────
204
- defineBasicTypedPageLayout(vendor, {
205
- section: vendor.sections.vendor,
206
- fields: ['name', 'legal_name', 'vendor_category', 'risk_tier', 'contact_email', contractCountOnVendor],
484
+ CustomObjectPageLayout.basic(vendorObj, {
485
+ section: vendorSection,
486
+ fields: [
487
+ 'name',
488
+ vendorLegalNameField,
489
+ vendorCategoryField,
490
+ vendorRiskField,
491
+ vendorContactEmailField,
492
+ contractCountOnVendor,
493
+ ],
207
494
  });
208
495
 
209
- defineBasicTypedPageLayout(contract, {
210
- section: contract.sections.contract,
496
+ CustomObjectPageLayout.basic(contractObj, {
497
+ section: contractSection,
211
498
  fields: [
212
499
  'name',
213
- 'vendor_ref',
214
- 'status',
215
- 'start_date',
216
- 'end_date',
217
- 'spend_ceiling_cents',
500
+ contractVendorRef,
501
+ contractStatusField,
502
+ contractStartDateField,
503
+ contractEndDateField,
504
+ contractCeilingCentsField,
218
505
  invoicedAmountOnContract,
219
- 'key_terms',
506
+ contractTermsField,
220
507
  ],
221
508
  });
222
509
 
223
- defineBasicTypedPageLayout(request, {
224
- section: request.sections.request,
510
+ CustomObjectPageLayout.basic(requestObj, {
511
+ section: requestSection,
225
512
  fields: [
226
513
  'name',
227
- 'vendor_ref',
228
- 'contract_ref',
229
- 'amount_cents',
230
- 'status',
231
- 'need_by',
514
+ requestVendorRef,
515
+ requestContractRef,
516
+ requestAmountCentsField,
517
+ requestStatusField,
518
+ requestNeedByField,
232
519
  approvalCountOnRequest,
233
- 'approval_label',
234
- 'business_justification',
520
+ requestLabelField,
521
+ requestJustificationField,
235
522
  ],
236
523
  });
237
524
 
238
- defineBasicTypedPageLayout(approval, {
239
- section: approval.sections.approval,
240
- fields: ['name', 'purchase_request_ref', 'sequence', 'approval_role', 'status'],
525
+ CustomObjectPageLayout.basic(approvalObj, {
526
+ section: approvalSection,
527
+ fields: ['name', approvalRequestRef, approvalSequenceField, approvalRoleField, approvalStatusField],
241
528
  });
242
529
 
243
- defineBasicTypedPageLayout(invoice, {
244
- section: invoice.sections.invoice,
245
- fields: ['name', 'contract_ref', 'invoice_number', 'amount_cents', 'status'],
530
+ CustomObjectPageLayout.basic(invoiceObj, {
531
+ section: invoiceSection,
532
+ fields: ['name', invoiceContractRef, invoiceNumberField, invoiceAmountCentsField, invoiceStatusField],
246
533
  });
247
534
 
248
- // ── Workflow ───────────────────────────────────────────────────────────────
249
- defineTypedWorkflowFromFunctionFile(manifest, {
250
- function: {
251
- apiName: 'pa_route_purchase_request_fn',
252
- name: 'Route purchase request approvals',
253
- description: 'Function invoked by workflow when a purchase request is submitted',
254
- codeDirectory: __dirname,
255
- codeFilename: 'functions/route-purchase-request.ts',
256
- dependencies: {
257
- '@rippling/rippling-sdk': '^0.2.0-alpha.78',
258
- },
259
- },
535
+ const routeApprovalFunction = new ManifestFunction(manifest, {
536
+ apiName: 'pa_route_purchase_request_fn',
537
+ name: 'Route purchase request approvals',
538
+ description: 'Function invoked by workflow when a purchase request is submitted',
539
+ });
540
+
541
+ new Workflow(manifest, {
260
542
  definitionId: 'pa_purchase_request_submitted_workflow',
261
543
  title: 'Purchase request submitted',
262
- description: 'Routes purchase requests into approval steps when request records are submitted',
263
- trigger: customObjectLifecycle(request)
264
- .onCreateOrUpdate()
265
- .when((c) => c.where('status').eq('Submitted')),
544
+ description: 'Routes purchase requests into approval steps when request records are created',
545
+ function: routeApprovalFunction,
546
+ trigger: {
547
+ automation_event_type: 'AUTOMATION_EVENT_TYPE_RECORD_CHANGE',
548
+ og_module: 'custom_objects',
549
+ base_model: requestObj.getApiName(),
550
+ record_change_operation_type: 'RECORD_CHANGE_OPERATION_TYPE_CREATE',
551
+ },
266
552
  });
267
553
 
268
554
  console.log(manifest.preview());