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

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 (314) 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/custom-objects.d.mts +0 -7
  24. package/resources/custom-objects/custom-objects.d.mts.map +1 -1
  25. package/resources/custom-objects/custom-objects.d.ts +0 -7
  26. package/resources/custom-objects/custom-objects.d.ts.map +1 -1
  27. package/resources/custom-objects/custom-objects.js.map +1 -1
  28. package/resources/custom-objects/custom-objects.mjs.map +1 -1
  29. package/resources/custom-objects/fields.d.mts +14 -128
  30. package/resources/custom-objects/fields.d.mts.map +1 -1
  31. package/resources/custom-objects/fields.d.ts +14 -128
  32. package/resources/custom-objects/fields.d.ts.map +1 -1
  33. package/src/resources/custom-objects/custom-objects.ts +0 -8
  34. package/src/resources/custom-objects/fields.ts +13 -191
  35. package/src/tsconfig.json +1 -1
  36. package/src/version.ts +1 -1
  37. package/version.d.mts +1 -1
  38. package/version.d.ts +1 -1
  39. package/version.js +1 -1
  40. package/version.mjs +1 -1
  41. package/core/platform/custom-objects/category.d.mts +0 -125
  42. package/core/platform/custom-objects/category.d.mts.map +0 -1
  43. package/core/platform/custom-objects/category.d.ts +0 -125
  44. package/core/platform/custom-objects/category.d.ts.map +0 -1
  45. package/core/platform/custom-objects/category.js +0 -188
  46. package/core/platform/custom-objects/category.js.map +0 -1
  47. package/core/platform/custom-objects/category.mjs +0 -178
  48. package/core/platform/custom-objects/category.mjs.map +0 -1
  49. package/core/platform/custom-objects/definition.d.mts +0 -147
  50. package/core/platform/custom-objects/definition.d.mts.map +0 -1
  51. package/core/platform/custom-objects/definition.d.ts +0 -147
  52. package/core/platform/custom-objects/definition.d.ts.map +0 -1
  53. package/core/platform/custom-objects/definition.js +0 -200
  54. package/core/platform/custom-objects/definition.js.map +0 -1
  55. package/core/platform/custom-objects/definition.mjs +0 -190
  56. package/core/platform/custom-objects/definition.mjs.map +0 -1
  57. package/core/platform/custom-objects/fields.d.mts +0 -302
  58. package/core/platform/custom-objects/fields.d.mts.map +0 -1
  59. package/core/platform/custom-objects/fields.d.ts +0 -302
  60. package/core/platform/custom-objects/fields.d.ts.map +0 -1
  61. package/core/platform/custom-objects/fields.js +0 -369
  62. package/core/platform/custom-objects/fields.js.map +0 -1
  63. package/core/platform/custom-objects/fields.mjs +0 -347
  64. package/core/platform/custom-objects/fields.mjs.map +0 -1
  65. package/core/platform/custom-objects/function-runtime.d.mts +0 -42
  66. package/core/platform/custom-objects/function-runtime.d.mts.map +0 -1
  67. package/core/platform/custom-objects/function-runtime.d.ts +0 -42
  68. package/core/platform/custom-objects/function-runtime.d.ts.map +0 -1
  69. package/core/platform/custom-objects/function-runtime.js +0 -38
  70. package/core/platform/custom-objects/function-runtime.js.map +0 -1
  71. package/core/platform/custom-objects/function-runtime.mjs +0 -35
  72. package/core/platform/custom-objects/function-runtime.mjs.map +0 -1
  73. package/core/platform/custom-objects/lifecycle.d.mts +0 -83
  74. package/core/platform/custom-objects/lifecycle.d.mts.map +0 -1
  75. package/core/platform/custom-objects/lifecycle.d.ts +0 -83
  76. package/core/platform/custom-objects/lifecycle.d.ts.map +0 -1
  77. package/core/platform/custom-objects/lifecycle.js +0 -372
  78. package/core/platform/custom-objects/lifecycle.js.map +0 -1
  79. package/core/platform/custom-objects/lifecycle.mjs +0 -367
  80. package/core/platform/custom-objects/lifecycle.mjs.map +0 -1
  81. package/core/platform/custom-objects/manager.d.mts +0 -354
  82. package/core/platform/custom-objects/manager.d.mts.map +0 -1
  83. package/core/platform/custom-objects/manager.d.ts +0 -354
  84. package/core/platform/custom-objects/manager.d.ts.map +0 -1
  85. package/core/platform/custom-objects/manager.js +0 -646
  86. package/core/platform/custom-objects/manager.js.map +0 -1
  87. package/core/platform/custom-objects/manager.mjs +0 -637
  88. package/core/platform/custom-objects/manager.mjs.map +0 -1
  89. package/core/platform/custom-objects/provisioning.d.mts +0 -138
  90. package/core/platform/custom-objects/provisioning.d.mts.map +0 -1
  91. package/core/platform/custom-objects/provisioning.d.ts +0 -138
  92. package/core/platform/custom-objects/provisioning.d.ts.map +0 -1
  93. package/core/platform/custom-objects/provisioning.js +0 -455
  94. package/core/platform/custom-objects/provisioning.js.map +0 -1
  95. package/core/platform/custom-objects/provisioning.mjs +0 -447
  96. package/core/platform/custom-objects/provisioning.mjs.map +0 -1
  97. package/core/platform/custom-objects/rql.d.mts +0 -122
  98. package/core/platform/custom-objects/rql.d.mts.map +0 -1
  99. package/core/platform/custom-objects/rql.d.ts +0 -122
  100. package/core/platform/custom-objects/rql.d.ts.map +0 -1
  101. package/core/platform/custom-objects/rql.js +0 -225
  102. package/core/platform/custom-objects/rql.js.map +0 -1
  103. package/core/platform/custom-objects/rql.mjs +0 -222
  104. package/core/platform/custom-objects/rql.mjs.map +0 -1
  105. package/core/platform/custom-objects/schema-manager.d.mts +0 -203
  106. package/core/platform/custom-objects/schema-manager.d.mts.map +0 -1
  107. package/core/platform/custom-objects/schema-manager.d.ts +0 -203
  108. package/core/platform/custom-objects/schema-manager.d.ts.map +0 -1
  109. package/core/platform/custom-objects/schema-manager.js +0 -256
  110. package/core/platform/custom-objects/schema-manager.js.map +0 -1
  111. package/core/platform/custom-objects/schema-manager.mjs +0 -249
  112. package/core/platform/custom-objects/schema-manager.mjs.map +0 -1
  113. package/core/platform/custom-objects/typed-rql.d.mts +0 -157
  114. package/core/platform/custom-objects/typed-rql.d.mts.map +0 -1
  115. package/core/platform/custom-objects/typed-rql.d.ts +0 -157
  116. package/core/platform/custom-objects/typed-rql.d.ts.map +0 -1
  117. package/core/platform/custom-objects/typed-rql.js +0 -583
  118. package/core/platform/custom-objects/typed-rql.js.map +0 -1
  119. package/core/platform/custom-objects/typed-rql.mjs +0 -580
  120. package/core/platform/custom-objects/typed-rql.mjs.map +0 -1
  121. package/core/platform/custom-objects/types.d.mts +0 -549
  122. package/core/platform/custom-objects/types.d.mts.map +0 -1
  123. package/core/platform/custom-objects/types.d.ts +0 -549
  124. package/core/platform/custom-objects/types.d.ts.map +0 -1
  125. package/core/platform/custom-objects/types.js +0 -20
  126. package/core/platform/custom-objects/types.js.map +0 -1
  127. package/core/platform/custom-objects/types.mjs +0 -17
  128. package/core/platform/custom-objects/types.mjs.map +0 -1
  129. package/core/platform/custom-objects/validation.d.mts +0 -97
  130. package/core/platform/custom-objects/validation.d.mts.map +0 -1
  131. package/core/platform/custom-objects/validation.d.ts +0 -97
  132. package/core/platform/custom-objects/validation.d.ts.map +0 -1
  133. package/core/platform/custom-objects/validation.js +0 -477
  134. package/core/platform/custom-objects/validation.js.map +0 -1
  135. package/core/platform/custom-objects/validation.mjs +0 -465
  136. package/core/platform/custom-objects/validation.mjs.map +0 -1
  137. package/core/platform/custom-objects.d.mts +0 -67
  138. package/core/platform/custom-objects.d.mts.map +0 -1
  139. package/core/platform/custom-objects.d.ts +0 -67
  140. package/core/platform/custom-objects.d.ts.map +0 -1
  141. package/core/platform/custom-objects.js +0 -118
  142. package/core/platform/custom-objects.js.map +0 -1
  143. package/core/platform/custom-objects.mjs +0 -45
  144. package/core/platform/custom-objects.mjs.map +0 -1
  145. package/core/platform/manifest/custom-objects/action.d.mts +0 -58
  146. package/core/platform/manifest/custom-objects/action.d.mts.map +0 -1
  147. package/core/platform/manifest/custom-objects/action.d.ts +0 -58
  148. package/core/platform/manifest/custom-objects/action.d.ts.map +0 -1
  149. package/core/platform/manifest/custom-objects/action.js +0 -44
  150. package/core/platform/manifest/custom-objects/action.js.map +0 -1
  151. package/core/platform/manifest/custom-objects/action.mjs +0 -40
  152. package/core/platform/manifest/custom-objects/action.mjs.map +0 -1
  153. package/core/platform/manifest/custom-objects/conditions.d.mts +0 -240
  154. package/core/platform/manifest/custom-objects/conditions.d.mts.map +0 -1
  155. package/core/platform/manifest/custom-objects/conditions.d.ts +0 -240
  156. package/core/platform/manifest/custom-objects/conditions.d.ts.map +0 -1
  157. package/core/platform/manifest/custom-objects/conditions.js +0 -326
  158. package/core/platform/manifest/custom-objects/conditions.js.map +0 -1
  159. package/core/platform/manifest/custom-objects/conditions.mjs +0 -321
  160. package/core/platform/manifest/custom-objects/conditions.mjs.map +0 -1
  161. package/core/platform/manifest/custom-objects/existing.d.mts +0 -87
  162. package/core/platform/manifest/custom-objects/existing.d.mts.map +0 -1
  163. package/core/platform/manifest/custom-objects/existing.d.ts +0 -87
  164. package/core/platform/manifest/custom-objects/existing.d.ts.map +0 -1
  165. package/core/platform/manifest/custom-objects/existing.js +0 -113
  166. package/core/platform/manifest/custom-objects/existing.js.map +0 -1
  167. package/core/platform/manifest/custom-objects/existing.mjs +0 -109
  168. package/core/platform/manifest/custom-objects/existing.mjs.map +0 -1
  169. package/core/platform/manifest/custom-objects/field-resolution.d.mts +0 -48
  170. package/core/platform/manifest/custom-objects/field-resolution.d.mts.map +0 -1
  171. package/core/platform/manifest/custom-objects/field-resolution.d.ts +0 -48
  172. package/core/platform/manifest/custom-objects/field-resolution.d.ts.map +0 -1
  173. package/core/platform/manifest/custom-objects/field-resolution.js +0 -61
  174. package/core/platform/manifest/custom-objects/field-resolution.js.map +0 -1
  175. package/core/platform/manifest/custom-objects/field-resolution.mjs +0 -58
  176. package/core/platform/manifest/custom-objects/field-resolution.mjs.map +0 -1
  177. package/core/platform/manifest/custom-objects/function-file.d.mts +0 -87
  178. package/core/platform/manifest/custom-objects/function-file.d.mts.map +0 -1
  179. package/core/platform/manifest/custom-objects/function-file.d.ts +0 -87
  180. package/core/platform/manifest/custom-objects/function-file.d.ts.map +0 -1
  181. package/core/platform/manifest/custom-objects/function-file.js +0 -76
  182. package/core/platform/manifest/custom-objects/function-file.js.map +0 -1
  183. package/core/platform/manifest/custom-objects/function-file.mjs +0 -69
  184. package/core/platform/manifest/custom-objects/function-file.mjs.map +0 -1
  185. package/core/platform/manifest/custom-objects/list-view.d.mts +0 -65
  186. package/core/platform/manifest/custom-objects/list-view.d.mts.map +0 -1
  187. package/core/platform/manifest/custom-objects/list-view.d.ts +0 -65
  188. package/core/platform/manifest/custom-objects/list-view.d.ts.map +0 -1
  189. package/core/platform/manifest/custom-objects/list-view.js +0 -33
  190. package/core/platform/manifest/custom-objects/list-view.js.map +0 -1
  191. package/core/platform/manifest/custom-objects/list-view.mjs +0 -30
  192. package/core/platform/manifest/custom-objects/list-view.mjs.map +0 -1
  193. package/core/platform/manifest/custom-objects/object-list-page.d.mts +0 -43
  194. package/core/platform/manifest/custom-objects/object-list-page.d.mts.map +0 -1
  195. package/core/platform/manifest/custom-objects/object-list-page.d.ts +0 -43
  196. package/core/platform/manifest/custom-objects/object-list-page.d.ts.map +0 -1
  197. package/core/platform/manifest/custom-objects/object-list-page.js +0 -54
  198. package/core/platform/manifest/custom-objects/object-list-page.js.map +0 -1
  199. package/core/platform/manifest/custom-objects/object-list-page.mjs +0 -50
  200. package/core/platform/manifest/custom-objects/object-list-page.mjs.map +0 -1
  201. package/core/platform/manifest/custom-objects/page-layout.d.mts +0 -142
  202. package/core/platform/manifest/custom-objects/page-layout.d.mts.map +0 -1
  203. package/core/platform/manifest/custom-objects/page-layout.d.ts +0 -142
  204. package/core/platform/manifest/custom-objects/page-layout.d.ts.map +0 -1
  205. package/core/platform/manifest/custom-objects/page-layout.js +0 -184
  206. package/core/platform/manifest/custom-objects/page-layout.js.map +0 -1
  207. package/core/platform/manifest/custom-objects/page-layout.mjs +0 -180
  208. package/core/platform/manifest/custom-objects/page-layout.mjs.map +0 -1
  209. package/core/platform/manifest/custom-objects/register.d.mts +0 -87
  210. package/core/platform/manifest/custom-objects/register.d.mts.map +0 -1
  211. package/core/platform/manifest/custom-objects/register.d.ts +0 -87
  212. package/core/platform/manifest/custom-objects/register.d.ts.map +0 -1
  213. package/core/platform/manifest/custom-objects/register.js +0 -395
  214. package/core/platform/manifest/custom-objects/register.js.map +0 -1
  215. package/core/platform/manifest/custom-objects/register.mjs +0 -391
  216. package/core/platform/manifest/custom-objects/register.mjs.map +0 -1
  217. package/core/platform/manifest/custom-objects/rule.d.mts +0 -113
  218. package/core/platform/manifest/custom-objects/rule.d.mts.map +0 -1
  219. package/core/platform/manifest/custom-objects/rule.d.ts +0 -113
  220. package/core/platform/manifest/custom-objects/rule.d.ts.map +0 -1
  221. package/core/platform/manifest/custom-objects/rule.js +0 -49
  222. package/core/platform/manifest/custom-objects/rule.js.map +0 -1
  223. package/core/platform/manifest/custom-objects/rule.mjs +0 -45
  224. package/core/platform/manifest/custom-objects/rule.mjs.map +0 -1
  225. package/core/platform/manifest/custom-objects/sdui-page.d.mts +0 -214
  226. package/core/platform/manifest/custom-objects/sdui-page.d.mts.map +0 -1
  227. package/core/platform/manifest/custom-objects/sdui-page.d.ts +0 -214
  228. package/core/platform/manifest/custom-objects/sdui-page.d.ts.map +0 -1
  229. package/core/platform/manifest/custom-objects/sdui-page.js +0 -194
  230. package/core/platform/manifest/custom-objects/sdui-page.js.map +0 -1
  231. package/core/platform/manifest/custom-objects/sdui-page.mjs +0 -182
  232. package/core/platform/manifest/custom-objects/sdui-page.mjs.map +0 -1
  233. package/core/platform/manifest/custom-objects/typed-condition.d.mts +0 -28
  234. package/core/platform/manifest/custom-objects/typed-condition.d.mts.map +0 -1
  235. package/core/platform/manifest/custom-objects/typed-condition.d.ts +0 -28
  236. package/core/platform/manifest/custom-objects/typed-condition.d.ts.map +0 -1
  237. package/core/platform/manifest/custom-objects/typed-condition.js +0 -434
  238. package/core/platform/manifest/custom-objects/typed-condition.js.map +0 -1
  239. package/core/platform/manifest/custom-objects/typed-condition.mjs +0 -431
  240. package/core/platform/manifest/custom-objects/typed-condition.mjs.map +0 -1
  241. package/core/platform/manifest/custom-objects/types.d.mts +0 -29
  242. package/core/platform/manifest/custom-objects/types.d.mts.map +0 -1
  243. package/core/platform/manifest/custom-objects/types.d.ts +0 -29
  244. package/core/platform/manifest/custom-objects/types.d.ts.map +0 -1
  245. package/core/platform/manifest/custom-objects/types.js +0 -3
  246. package/core/platform/manifest/custom-objects/types.js.map +0 -1
  247. package/core/platform/manifest/custom-objects/types.mjs +0 -2
  248. package/core/platform/manifest/custom-objects/types.mjs.map +0 -1
  249. package/core/platform/manifest/custom-objects/validation.d.mts +0 -44
  250. package/core/platform/manifest/custom-objects/validation.d.mts.map +0 -1
  251. package/core/platform/manifest/custom-objects/validation.d.ts +0 -44
  252. package/core/platform/manifest/custom-objects/validation.d.ts.map +0 -1
  253. package/core/platform/manifest/custom-objects/validation.js +0 -30
  254. package/core/platform/manifest/custom-objects/validation.js.map +0 -1
  255. package/core/platform/manifest/custom-objects/validation.mjs +0 -27
  256. package/core/platform/manifest/custom-objects/validation.mjs.map +0 -1
  257. package/core/platform/manifest/custom-objects/workflow.d.mts +0 -47
  258. package/core/platform/manifest/custom-objects/workflow.d.mts.map +0 -1
  259. package/core/platform/manifest/custom-objects/workflow.d.ts +0 -47
  260. package/core/platform/manifest/custom-objects/workflow.d.ts.map +0 -1
  261. package/core/platform/manifest/custom-objects/workflow.js +0 -38
  262. package/core/platform/manifest/custom-objects/workflow.js.map +0 -1
  263. package/core/platform/manifest/custom-objects/workflow.mjs +0 -34
  264. package/core/platform/manifest/custom-objects/workflow.mjs.map +0 -1
  265. package/core/platform/manifest/custom-objects.d.mts +0 -85
  266. package/core/platform/manifest/custom-objects.d.mts.map +0 -1
  267. package/core/platform/manifest/custom-objects.d.ts +0 -85
  268. package/core/platform/manifest/custom-objects.d.ts.map +0 -1
  269. package/core/platform/manifest/custom-objects.js +0 -84
  270. package/core/platform/manifest/custom-objects.js.map +0 -1
  271. package/core/platform/manifest/custom-objects.mjs +0 -55
  272. package/core/platform/manifest/custom-objects.mjs.map +0 -1
  273. package/examples/manifest/custom-object-creation-workflow/functions/intake-request-created.ts +0 -20
  274. package/examples/manifest/custom-object-creation-workflow/schema.ts +0 -29
  275. package/examples/manifest/dental-practice-management/schema.ts +0 -298
  276. package/examples/manifest/field-service-dispatch/schema.ts +0 -248
  277. package/examples/manifest/grant-program-management/schema.ts +0 -269
  278. package/examples/manifest/gym-membership-management/schema.ts +0 -266
  279. package/examples/manifest/procurement-approval-hub/functions/route-purchase-request.ts +0 -20
  280. package/examples/manifest/procurement-approval-hub/schema.ts +0 -256
  281. package/examples/manifest/simple-todo-app/schema.ts +0 -60
  282. package/examples/manifest/todo-app-without-object-list-view/schema.ts +0 -28
  283. package/src/core/platform/README.md +0 -20
  284. package/src/core/platform/custom-objects/category.ts +0 -294
  285. package/src/core/platform/custom-objects/definition.ts +0 -373
  286. package/src/core/platform/custom-objects/fields.ts +0 -653
  287. package/src/core/platform/custom-objects/function-runtime.ts +0 -76
  288. package/src/core/platform/custom-objects/lifecycle.ts +0 -557
  289. package/src/core/platform/custom-objects/manager.ts +0 -959
  290. package/src/core/platform/custom-objects/provisioning.ts +0 -672
  291. package/src/core/platform/custom-objects/rql.ts +0 -375
  292. package/src/core/platform/custom-objects/schema-manager.ts +0 -351
  293. package/src/core/platform/custom-objects/typed-rql.ts +0 -1273
  294. package/src/core/platform/custom-objects/types.ts +0 -753
  295. package/src/core/platform/custom-objects/validation.ts +0 -573
  296. package/src/core/platform/custom-objects.ts +0 -269
  297. package/src/core/platform/manifest/README.md +0 -26
  298. package/src/core/platform/manifest/custom-objects/action.ts +0 -87
  299. package/src/core/platform/manifest/custom-objects/conditions.ts +0 -762
  300. package/src/core/platform/manifest/custom-objects/existing.ts +0 -221
  301. package/src/core/platform/manifest/custom-objects/field-resolution.ts +0 -116
  302. package/src/core/platform/manifest/custom-objects/function-file.ts +0 -149
  303. package/src/core/platform/manifest/custom-objects/list-view.ts +0 -95
  304. package/src/core/platform/manifest/custom-objects/object-list-page.ts +0 -87
  305. package/src/core/platform/manifest/custom-objects/page-layout.ts +0 -380
  306. package/src/core/platform/manifest/custom-objects/register.ts +0 -555
  307. package/src/core/platform/manifest/custom-objects/rule.ts +0 -192
  308. package/src/core/platform/manifest/custom-objects/sdui-page.ts +0 -515
  309. package/src/core/platform/manifest/custom-objects/typed-condition.ts +0 -617
  310. package/src/core/platform/manifest/custom-objects/types.ts +0 -92
  311. package/src/core/platform/manifest/custom-objects/validation.ts +0 -70
  312. package/src/core/platform/manifest/custom-objects/workflow.ts +0 -71
  313. package/src/core/platform/manifest/custom-objects.ts +0 -203
  314. package/src/pebble-sdui-web-custom-apps-shim.d.ts +0 -3
@@ -2,43 +2,46 @@
2
2
  * Dental Practice Management — patient charts, operatories (chairs), appointments
3
3
  * with status, treatment plans, rollups, and an SDUI ObjectListView tab for appointments.
4
4
  *
5
- * This example demonstrates the typed custom-object schema layer under
6
- * `@rippling/rippling-sdk/core/platform/custom-objects` and then compiles those
7
- * structural definitions back into the existing manifest class model.
5
+ * dental_patient__c ← chart: demographics, allergies, notes
6
+ * dental_provider__c ← providers selectable for appointments
7
+ * dental_operatory__c ← chair / room (parent for same-day board rollups)
8
+ * dental_appointment__c ← child of operatory; patient lookup, time, status, visit type
9
+ * dental_treatment_plan__c ← child of patient; plan status, procedures, estimates
8
10
  *
9
11
  * Run:
10
12
  * yarn tsn examples/manifest/dental-practice-management/dental-practice-management.ts \
11
13
  * > examples/manifest/dental-practice-management/manifest.json
12
14
  */
13
15
 
16
+ import * as fs from 'node:fs';
14
17
  import * as path from 'node:path';
15
- import { toCustomCategoryApiName } from '@rippling/rippling-sdk/core/platform/custom-objects';
16
- import {
17
- defineSduiPageFromFunctionFile,
18
- defineTypedCustomObjectActionFromFunctionFile,
19
- defineTypedListView,
20
- defineTypedPageLayout,
21
- defineTypedRule,
22
- defineTypedValidation,
23
- registerManifestCustomObject,
24
- } from '@rippling/rippling-sdk/core/platform/manifest/custom-objects';
25
18
  import {
26
19
  App,
20
+ BooleanField,
27
21
  Category,
28
- type CustomObject,
22
+ CustomObject,
23
+ CustomObjectAction,
24
+ CustomObjectFieldSection,
25
+ CustomObjectPageLayout,
26
+ DatetimeField,
27
+ DateField,
28
+ EmailField,
29
+ FormulaField,
30
+ ListViewDef,
31
+ LongTextField,
32
+ LookupField,
29
33
  ManifestBuilder,
34
+ ManifestFunction,
35
+ NumberField,
36
+ ParentChildField,
37
+ PhoneField,
38
+ Rule,
39
+ RadioField,
30
40
  SduiPage,
31
41
  SummaryField,
42
+ TextField,
43
+ Validation,
32
44
  } from '@rippling/rippling-sdk/lib/manifest';
33
- import {
34
- appointmentDefinition,
35
- DENTAL_CATEGORY_NAME,
36
- operatoryDefinition,
37
- patientDefinition,
38
- providerDefinition,
39
- treatmentPlanDefinition,
40
- } from './schema';
41
-
42
45
  const manifest = new ManifestBuilder({
43
46
  key: 'dental_practice_management',
44
47
  name: 'Dental Practice Management',
@@ -47,165 +50,477 @@ const manifest = new ManifestBuilder({
47
50
  });
48
51
 
49
52
  const dentalCategory = new Category(manifest, {
50
- apiName: toCustomCategoryApiName(DENTAL_CATEGORY_NAME),
53
+ apiName: 'dental__c',
51
54
  name: 'Dental',
52
55
  description: 'Patients, chairs, visits, and treatment plans',
53
56
  });
54
57
 
55
- const registeredObjects = new Map<string, { object: CustomObject }>();
58
+ // ── Patient (chart) ─────────────────────────────────────────────────────────
59
+ const patientObj = new CustomObject(manifest, {
60
+ apiName: 'dental_patient__c',
61
+ name: 'Patient',
62
+ pluralLabel: 'Patients',
63
+ category: dentalCategory,
64
+ description: 'Clinical chart, demographics, and care preferences',
65
+ icon: { emoji: '🦷' },
66
+ });
56
67
 
57
- function resolveCustomObjectTarget(apiName: string): CustomObject {
58
- const target = registeredObjects.get(apiName);
59
- if (target == null) {
60
- throw new Error(`Custom object target "${apiName}" must be registered before dependents.`);
61
- }
62
- return target.object;
63
- }
68
+ const patientIdentitySection = new CustomObjectFieldSection(patientObj, {
69
+ name: 'Demographics',
70
+ sectionId: 'sec_pt_identity',
71
+ });
64
72
 
65
- const patient = registerManifestCustomObject(manifest, {
66
- definition: patientDefinition,
67
- category: dentalCategory,
68
- resolveCustomObjectTarget,
73
+ const patientClinicalSection = new CustomObjectFieldSection(patientObj, {
74
+ name: 'Clinical',
75
+ sectionId: 'sec_pt_clinical',
76
+ });
77
+
78
+ const patientNameField = new TextField(patientObj, {
79
+ apiName: 'legal_name__c',
80
+ displayName: 'Full legal name',
81
+ description: 'Full legal name field',
82
+ required: true,
83
+ maxLength: 160,
84
+ section: patientIdentitySection,
85
+ });
86
+
87
+ const patientDobField = new DateField(patientObj, {
88
+ apiName: 'date_of_birth__c',
89
+ displayName: 'Date of birth',
90
+ description: 'Date of birth field',
91
+ section: patientIdentitySection,
92
+ });
93
+
94
+ const patientPhoneField = new PhoneField(patientObj, {
95
+ apiName: 'phone__c',
96
+ displayName: 'Phone',
97
+ description: 'Phone field',
98
+ section: patientIdentitySection,
99
+ });
100
+
101
+ const patientEmailField = new EmailField(patientObj, {
102
+ apiName: 'email__c',
103
+ displayName: 'Email',
104
+ description: 'Email field',
105
+ unique: true,
106
+ section: patientIdentitySection,
107
+ });
108
+
109
+ const patientActiveField = new BooleanField(patientObj, {
110
+ apiName: 'active_patient__c',
111
+ displayName: 'Active patient',
112
+ description: 'Whether the patient is currently active in the practice',
113
+ required: true,
114
+ section: patientIdentitySection,
115
+ });
116
+
117
+ const patientAllergiesField = new LongTextField(patientObj, {
118
+ apiName: 'allergies_and_alerts__c',
119
+ displayName: 'Allergies & medical alerts',
120
+ maxLength: 2000,
121
+ description: 'Drug allergies, bisphosphonates, anticoagulants, latex, etc.',
122
+ section: patientClinicalSection,
123
+ });
124
+
125
+ const patientInsuranceField = new TextField(patientObj, {
126
+ apiName: 'insurance_plan__c',
127
+ displayName: 'Insurance / payer',
128
+ description: 'Insurance / payer field',
129
+ maxLength: 120,
130
+ section: patientClinicalSection,
131
+ });
132
+
133
+ const patientChartNotesField = new LongTextField(patientObj, {
134
+ apiName: 'chart_summary__c',
135
+ displayName: 'Chart summary & preferences',
136
+ maxLength: 4000,
137
+ description: 'Narrative, anxiety notes, perio class, last prophy, family history',
138
+ section: patientClinicalSection,
139
+ });
140
+
141
+ const patientLabelField = new FormulaField(patientObj, {
142
+ apiName: 'patient_label__c',
143
+ displayName: 'Chart label',
144
+ fieldType: 'TEXT',
145
+ maxLength: 220,
146
+ formula: "CONCATENATE(legal_name__c, ' (b. ', YEAR(date_of_birth__c), ')')",
147
+ description: 'Quick list label (name and birth year)',
148
+ section: patientIdentitySection,
69
149
  });
70
- registeredObjects.set(patient.definition.apiName, patient);
71
150
 
72
- const provider = registerManifestCustomObject(manifest, {
73
- definition: providerDefinition,
151
+ // ── Provider ────────────────────────────────────────────────────────────────
152
+ const providerObj = new CustomObject(manifest, {
153
+ apiName: 'dental_provider__c',
154
+ name: 'Provider',
155
+ pluralLabel: 'Providers',
74
156
  category: dentalCategory,
75
- resolveCustomObjectTarget,
157
+ description: 'Clinicians who can be assigned to appointment blocks',
158
+ icon: { emoji: '🧑‍⚕️' },
76
159
  });
77
- registeredObjects.set(provider.definition.apiName, provider);
78
160
 
79
- const operatory = registerManifestCustomObject(manifest, {
80
- definition: operatoryDefinition,
161
+ const providerSection = new CustomObjectFieldSection(providerObj, {
162
+ name: 'Provider',
163
+ sectionId: 'sec_provider_info',
164
+ });
165
+
166
+ const providerNameField = providerObj.standardFields.name;
167
+
168
+ const providerStatusField = new RadioField(providerObj, {
169
+ apiName: 'provider_status__c',
170
+ displayName: 'Status',
171
+ description: 'Whether this provider is active in the practice',
172
+ options: ['Active', 'On leave', 'Inactive'],
173
+ required: true,
174
+ section: providerSection,
175
+ });
176
+
177
+ const providerBookingStatusField = new RadioField(providerObj, {
178
+ apiName: 'booking_status__c',
179
+ displayName: 'Booking status',
180
+ description: 'Whether scheduling should offer this provider for new appointments',
181
+ options: ['Open', 'Limited', 'Closed'],
182
+ required: true,
183
+ section: providerSection,
184
+ });
185
+
186
+ const providerNextAvailableDaysField = new NumberField(providerObj, {
187
+ apiName: 'next_available_days__c',
188
+ displayName: 'Next available (days)',
189
+ description: 'Estimated days until this provider has an open appointment slot',
190
+ decimalPlaces: 0,
191
+ required: true,
192
+ section: providerSection,
193
+ });
194
+
195
+ // ── Operatory (chair) ─────────────────────────────────────────────────────────
196
+ const operatoryObj = new CustomObject(manifest, {
197
+ apiName: 'dental_operatory__c',
198
+ name: 'Operatory',
199
+ pluralLabel: 'Operatories',
81
200
  category: dentalCategory,
82
- resolveCustomObjectTarget,
201
+ description: 'A chair, bay, or room you book on the daily board',
202
+ icon: { emoji: '🪥' },
83
203
  });
84
- registeredObjects.set(operatory.definition.apiName, operatory);
85
204
 
86
- const appointment = registerManifestCustomObject(manifest, {
87
- definition: appointmentDefinition,
205
+ const operatorySection = new CustomObjectFieldSection(operatoryObj, {
206
+ name: 'Operatory',
207
+ sectionId: 'sec_op_info',
208
+ });
209
+
210
+ const opNameField = operatoryObj.standardFields.name;
211
+
212
+ const opCodeField = new TextField(operatoryObj, {
213
+ apiName: 'room_code__c',
214
+ displayName: 'Room code',
215
+ maxLength: 20,
216
+ description: 'Short code for whiteboards and schedules',
217
+ section: operatorySection,
218
+ });
219
+
220
+ // ── Appointment (child of operatory) ─────────────────────────────────────────
221
+ const apptObj = new CustomObject(manifest, {
222
+ apiName: 'dental_appointment__c',
223
+ name: 'Appointment',
224
+ pluralLabel: 'Appointments',
88
225
  category: dentalCategory,
89
- resolveCustomObjectTarget,
226
+ description: 'Chair booking with visit type and real-time visit status',
227
+ icon: { emoji: '📅' },
228
+ });
229
+
230
+ const apptOperatorySection = new CustomObjectFieldSection(apptObj, {
231
+ name: 'Operatory & time',
232
+ sectionId: 'sec_appt_op',
90
233
  });
91
- registeredObjects.set(appointment.definition.apiName, appointment);
92
234
 
93
- const treatmentPlan = registerManifestCustomObject(manifest, {
94
- definition: treatmentPlanDefinition,
235
+ const apptPatientSection = new CustomObjectFieldSection(apptObj, {
236
+ name: 'Patient & visit',
237
+ sectionId: 'sec_appt_patient',
238
+ });
239
+
240
+ const apptOperatoryRef = new ParentChildField(apptObj, {
241
+ apiName: 'operatory_ref__c',
242
+ displayName: 'Operatory (chair)',
243
+ target: operatoryObj,
244
+ relatedDataLabel: 'Appointments',
245
+ parentChildType: 'PRIMARY',
246
+ enableParentOwnerInheritance: false,
247
+ description: 'Which chair or bay this visit is booked on',
248
+ section: apptOperatorySection,
249
+ });
250
+
251
+ const apptStartField = new DatetimeField(apptObj, {
252
+ apiName: 'start_time__c',
253
+ displayName: 'Start (local)',
254
+ required: true,
255
+ description: 'Planned or actual start; board sorts by this',
256
+ section: apptOperatorySection,
257
+ });
258
+
259
+ const apptDurationMins = new NumberField(apptObj, {
260
+ apiName: 'duration_minutes__c',
261
+ displayName: 'Duration (minutes)',
262
+ required: true,
263
+ decimalPlaces: 0,
264
+ description: 'Expected chair time for the procedure block',
265
+ section: apptOperatorySection,
266
+ });
267
+
268
+ const apptPatientRef = new LookupField(apptObj, {
269
+ apiName: 'patient_ref__c',
270
+ displayName: 'Patient',
271
+ target: patientObj,
272
+ relatedDataLabel: 'Appointments',
273
+ required: true,
274
+ lookup_filter_rql_condition: '(active_patient__c == True)',
275
+ description: 'Chart to open for this visit (active patients only)',
276
+ section: apptPatientSection,
277
+ });
278
+
279
+ const apptProviderRef = new LookupField(apptObj, {
280
+ apiName: 'provider_ref__c',
281
+ displayName: 'Provider',
282
+ target: providerObj,
283
+ relatedDataLabel: 'Appointments',
284
+ required: true,
285
+ lookup_filter_rql_condition:
286
+ "((provider_status__c IN ['Active']) AND (next_available_days__c <= 14) AND (booking_status__c NOT_IN ['Closed']))",
287
+ description: 'Provider assigned to this visit (active and bookable within two weeks)',
288
+ section: apptPatientSection,
289
+ });
290
+
291
+ const apptVisitTypeField = new RadioField(apptObj, {
292
+ apiName: 'visit_type__c',
293
+ displayName: 'Visit type',
294
+ description: 'Visit type field',
295
+ options: [
296
+ 'New patient exam',
297
+ 'Periodic / recall exam',
298
+ 'Prophy / cleaning',
299
+ 'Restorative',
300
+ 'Endodontic',
301
+ 'Perio / SRP',
302
+ 'Oral surgery / extraction',
303
+ 'Orthodontic',
304
+ 'Emergency / pain',
305
+ 'Other',
306
+ ],
307
+ required: true,
308
+ section: apptPatientSection,
309
+ });
310
+
311
+ const apptStatusField = new RadioField(apptObj, {
312
+ apiName: 'appointment_status__c',
313
+ displayName: 'Visit status',
314
+ options: ['Scheduled', 'Checked in', 'In treatment', 'Completed', 'Cancelled', 'No-show'],
315
+ required: true,
316
+ description: 'Front-desk and clinical workflow status',
317
+ section: apptPatientSection,
318
+ });
319
+
320
+ const apptClinicalNotes = new LongTextField(apptObj, {
321
+ apiName: 'visit_notes__c',
322
+ displayName: 'Visit notes',
323
+ maxLength: 4000,
324
+ description: 'Chairside notes for this block (sync with EDR as needed)',
325
+ section: apptPatientSection,
326
+ });
327
+
328
+ const apptBoardLabel = new FormulaField(apptObj, {
329
+ apiName: 'board_label__c',
330
+ displayName: 'Board label',
331
+ description: 'Board label field',
332
+ fieldType: 'TEXT',
333
+ maxLength: 260,
334
+ formula: "CONCATENATE(visit_type__c, ' · ', appointment_status__c)",
335
+ section: apptPatientSection,
336
+ });
337
+
338
+ // ── Treatment plan (child of patient) ─────────────────────────────────────────
339
+ const planObj = new CustomObject(manifest, {
340
+ apiName: 'dental_treatment_plan__c',
341
+ name: 'Treatment plan',
342
+ pluralLabel: 'Treatment plans',
95
343
  category: dentalCategory,
96
- resolveCustomObjectTarget,
344
+ description: 'Staged work sequenced for a patient',
345
+ icon: { emoji: '📋' },
346
+ });
347
+
348
+ const planLinkSection = new CustomObjectFieldSection(planObj, {
349
+ name: 'Link',
350
+ sectionId: 'sec_plan_link',
351
+ });
352
+
353
+ const planBodySection = new CustomObjectFieldSection(planObj, {
354
+ name: 'Plan',
355
+ sectionId: 'sec_plan_body',
356
+ });
357
+
358
+ const planNameField = planObj.standardFields.name;
359
+
360
+ const planPatientRef = new ParentChildField(planObj, {
361
+ apiName: 'plan_patient_ref__c',
362
+ displayName: 'Patient',
363
+ target: patientObj,
364
+ relatedDataLabel: 'Treatment plans',
365
+ parentChildType: 'PRIMARY',
366
+ enableParentOwnerInheritance: false,
367
+ description: 'Which chart owns this plan',
368
+ section: planLinkSection,
369
+ });
370
+
371
+ const planStatusField = new RadioField(planObj, {
372
+ apiName: 'plan_status__c',
373
+ displayName: 'Status',
374
+ description: 'Status field',
375
+ options: ['Draft', 'Presented', 'Accepted', 'In progress', 'Completed', 'Declined / on hold'],
376
+ required: true,
377
+ section: planBodySection,
378
+ });
379
+
380
+ const planTargetField = new DateField(planObj, {
381
+ apiName: 'target_completion__c',
382
+ displayName: 'Target completion',
383
+ description: 'Goal to finish or next review',
384
+ section: planBodySection,
385
+ });
386
+
387
+ const planProceduresField = new LongTextField(planObj, {
388
+ apiName: 'procedures_summary__c',
389
+ displayName: 'Procedures & sequence',
390
+ maxLength: 8000,
391
+ description: 'Tooth numbers, codes, and staging',
392
+ section: planBodySection,
393
+ });
394
+
395
+ const planFeeCents = new NumberField(planObj, {
396
+ apiName: 'fee_estimate_cents__c',
397
+ displayName: 'Fee estimate (cents)',
398
+ decimalPlaces: 0,
399
+ description: 'Rough office fee total for planning; adjust per office policy',
400
+ section: planBodySection,
97
401
  });
98
- registeredObjects.set(treatmentPlan.definition.apiName, treatmentPlan);
99
402
 
100
403
  // ── Rollups ────────────────────────────────────────────────────────────────
101
- const apptCountOnOperatory = new SummaryField(operatory.object, {
404
+ const apptCountOnOperatory = new SummaryField(operatoryObj, {
102
405
  apiName: 'appointment_count__c',
103
406
  displayName: 'Appointments (count)',
104
- aggregates: appointment.object.standardFields.name,
407
+ aggregates: apptPatientRef,
105
408
  using: 'COUNT',
106
- lookup: appointment.fields.operatory_ref,
409
+ lookup: apptOperatoryRef,
107
410
  description: 'Rows in this operatory (filter by day in the chair board function)',
108
- section: operatory.sections.operatory,
411
+ section: operatorySection,
109
412
  });
110
413
 
111
- const planCountOnPatient = new SummaryField(patient.object, {
414
+ const planCountOnPatient = new SummaryField(patientObj, {
112
415
  apiName: 'treatment_plan_count__c',
113
416
  displayName: 'Treatment plans',
114
- aggregates: treatmentPlan.object.standardFields.name,
417
+ aggregates: planNameField,
115
418
  using: 'COUNT',
116
- lookup: treatmentPlan.fields.plan_patient_ref,
419
+ lookup: planPatientRef,
117
420
  description: 'Active plans tied to the chart',
118
- section: patient.sections.clinical,
421
+ section: patientClinicalSection,
119
422
  });
120
423
 
121
- // ── Validations & defaults ────────────────────────────────────────────────
122
- defineTypedValidation(appointment, {
424
+ // ── Validations & defaults ──────────────────────────────────────────────────
425
+ new Validation(apptObj, {
123
426
  ruleId: 'dental_appt_duration_positive',
124
427
  displayName: 'Duration must be positive',
125
- whenInvalid: (c) => c.lte(c.fields.duration_minutes, 0),
428
+ rqlFormula: '(duration_minutes__c <= 0)',
126
429
  errorMessage: 'Duration must be at least 1 minute.',
127
430
  ruleDescription: 'Blocks empty or zero chair blocks',
128
431
  state: 'ACTIVE',
129
432
  level: 'FIELD',
130
- field: 'duration_minutes',
433
+ fieldRef: apptDurationMins,
131
434
  });
132
435
 
133
- defineTypedRule(appointment, {
436
+ new Rule(apptObj, {
134
437
  flowId: 'dental_default_appt_status',
135
438
  flowName: 'Default visit status to Scheduled',
136
439
  triggerType: 'CREATE',
137
440
  description: 'New bookings start as Scheduled unless the team changes it',
138
- actions: (rules) => [rules.setField('appointment_status').toValue('Scheduled')],
441
+ actions: [{ targetField: apptStatusField, fixedValue: 'Scheduled' }],
139
442
  });
140
443
 
141
444
  // ── List views ─────────────────────────────────────────────────────────────
142
- defineTypedListView(patient, {
445
+ new ListViewDef(patientObj, {
143
446
  viewId: 'view_dental_all_patients',
144
447
  name: 'All patients',
145
448
  description: 'Full chart list with plan counts',
146
- fields: ['name', 'date_of_birth', 'phone', 'active_patient', 'patient_label', planCountOnPatient],
449
+ fields: [
450
+ 'name',
451
+ patientDobField,
452
+ patientPhoneField,
453
+ patientActiveField,
454
+ patientLabelField,
455
+ planCountOnPatient,
456
+ ],
147
457
  orderBy: 'name',
148
458
  sortOrder: 'ASC',
149
459
  isPublic: true,
150
460
  objectScope: 'all',
151
461
  });
152
462
 
153
- defineTypedListView(provider, {
463
+ new ListViewDef(providerObj, {
154
464
  viewId: 'view_dental_providers',
155
465
  name: 'All providers',
156
466
  description: 'Provider directory with appointment booking fields',
157
- fields: ['name', 'provider_status', 'booking_status', 'next_available_days'],
467
+ fields: [
468
+ providerNameField,
469
+ providerStatusField,
470
+ providerBookingStatusField,
471
+ providerNextAvailableDaysField,
472
+ ],
158
473
  orderBy: 'name',
159
474
  sortOrder: 'ASC',
160
475
  isPublic: true,
161
476
  objectScope: 'all',
162
477
  });
163
478
 
164
- defineTypedListView(operatory, {
479
+ new ListViewDef(operatoryObj, {
165
480
  viewId: 'view_dental_all_operatories',
166
481
  name: 'All operatories',
167
482
  description: 'Chairs and daily volume rollups',
168
- fields: ['name', 'room_code', apptCountOnOperatory],
483
+ fields: [opNameField, opCodeField, apptCountOnOperatory],
169
484
  orderBy: 'name',
170
485
  sortOrder: 'ASC',
171
486
  isPublic: true,
172
487
  objectScope: 'all',
173
488
  });
174
489
 
175
- defineTypedListView(appointment, {
490
+ new ListViewDef(apptObj, {
176
491
  viewId: 'view_dental_appointments_all',
177
492
  name: 'All appointments',
178
493
  description: 'Chronological board with chair and status',
179
494
  fields: [
180
495
  'name',
181
- 'operatory_ref',
182
- 'start_time',
183
- 'duration_minutes',
184
- 'patient_ref',
185
- 'provider_ref',
186
- 'visit_type',
187
- 'appointment_status',
188
- 'board_label',
496
+ apptOperatoryRef,
497
+ apptStartField,
498
+ apptDurationMins,
499
+ apptPatientRef,
500
+ apptProviderRef,
501
+ apptVisitTypeField,
502
+ apptStatusField,
503
+ apptBoardLabel,
189
504
  ],
190
- orderBy: 'start_time',
505
+ orderBy: apptStartField,
191
506
  sortOrder: 'ASC',
192
507
  isPublic: true,
193
508
  objectScope: 'all',
194
509
  });
195
510
 
196
- defineTypedListView(treatmentPlan, {
511
+ new ListViewDef(planObj, {
197
512
  viewId: 'view_dental_treatment_plans',
198
513
  name: 'All treatment plans',
199
514
  description: 'Case tracking by status',
200
- fields: ['name', 'plan_patient_ref', 'plan_status', 'target_completion', 'fee_estimate_cents'],
201
- orderBy: 'target_completion',
515
+ fields: [planNameField, planPatientRef, planStatusField, planTargetField, planFeeCents],
516
+ orderBy: planTargetField,
202
517
  sortOrder: 'ASC',
203
518
  isPublic: true,
204
519
  objectScope: 'all',
205
520
  });
206
521
 
207
- // ── Page layouts ───────────────────────────────────────────────────────────
208
- defineTypedPageLayout(patient, {
522
+ // ── Page layouts ─────────────────────────────────────────────────────────────
523
+ new CustomObjectPageLayout(patientObj, {
209
524
  apiName: 'default',
210
525
  name: 'Patient chart',
211
526
  layoutId: 'layout_dental_patient',
@@ -219,22 +534,27 @@ defineTypedPageLayout(patient, {
219
534
  {
220
535
  name: 'Profile',
221
536
  type: 'fields_section',
222
- section: patient.sections.identity,
537
+ section: patientIdentitySection,
223
538
  fields: [
224
539
  { field: 'name', editable: true },
225
- 'legal_name',
226
- 'date_of_birth',
227
- 'phone',
228
- 'email',
229
- 'active_patient',
230
- 'patient_label',
540
+ patientNameField,
541
+ patientDobField,
542
+ patientPhoneField,
543
+ patientEmailField,
544
+ patientActiveField,
545
+ patientLabelField,
231
546
  ],
232
547
  },
233
548
  {
234
549
  name: 'Clinical & billing',
235
550
  type: 'fields_section',
236
- section: patient.sections.clinical,
237
- fields: ['allergies_and_alerts', 'insurance_plan', 'chart_summary', planCountOnPatient],
551
+ section: patientClinicalSection,
552
+ fields: [
553
+ patientAllergiesField,
554
+ patientInsuranceField,
555
+ patientChartNotesField,
556
+ planCountOnPatient,
557
+ ],
238
558
  },
239
559
  ],
240
560
  },
@@ -245,7 +565,7 @@ defineTypedPageLayout(patient, {
245
565
  visibilityConditions: {},
246
566
  });
247
567
 
248
- defineTypedPageLayout(provider, {
568
+ new CustomObjectPageLayout(providerObj, {
249
569
  apiName: 'default',
250
570
  name: 'Provider',
251
571
  layoutId: 'layout_dental_provider',
@@ -259,12 +579,12 @@ defineTypedPageLayout(provider, {
259
579
  {
260
580
  name: 'Booking',
261
581
  type: 'fields_section',
262
- section: provider.sections.provider,
582
+ section: providerSection,
263
583
  fields: [
264
- { field: 'name', editable: true },
265
- 'provider_status',
266
- 'booking_status',
267
- 'next_available_days',
584
+ { field: providerNameField, editable: true },
585
+ providerStatusField,
586
+ providerBookingStatusField,
587
+ providerNextAvailableDaysField,
268
588
  ],
269
589
  },
270
590
  ],
@@ -276,7 +596,7 @@ defineTypedPageLayout(provider, {
276
596
  visibilityConditions: {},
277
597
  });
278
598
 
279
- defineTypedPageLayout(operatory, {
599
+ new CustomObjectPageLayout(operatoryObj, {
280
600
  apiName: 'default',
281
601
  name: 'Operatory',
282
602
  layoutId: 'layout_dental_operatory',
@@ -290,8 +610,8 @@ defineTypedPageLayout(operatory, {
290
610
  {
291
611
  name: 'Room',
292
612
  type: 'fields_section',
293
- section: operatory.sections.operatory,
294
- fields: [{ field: 'name', editable: true }, 'room_code', apptCountOnOperatory],
613
+ section: operatorySection,
614
+ fields: [{ field: opNameField, editable: true }, opCodeField, apptCountOnOperatory],
295
615
  },
296
616
  ],
297
617
  },
@@ -302,22 +622,23 @@ defineTypedPageLayout(operatory, {
302
622
  visibilityConditions: {},
303
623
  });
304
624
 
305
- defineTypedCustomObjectActionFromFunctionFile(manifest, appointment, {
625
+ const completeVisitFn = new ManifestFunction(manifest, {
626
+ apiName: 'dental_complete_visit_fn',
627
+ name: 'completeVisit',
628
+ description: 'Detail-view action that completes an appointment and drafts follow-up treatment',
629
+ code: fs.readFileSync(path.join(__dirname, 'functions', 'complete-visit.ts'), 'utf-8'),
630
+ dependencies: { '@rippling/rippling-sdk': '^0.2.0-alpha.65' },
631
+ isAsync: false,
632
+ });
633
+
634
+ new CustomObjectAction(apptObj, {
306
635
  actionId: 'action_dental_complete_visit',
307
636
  name: 'Complete visit',
637
+ function: completeVisitFn,
308
638
  visibilityPreferences: ['DETAIL_VIEW'],
309
- function: {
310
- apiName: 'dental_complete_visit_fn',
311
- name: 'completeVisit',
312
- description: 'Detail-view action that completes an appointment and drafts follow-up treatment',
313
- codeDirectory: path.join(__dirname, 'functions'),
314
- codeFilename: 'complete-visit.ts',
315
- dependencies: { '@rippling/rippling-sdk': '^0.2.0-alpha.65' },
316
- isAsync: false,
317
- },
318
639
  });
319
640
 
320
- defineTypedPageLayout(appointment, {
641
+ new CustomObjectPageLayout(apptObj, {
321
642
  apiName: 'default',
322
643
  name: 'Appointment',
323
644
  layoutId: 'layout_dental_appointment',
@@ -331,20 +652,20 @@ defineTypedPageLayout(appointment, {
331
652
  {
332
653
  name: 'Chair & schedule',
333
654
  type: 'fields_section',
334
- section: appointment.sections.operatory_and_time,
335
- fields: [{ field: 'name', editable: true }, 'operatory_ref', 'start_time', 'duration_minutes'],
655
+ section: apptOperatorySection,
656
+ fields: [{ field: 'name', editable: true }, apptOperatoryRef, apptStartField, apptDurationMins],
336
657
  },
337
658
  {
338
659
  name: 'Patient & status',
339
660
  type: 'fields_section',
340
- section: appointment.sections.patient_and_visit,
661
+ section: apptPatientSection,
341
662
  fields: [
342
- 'patient_ref',
343
- 'provider_ref',
344
- 'visit_type',
345
- 'appointment_status',
346
- 'board_label',
347
- 'visit_notes',
663
+ apptPatientRef,
664
+ apptProviderRef,
665
+ apptVisitTypeField,
666
+ apptStatusField,
667
+ apptBoardLabel,
668
+ apptClinicalNotes,
348
669
  ],
349
670
  },
350
671
  ],
@@ -357,7 +678,7 @@ defineTypedPageLayout(appointment, {
357
678
  visibilityConditions: {},
358
679
  });
359
680
 
360
- defineTypedPageLayout(treatmentPlan, {
681
+ new CustomObjectPageLayout(planObj, {
361
682
  apiName: 'default',
362
683
  name: 'Treatment plan',
363
684
  layoutId: 'layout_dental_treatment_plan',
@@ -371,19 +692,19 @@ defineTypedPageLayout(treatmentPlan, {
371
692
  {
372
693
  name: 'Patient',
373
694
  type: 'fields_section',
374
- section: treatmentPlan.sections.link,
375
- fields: ['plan_patient_ref'],
695
+ section: planLinkSection,
696
+ fields: [planPatientRef],
376
697
  },
377
698
  {
378
699
  name: 'Planned work',
379
700
  type: 'fields_section',
380
- section: treatmentPlan.sections.plan,
701
+ section: planBodySection,
381
702
  fields: [
382
- { field: 'name', editable: true },
383
- 'plan_status',
384
- 'target_completion',
385
- 'procedures_summary',
386
- 'fee_estimate_cents',
703
+ { field: planNameField, editable: true },
704
+ planStatusField,
705
+ planTargetField,
706
+ planProceduresField,
707
+ planFeeCents,
387
708
  ],
388
709
  },
389
710
  ],
@@ -395,12 +716,16 @@ defineTypedPageLayout(treatmentPlan, {
395
716
  visibilityConditions: {},
396
717
  });
397
718
 
398
- // ── SDUI object-list tabs ─────────────────────────────────────────────────
719
+ // ── SDUI object-list tabs ───────────────────────────────────────────────────
399
720
  const sduiObjectListDependencies = {
400
721
  '@rippling/rippling-sdk': '^0.2.0-alpha.65',
401
722
  '@rippling/pebble-sdui-web': '^0.9.2',
402
723
  };
403
724
 
725
+ function loadFunctionCode(filename: string): string {
726
+ return fs.readFileSync(path.join(__dirname, 'functions', filename), 'utf-8');
727
+ }
728
+
404
729
  function createObjectListPage(props: {
405
730
  codeFilename: string;
406
731
  functionApiName: string;
@@ -409,17 +734,20 @@ function createObjectListPage(props: {
409
734
  pageId: string;
410
735
  pageName: string;
411
736
  }): SduiPage {
412
- return defineSduiPageFromFunctionFile(manifest, {
737
+ const listFn = new ManifestFunction(manifest, {
413
738
  apiName: props.functionApiName,
414
739
  name: props.functionName,
415
740
  description: props.functionDescription,
416
- codeDirectory: path.join(__dirname, 'functions'),
417
- codeFilename: props.codeFilename,
741
+ code: loadFunctionCode(props.codeFilename),
418
742
  dependencies: sduiObjectListDependencies,
419
743
  isAsync: false,
420
- pageId: props.pageId,
421
- pageName: props.pageName,
422
- }).page;
744
+ });
745
+
746
+ return new SduiPage(manifest, {
747
+ sduiPageId: props.pageId,
748
+ name: props.pageName,
749
+ function: listFn,
750
+ });
423
751
  }
424
752
 
425
753
  const patientListPage = createObjectListPage({