@hyperscale0/udl 2.6.0 → 3.0.0

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 (213) hide show
  1. package/CHANGELOG.md +2 -322
  2. package/LICENSING.md +1 -2
  3. package/README.md +3 -114
  4. package/TRADEMARKS.md +2 -2
  5. package/dist/diagnostics.d.ts +21 -201
  6. package/dist/diagnostics.d.ts.map +1 -1
  7. package/dist/diagnostics.js +29 -193
  8. package/dist/diagnostics.js.map +1 -1
  9. package/dist/evolution.d.ts +3 -132
  10. package/dist/evolution.d.ts.map +1 -1
  11. package/dist/evolution.js +29 -633
  12. package/dist/evolution.js.map +1 -1
  13. package/dist/finance.d.ts +5 -72
  14. package/dist/finance.d.ts.map +1 -1
  15. package/dist/finance.js +233 -737
  16. package/dist/finance.js.map +1 -1
  17. package/dist/index.d.ts +7 -18
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +7 -12
  20. package/dist/index.js.map +1 -1
  21. package/dist/instrument-references.d.ts.map +1 -1
  22. package/dist/instrument-references.js +3 -2
  23. package/dist/instrument-references.js.map +1 -1
  24. package/dist/schema.d.ts +2079 -4564
  25. package/dist/schema.d.ts.map +1 -1
  26. package/dist/schema.js +270 -1609
  27. package/dist/schema.js.map +1 -1
  28. package/dist/validation.d.ts +8 -104
  29. package/dist/validation.d.ts.map +1 -1
  30. package/dist/validation.js +653 -3271
  31. package/dist/validation.js.map +1 -1
  32. package/docs/README.md +147 -14
  33. package/package.json +7 -11
  34. package/spec/README.md +151 -164
  35. package/spec/darb.udl.json +249 -0
  36. package/spec/udl.schema.json +4104 -3202
  37. package/src/diagnostics.ts +51 -246
  38. package/src/evolution.ts +39 -1045
  39. package/src/finance.ts +287 -1127
  40. package/src/index.ts +18 -142
  41. package/src/instrument-references.ts +3 -2
  42. package/src/schema.ts +285 -1843
  43. package/src/validation.ts +870 -5611
  44. package/conformance/README.md +0 -82
  45. package/conformance/evolution/action-contract.expected.json +0 -10
  46. package/conformance/evolution/action-contract.live.udl +0 -44
  47. package/conformance/evolution/action-contract.next.udl +0 -45
  48. package/conformance/evolution/product-identity.expected.json +0 -10
  49. package/conformance/evolution/product-identity.live.udl +0 -55
  50. package/conformance/evolution/product-identity.next.udl +0 -55
  51. package/conformance/evolution/version-required.expected.json +0 -10
  52. package/conformance/evolution/version-required.live.udl +0 -55
  53. package/conformance/evolution/version-required.next.udl +0 -58
  54. package/conformance/invalid/action-without-transition.expected.json +0 -10
  55. package/conformance/invalid/action-without-transition.udl +0 -60
  56. package/conformance/invalid/agent-description-too-long.expected.json +0 -10
  57. package/conformance/invalid/agent-description-too-long.udl +0 -57
  58. package/conformance/invalid/blank-title.expected.json +0 -10
  59. package/conformance/invalid/blank-title.udl +0 -54
  60. package/conformance/invalid/call-binds-results.expected.json +0 -10
  61. package/conformance/invalid/call-binds-results.udl +0 -314
  62. package/conformance/invalid/call-unknown-action.expected.json +0 -10
  63. package/conformance/invalid/call-unknown-action.udl +0 -314
  64. package/conformance/invalid/composition-dial-duplicate-key.expected.json +0 -10
  65. package/conformance/invalid/composition-dial-duplicate-key.udl +0 -73
  66. package/conformance/invalid/depth-budget.expected.json +0 -10
  67. package/conformance/invalid/depth-budget.udl +0 -49
  68. package/conformance/invalid/duplicate-subject.expected.json +0 -10
  69. package/conformance/invalid/duplicate-subject.udl +0 -230
  70. package/conformance/invalid/forged-effects.expected.json +0 -10
  71. package/conformance/invalid/forged-effects.udl +0 -76
  72. package/conformance/invalid/format-version.expected.json +0 -10
  73. package/conformance/invalid/format-version.udl +0 -54
  74. package/conformance/invalid/instrument-id-not-snake-case.expected.json +0 -10
  75. package/conformance/invalid/instrument-id-not-snake-case.udl +0 -54
  76. package/conformance/invalid/invalid-aggregate-gate-shape.expected.json +0 -10
  77. package/conformance/invalid/invalid-aggregate-gate-shape.udl +0 -1819
  78. package/conformance/invalid/invalid-check-duration.expected.json +0 -10
  79. package/conformance/invalid/invalid-check-duration.udl +0 -219
  80. package/conformance/invalid/invalid-dial-anchor.expected.json +0 -10
  81. package/conformance/invalid/invalid-dial-anchor.udl +0 -219
  82. package/conformance/invalid/invalid-exception-parent-ref.expected.json +0 -10
  83. package/conformance/invalid/invalid-exception-parent-ref.udl +0 -2487
  84. package/conformance/invalid/invalid-exposure-shape.expected.json +0 -10
  85. package/conformance/invalid/invalid-exposure-shape.udl +0 -1819
  86. package/conformance/invalid/invalid-journeys.expected.json +0 -10
  87. package/conformance/invalid/invalid-journeys.udl +0 -77
  88. package/conformance/invalid/invalid-remainder.expected.json +0 -10
  89. package/conformance/invalid/invalid-remainder.udl +0 -220
  90. package/conformance/invalid/invalid-schema-keyword.expected.json +0 -10
  91. package/conformance/invalid/invalid-schema-keyword.udl +0 -220
  92. package/conformance/invalid/invalid-utf8.expected.json +0 -10
  93. package/conformance/invalid/invalid-utf8.udl +0 -1
  94. package/conformance/invalid/leaf-effect-mismatch.expected.json +0 -10
  95. package/conformance/invalid/leaf-effect-mismatch.udl +0 -314
  96. package/conformance/invalid/malformed-json.expected.json +0 -10
  97. package/conformance/invalid/malformed-json.udl +0 -1
  98. package/conformance/invalid/missing-create-action.expected.json +0 -10
  99. package/conformance/invalid/missing-create-action.udl +0 -48
  100. package/conformance/invalid/missing-exception-amount-field.expected.json +0 -10
  101. package/conformance/invalid/missing-exception-amount-field.udl +0 -2487
  102. package/conformance/invalid/missing-exception-contract.expected.json +0 -14
  103. package/conformance/invalid/missing-exception-contract.udl +0 -2523
  104. package/conformance/invalid/missing-exception-reason-field.expected.json +0 -10
  105. package/conformance/invalid/missing-exception-reason-field.udl +0 -2487
  106. package/conformance/invalid/not-an-object.expected.json +0 -10
  107. package/conformance/invalid/not-an-object.udl +0 -1
  108. package/conformance/invalid/payout-reconcile-not-a-bank-debit.expected.json +0 -10
  109. package/conformance/invalid/payout-reconcile-not-a-bank-debit.udl +0 -259
  110. package/conformance/invalid/piece-plan-without-partition.expected.json +0 -10
  111. package/conformance/invalid/piece-plan-without-partition.udl +0 -305
  112. package/conformance/invalid/private-action-independent-approval.expected.json +0 -10
  113. package/conformance/invalid/private-action-independent-approval.udl +0 -314
  114. package/conformance/invalid/quote-freeze-set-incomplete.expected.json +0 -10
  115. package/conformance/invalid/quote-freeze-set-incomplete.udl +0 -261
  116. package/conformance/invalid/quote-named-reference-gate.expected.json +0 -10
  117. package/conformance/invalid/quote-named-reference-gate.udl +0 -50
  118. package/conformance/invalid/reconcile-named-reference-gate.expected.json +0 -10
  119. package/conformance/invalid/reconcile-named-reference-gate.udl +0 -50
  120. package/conformance/invalid/unfund-order-not-reversed.expected.json +0 -10
  121. package/conformance/invalid/unfund-order-not-reversed.udl +0 -314
  122. package/conformance/invalid/unknown-key.expected.json +0 -10
  123. package/conformance/invalid/unknown-key.udl +0 -55
  124. package/conformance/invalid/unknown-reference-gate-field.expected.json +0 -10
  125. package/conformance/invalid/unknown-reference-gate-field.udl +0 -1819
  126. package/conformance/invalid/unknown-required-field.expected.json +0 -10
  127. package/conformance/invalid/unknown-required-field.udl +0 -220
  128. package/conformance/invalid/unreachable-state.expected.json +0 -10
  129. package/conformance/invalid/unreachable-state.udl +0 -55
  130. package/conformance/invalid/wrong-exception-amount-field.expected.json +0 -10
  131. package/conformance/invalid/wrong-exception-amount-field.udl +0 -2487
  132. package/conformance/invalid/wrong-exception-reason-field.expected.json +0 -10
  133. package/conformance/invalid/wrong-exception-reason-field.udl +0 -2487
  134. package/conformance/valid/agent-description.expected.json +0 -6
  135. package/conformance/valid/agent-description.udl +0 -66
  136. package/conformance/valid/attested.expected.json +0 -6
  137. package/conformance/valid/attested.udl +0 -251
  138. package/conformance/valid/cards.expected.json +0 -6
  139. package/conformance/valid/cards.udl +0 -1579
  140. package/conformance/valid/commerce-escrow.expected.json +0 -6
  141. package/conformance/valid/commerce-escrow.udl +0 -1512
  142. package/conformance/valid/compiled-crowdfunding.expected.json +0 -6
  143. package/conformance/valid/compiled-crowdfunding.udl +0 -1843
  144. package/conformance/valid/compiled-watch-club.expected.json +0 -6
  145. package/conformance/valid/compiled-watch-club.udl +0 -2486
  146. package/conformance/valid/complete-contract.expected.json +0 -6
  147. package/conformance/valid/complete-contract.udl +0 -218
  148. package/conformance/valid/effect-signatures.expected.json +0 -6
  149. package/conformance/valid/effect-signatures.udl +0 -75
  150. package/conformance/valid/hand-edited.expected.json +0 -6
  151. package/conformance/valid/hand-edited.udl +0 -1
  152. package/conformance/valid/insured-car-marketplace.expected.json +0 -6
  153. package/conformance/valid/insured-car-marketplace.udl +0 -1050
  154. package/conformance/valid/insured-travel.expected.json +0 -6
  155. package/conformance/valid/insured-travel.udl +0 -3469
  156. package/conformance/valid/minimal.expected.json +0 -6
  157. package/conformance/valid/minimal.udl +0 -62
  158. package/conformance/valid/piece-plan-calls.expected.json +0 -6
  159. package/conformance/valid/piece-plan-calls.udl +0 -314
  160. package/conformance/valid/protection.expected.json +0 -6
  161. package/conformance/valid/protection.udl +0 -1551
  162. package/conformance/valid/string-escaping.expected.json +0 -6
  163. package/conformance/valid/string-escaping.udl +0 -54
  164. package/conformance/valid/vocabulary.expected.json +0 -6
  165. package/conformance/valid/vocabulary.udl +0 -2012
  166. package/dist/allocation.d.ts +0 -60
  167. package/dist/allocation.d.ts.map +0 -1
  168. package/dist/allocation.js +0 -177
  169. package/dist/allocation.js.map +0 -1
  170. package/dist/check-profiles.d.ts +0 -57
  171. package/dist/check-profiles.d.ts.map +0 -1
  172. package/dist/check-profiles.js +0 -62
  173. package/dist/check-profiles.js.map +0 -1
  174. package/dist/distribution.d.ts +0 -15
  175. package/dist/distribution.d.ts.map +0 -1
  176. package/dist/distribution.js +0 -49
  177. package/dist/distribution.js.map +0 -1
  178. package/dist/effects.d.ts +0 -58
  179. package/dist/effects.d.ts.map +0 -1
  180. package/dist/effects.js +0 -1126
  181. package/dist/effects.js.map +0 -1
  182. package/dist/reference.d.ts +0 -3
  183. package/dist/reference.d.ts.map +0 -1
  184. package/dist/reference.js +0 -28
  185. package/dist/reference.js.map +0 -1
  186. package/dist/vocabulary.d.ts +0 -23
  187. package/dist/vocabulary.d.ts.map +0 -1
  188. package/dist/vocabulary.js +0 -1052
  189. package/dist/vocabulary.js.map +0 -1
  190. package/docs/funding-custody.md +0 -165
  191. package/docs/guide/01-a-document.md +0 -37
  192. package/docs/guide/02-money-steps.md +0 -23
  193. package/docs/guide/03-laws.md +0 -18
  194. package/docs/guide/04-fees-and-remainder.md +0 -36
  195. package/docs/guide/05-checks-updates-dials.md +0 -7
  196. package/docs/guide/06-effects.md +0 -11
  197. package/docs/guide/07-evolution.md +0 -11
  198. package/docs/guide/08-implementing.md +0 -13
  199. package/docs/guide/09-schedules-and-allocation.md +0 -132
  200. package/docs/llms-full.txt +0 -2008
  201. package/docs/llms.txt +0 -14
  202. package/docs/piece-plans.md +0 -148
  203. package/docs/reference/canonical.md +0 -16
  204. package/docs/reference/clauses.md +0 -1585
  205. package/docs/reference/cli.md +0 -24
  206. package/docs/reference/diagnostics.md +0 -38
  207. package/skills/udl/SKILL.md +0 -28
  208. package/src/allocation.ts +0 -259
  209. package/src/check-profiles.ts +0 -80
  210. package/src/distribution.ts +0 -61
  211. package/src/effects.ts +0 -1920
  212. package/src/reference.ts +0 -31
  213. package/src/vocabulary.ts +0 -1635
@@ -1,1819 +0,0 @@
1
- {
2
- "instruments": [
3
- {
4
- "actionOrder": [
5
- "create",
6
- "fund_piece_1",
7
- "accept_commitment",
8
- "cancel",
9
- "abandon"
10
- ],
11
- "actions": {
12
- "abandon": {
13
- "moves": [],
14
- "publicAction": "abandonLenderCommitment",
15
- "requiresDrainedAccount": {
16
- "path": "refs.escrowAccountId"
17
- },
18
- "steps": [],
19
- "summary": "Abandon the settlement before any money is held"
20
- },
21
- "accept_commitment": {
22
- "effects": {
23
- "decides": [
24
- {
25
- "signature": "decides.tenant_port",
26
- "source": "port"
27
- }
28
- ],
29
- "moves": [
30
- {
31
- "signature": "moves.transfer.internal",
32
- "source": "moves[0]"
33
- }
34
- ]
35
- },
36
- "input": {
37
- "additionalProperties": false,
38
- "properties": {
39
- "acceptanceReference": {
40
- "description": "Required decision reference retained in the operation receipt",
41
- "maxLength": 180,
42
- "minLength": 1,
43
- "type": "string"
44
- }
45
- },
46
- "required": [
47
- "acceptanceReference"
48
- ],
49
- "type": "object"
50
- },
51
- "moves": [
52
- {
53
- "bind": {
54
- "amount": {
55
- "from": "instance",
56
- "path": "fields.committedAmount"
57
- },
58
- "currency": {
59
- "from": "instance",
60
- "path": "fields.currency"
61
- },
62
- "destinationAccountId": {
63
- "from": "instance",
64
- "path": "fields.servicingPoolAccountId"
65
- },
66
- "metadata.instrumentId": {
67
- "from": "const",
68
- "value": "lender_commitment"
69
- },
70
- "metadata.instrumentInstanceId": {
71
- "from": "instance",
72
- "path": "instrumentInstanceId"
73
- },
74
- "metadata.phase": {
75
- "from": "const",
76
- "value": "accept_commitment"
77
- },
78
- "productId": {
79
- "from": "instance",
80
- "path": "productId"
81
- },
82
- "sourceAccountId": {
83
- "from": "instance",
84
- "path": "refs.escrowAccountId"
85
- }
86
- },
87
- "capture": {
88
- "acceptCommitmentTransferTransferId": "transferId"
89
- },
90
- "key": "transfer",
91
- "operation": "internal_transfer.create"
92
- }
93
- ],
94
- "port": {
95
- "allowedParties": [
96
- "beneficiary"
97
- ]
98
- },
99
- "publicAction": "acceptCommitmentLenderCommitment",
100
- "steps": [],
101
- "summary": "Confirm through accept_commitment and start the release payout"
102
- },
103
- "cancel": {
104
- "effects": {
105
- "moves": [
106
- {
107
- "signature": "moves.transfer.internal",
108
- "source": "moves[0]"
109
- }
110
- ]
111
- },
112
- "moves": [
113
- {
114
- "bind": {
115
- "amount": {
116
- "from": "instance",
117
- "path": "fields.committedAmount"
118
- },
119
- "currency": {
120
- "from": "instance",
121
- "path": "fields.currency"
122
- },
123
- "destinationAccountId": {
124
- "from": "instance",
125
- "path": "fields.lenderAccountId"
126
- },
127
- "metadata.instrumentId": {
128
- "from": "const",
129
- "value": "lender_commitment"
130
- },
131
- "metadata.instrumentInstanceId": {
132
- "from": "instance",
133
- "path": "instrumentInstanceId"
134
- },
135
- "metadata.phase": {
136
- "from": "const",
137
- "value": "cancel"
138
- },
139
- "productId": {
140
- "from": "instance",
141
- "path": "productId"
142
- },
143
- "sourceAccountId": {
144
- "from": "instance",
145
- "path": "refs.escrowAccountId"
146
- }
147
- },
148
- "capture": {
149
- "cancelTransferTransferId": "transferId"
150
- },
151
- "key": "transfer",
152
- "operation": "internal_transfer.create"
153
- }
154
- ],
155
- "publicAction": "cancelLenderCommitment",
156
- "steps": [],
157
- "summary": "Cancel the settlement and start the unwind"
158
- },
159
- "create": {
160
- "moves": [],
161
- "publicAction": "createLenderCommitment",
162
- "steps": [
163
- {
164
- "bind": {
165
- "currency": {
166
- "from": "instance",
167
- "path": "fields.currency"
168
- },
169
- "owner.id": {
170
- "from": "instance",
171
- "path": "productId"
172
- },
173
- "owner.type": {
174
- "from": "const",
175
- "value": "product"
176
- },
177
- "productId": {
178
- "from": "instance",
179
- "path": "productId"
180
- },
181
- "role": {
182
- "from": "const",
183
- "value": "product_escrow"
184
- }
185
- },
186
- "capture": {
187
- "escrowAccountId": "accountId"
188
- },
189
- "operation": "account.escrow.provision"
190
- }
191
- ],
192
- "summary": "Create a lender commitment settlement"
193
- },
194
- "fund_piece_1": {
195
- "effects": {
196
- "moves": [
197
- {
198
- "signature": "moves.collection.pay_in",
199
- "source": "moves[0]"
200
- }
201
- ]
202
- },
203
- "moves": [
204
- {
205
- "bind": {
206
- "amount": {
207
- "from": "instance",
208
- "path": "fields.committedAmount"
209
- },
210
- "currency": {
211
- "from": "instance",
212
- "path": "fields.currency"
213
- },
214
- "destinationAccountId": {
215
- "from": "instance",
216
- "path": "refs.escrowAccountId"
217
- },
218
- "metadata.instrumentId": {
219
- "from": "const",
220
- "value": "lender_commitment"
221
- },
222
- "metadata.instrumentInstanceId": {
223
- "from": "instance",
224
- "path": "instrumentInstanceId"
225
- },
226
- "metadata.phase": {
227
- "from": "const",
228
- "value": "fund_piece_1"
229
- },
230
- "productId": {
231
- "from": "instance",
232
- "path": "productId"
233
- },
234
- "sourceAccountId": {
235
- "from": "instance",
236
- "path": "fields.lenderAccountId"
237
- }
238
- },
239
- "capture": {
240
- "fundPiece1TransferTransferId": "transferId"
241
- },
242
- "key": "transfer",
243
- "operation": "internal_transfer.create"
244
- }
245
- ],
246
- "publicAction": "fundPiece1LenderCommitment",
247
- "steps": [],
248
- "summary": "Fund piece 1 of the held amount into escrow"
249
- }
250
- },
251
- "description": "Held payment: the lender funds committedAmount into this settlement's own escrow; servicing pool confirms through accept_commitment to release",
252
- "fields": {
253
- "committedAmount": {
254
- "description": "The held amount in SAR minor units, funded and paid out whole",
255
- "pattern": "^[1-9][0-9]{0,17}$",
256
- "type": "string"
257
- },
258
- "currency": {
259
- "description": "ISO 4217 currency code",
260
- "maxLength": 3,
261
- "minLength": 3,
262
- "pattern": "^[A-Z]{3}$",
263
- "type": "string"
264
- },
265
- "lenderAccountId": {
266
- "description": "The lender account",
267
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
268
- "type": "string",
269
- "x-hyperscale-reference-filter": {
270
- "column": "role",
271
- "values": [
272
- "customer_balance"
273
- ]
274
- }
275
- },
276
- "platformAccountId": {
277
- "description": "The product fee collection account",
278
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
279
- "type": "string",
280
- "x-hyperscale-fee-collection-port": true,
281
- "x-hyperscale-reference-filter": {
282
- "column": "role",
283
- "values": [
284
- "customer_balance",
285
- "product_revenue"
286
- ]
287
- }
288
- },
289
- "servicingPoolAccountId": {
290
- "description": "The servicing pool account",
291
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
292
- "type": "string",
293
- "x-hyperscale-reference-filter": {
294
- "column": "role",
295
- "values": [
296
- "customer_balance"
297
- ]
298
- }
299
- }
300
- },
301
- "id": "lender_commitment",
302
- "idPrefix": "lc",
303
- "lifecycle": {
304
- "initial": "created",
305
- "states": [
306
- "created",
307
- "funded",
308
- "released",
309
- "cancelled",
310
- "abandoned"
311
- ],
312
- "transitions": {
313
- "abandon": {
314
- "from": [
315
- "created"
316
- ],
317
- "to": "abandoned"
318
- },
319
- "accept_commitment": {
320
- "from": [
321
- "funded"
322
- ],
323
- "to": "released"
324
- },
325
- "cancel": {
326
- "from": [
327
- "funded"
328
- ],
329
- "to": "cancelled"
330
- },
331
- "fund_piece_1": {
332
- "from": [
333
- "created"
334
- ],
335
- "to": "funded"
336
- }
337
- }
338
- },
339
- "parties": {
340
- "beneficiary": "servicingPoolAccountId",
341
- "payer": "lenderAccountId"
342
- },
343
- "required": [
344
- "lenderAccountId",
345
- "servicingPoolAccountId",
346
- "platformAccountId",
347
- "committedAmount",
348
- "currency"
349
- ],
350
- "summary": "Escrow-held payment from lender to servicing pool",
351
- "title": "Lender commitment"
352
- },
353
- {
354
- "actionOrder": [
355
- "create",
356
- "approve",
357
- "advance",
358
- "collect_installment_1",
359
- "mark_installment_1_delinquent",
360
- "collect_installment_2",
361
- "mark_installment_2_delinquent",
362
- "complete",
363
- "write_off"
364
- ],
365
- "actions": {
366
- "advance": {
367
- "effects": {
368
- "moves": [
369
- {
370
- "signature": "moves.transfer.internal",
371
- "source": "moves[0]"
372
- }
373
- ]
374
- },
375
- "moves": [
376
- {
377
- "bind": {
378
- "amount": {
379
- "from": "instance",
380
- "path": "fields.principalAmount"
381
- },
382
- "currency": {
383
- "from": "instance",
384
- "path": "fields.currency"
385
- },
386
- "destinationAccountId": {
387
- "from": "instance",
388
- "path": "fields.borrowerProceedsAccountId"
389
- },
390
- "metadata.instrumentId": {
391
- "from": "const",
392
- "value": "borrower_loan"
393
- },
394
- "metadata.instrumentInstanceId": {
395
- "from": "instance",
396
- "path": "instrumentInstanceId"
397
- },
398
- "metadata.phase": {
399
- "from": "const",
400
- "value": "advance"
401
- },
402
- "productId": {
403
- "from": "instance",
404
- "path": "productId"
405
- },
406
- "sourceAccountId": {
407
- "from": "instance",
408
- "path": "fields.servicingPoolAccountId"
409
- }
410
- },
411
- "capture": {
412
- "advanceAdvanceTransferId": "transferId"
413
- },
414
- "key": "advance",
415
- "operation": "internal_transfer.create"
416
- }
417
- ],
418
- "publicAction": "advanceBorrowerLoan",
419
- "steps": [],
420
- "summary": "Advance the principal to the borrower proceeds; the internal ledger receipt is the confirmation"
421
- },
422
- "approve": {
423
- "moves": [],
424
- "publicAction": "approveBorrowerLoan",
425
- "steps": [],
426
- "summary": "Approve the immutable principal partition and stored anchors"
427
- },
428
- "collect_installment_1": {
429
- "due": {
430
- "field": "firstRepaymentDueAt"
431
- },
432
- "effects": {
433
- "reads": [
434
- {
435
- "signature": "reads.requires_aggregate",
436
- "source": "requiresAggregate"
437
- }
438
- ],
439
- "schedules": [
440
- {
441
- "signature": "schedules.due",
442
- "source": "due"
443
- }
444
- ]
445
- },
446
- "moves": [],
447
- "requiresAggregate": [
448
- {
449
- "check": {
450
- "amountField": "amount",
451
- "kind": "sum_exactly",
452
- "targetField": "installment1Amount"
453
- },
454
- "instrumentId": "borrower_loan_installment_1_payment",
455
- "over": "children",
456
- "refField": "borrowerLoanId",
457
- "statuses": [
458
- "paid"
459
- ]
460
- }
461
- ],
462
- "steps": [],
463
- "summary": "Close delinquent installment 1 after linked payments reach its stored amount"
464
- },
465
- "collect_installment_2": {
466
- "due": {
467
- "field": "firstRepaymentDueAt",
468
- "offset": "P30D"
469
- },
470
- "effects": {
471
- "reads": [
472
- {
473
- "signature": "reads.requires_aggregate",
474
- "source": "requiresAggregate"
475
- }
476
- ],
477
- "schedules": [
478
- {
479
- "signature": "schedules.due",
480
- "source": "due"
481
- }
482
- ]
483
- },
484
- "moves": [],
485
- "requiresAggregate": [
486
- {
487
- "check": {
488
- "amountField": "amount",
489
- "kind": "sum_exactly",
490
- "targetField": "installment2Amount"
491
- },
492
- "instrumentId": "borrower_loan_installment_2_payment",
493
- "over": "children",
494
- "refField": "borrowerLoanId",
495
- "statuses": [
496
- "paid"
497
- ]
498
- }
499
- ],
500
- "steps": [],
501
- "summary": "Close delinquent installment 2 after linked payments reach its stored amount"
502
- },
503
- "complete": {
504
- "due": {
505
- "field": "firstRepaymentDueAt",
506
- "offset": "P30D"
507
- },
508
- "effects": {
509
- "reads": [
510
- {
511
- "signature": "reads.requires_aggregate",
512
- "source": "requiresAggregate"
513
- }
514
- ],
515
- "schedules": [
516
- {
517
- "signature": "schedules.due",
518
- "source": "due"
519
- }
520
- ]
521
- },
522
- "moves": [],
523
- "requiresAggregate": [
524
- {
525
- "check": {
526
- "amountField": "amount",
527
- "kind": "sum_exactly",
528
- "targetField": "installment1Amount"
529
- },
530
- "instrumentId": "borrower_loan_installment_1_payment",
531
- "over": "children",
532
- "refField": "borrowerLoanId",
533
- "statuses": [
534
- "paid"
535
- ]
536
- },
537
- {
538
- "check": {
539
- "amountField": "amount",
540
- "kind": "sum_exactly",
541
- "targetField": "installment2Amount"
542
- },
543
- "instrumentId": "borrower_loan_installment_2_payment",
544
- "over": "children",
545
- "refField": "borrowerLoanId",
546
- "statuses": [
547
- "paid"
548
- ]
549
- }
550
- ],
551
- "steps": [],
552
- "summary": "Close the obligation only after every stored anchor is paid exactly"
553
- },
554
- "create": {
555
- "effects": {
556
- "moves": [
557
- {
558
- "signature": "moves.transfer.internal",
559
- "source": "moves[0]"
560
- }
561
- ]
562
- },
563
- "moves": [
564
- {
565
- "bind": {
566
- "amount": {
567
- "from": "instance",
568
- "path": "fields.platformFee"
569
- },
570
- "currency": {
571
- "from": "instance",
572
- "path": "fields.currency"
573
- },
574
- "destinationAccountId": {
575
- "from": "instance",
576
- "path": "fields.platformAccountId"
577
- },
578
- "metadata.instrumentId": {
579
- "from": "const",
580
- "value": "borrower_loan"
581
- },
582
- "metadata.instrumentInstanceId": {
583
- "from": "instance",
584
- "path": "instrumentInstanceId"
585
- },
586
- "metadata.phase": {
587
- "from": "const",
588
- "value": "create"
589
- },
590
- "productId": {
591
- "from": "instance",
592
- "path": "productId"
593
- },
594
- "sourceAccountId": {
595
- "from": "instance",
596
- "path": "fields.borrowerAccountId"
597
- }
598
- },
599
- "capture": {
600
- "createDerivedAmountTransferId": "transferId"
601
- },
602
- "key": "derived_amount",
603
- "operation": "internal_transfer.create"
604
- }
605
- ],
606
- "publicAction": "createBorrowerLoan",
607
- "steps": [],
608
- "summary": "Create a borrower loan obligation"
609
- },
610
- "mark_installment_1_delinquent": {
611
- "due": {
612
- "field": "firstRepaymentDueAt"
613
- },
614
- "effects": {
615
- "reads": [
616
- {
617
- "signature": "reads.requires_aggregate",
618
- "source": "requiresAggregate"
619
- }
620
- ],
621
- "schedules": [
622
- {
623
- "signature": "schedules.due",
624
- "source": "due"
625
- }
626
- ]
627
- },
628
- "moves": [],
629
- "requiresAggregate": [
630
- {
631
- "check": {
632
- "amountField": "amount",
633
- "kind": "sum_below",
634
- "targetField": "installment1Amount"
635
- },
636
- "instrumentId": "borrower_loan_installment_1_payment",
637
- "over": "children",
638
- "refField": "borrowerLoanId",
639
- "statuses": [
640
- "paid"
641
- ]
642
- }
643
- ],
644
- "setsAt": {
645
- "field": "installment1DelinquentAfter",
646
- "marker": true,
647
- "offset": "PT1S"
648
- },
649
- "steps": [],
650
- "summary": "Mark installment 1 delinquent only when its due anchor is unmet"
651
- },
652
- "mark_installment_2_delinquent": {
653
- "due": {
654
- "field": "firstRepaymentDueAt",
655
- "offset": "P30D"
656
- },
657
- "effects": {
658
- "reads": [
659
- {
660
- "signature": "reads.requires_aggregate",
661
- "source": "requiresAggregate"
662
- }
663
- ],
664
- "schedules": [
665
- {
666
- "signature": "schedules.due",
667
- "source": "due"
668
- }
669
- ]
670
- },
671
- "moves": [],
672
- "requiresAggregate": [
673
- {
674
- "check": {
675
- "amountField": "amount",
676
- "kind": "sum_below",
677
- "targetField": "installment2Amount"
678
- },
679
- "instrumentId": "borrower_loan_installment_2_payment",
680
- "over": "children",
681
- "refField": "borrowerLoanId",
682
- "statuses": [
683
- "paid"
684
- ]
685
- }
686
- ],
687
- "setsAt": {
688
- "field": "installment2DelinquentAfter",
689
- "marker": true,
690
- "offset": "PT1S"
691
- },
692
- "steps": [],
693
- "summary": "Mark installment 2 delinquent only when its due anchor is unmet"
694
- },
695
- "write_off": {
696
- "moves": [],
697
- "publicAction": "writeOffBorrowerLoan",
698
- "steps": [],
699
- "summary": "Write off the remaining exposure without moving money"
700
- }
701
- },
702
- "aggregateInvariants": [
703
- {
704
- "childField": "amount",
705
- "childInstrumentId": "borrower_loan_installment_1_payment",
706
- "childRefField": "borrowerLoanId",
707
- "childStatuses": [
708
- "paid"
709
- ],
710
- "parentField": "installment1Amount"
711
- },
712
- {
713
- "childField": "amount",
714
- "childInstrumentId": "borrower_loan_installment_2_payment",
715
- "childRefField": "borrowerLoanId",
716
- "childStatuses": [
717
- "paid"
718
- ],
719
- "parentField": "installment2Amount"
720
- }
721
- ],
722
- "derivedAmounts": [
723
- {
724
- "field": "platformFee",
725
- "rounding": "floor",
726
- "rule": {
727
- "bps": 200,
728
- "kind": "percentage_of"
729
- },
730
- "sourceField": "principalAmount"
731
- }
732
- ],
733
- "description": "Installment obligation for borrower; borrower pays servicing pool against exact stored anchors",
734
- "fields": {
735
- "borrowerAccountId": {
736
- "description": "The borrower account",
737
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
738
- "type": "string",
739
- "x-hyperscale-reference-filter": {
740
- "column": "role",
741
- "values": [
742
- "customer_balance"
743
- ]
744
- }
745
- },
746
- "borrowerProceedsAccountId": {
747
- "description": "The borrower proceeds account",
748
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
749
- "type": "string",
750
- "x-hyperscale-reference-filter": {
751
- "column": "role",
752
- "values": [
753
- "customer_balance"
754
- ]
755
- }
756
- },
757
- "currency": {
758
- "description": "ISO 4217 currency code",
759
- "maxLength": 3,
760
- "minLength": 3,
761
- "pattern": "^[A-Z]{3}$",
762
- "type": "string"
763
- },
764
- "firstRepaymentDueAt": {
765
- "description": "Due date of the first installment; later anchors use fixed offsets of P30D",
766
- "format": "hyperscale-date-time",
767
- "type": "string"
768
- },
769
- "installment1Amount": {
770
- "description": "Stored amount for installment 1 of 2 (carries the integer-division remainder)",
771
- "pattern": "^[1-9][0-9]{0,17}$",
772
- "type": "string"
773
- },
774
- "installment1DelinquentAfter": {
775
- "description": "Machine-set marker proving installment 1 reached its stored due date while unpaid",
776
- "format": "hyperscale-date-time",
777
- "type": "string"
778
- },
779
- "installment2Amount": {
780
- "description": "Stored amount for installment 2 of 2",
781
- "pattern": "^[1-9][0-9]{0,17}$",
782
- "type": "string"
783
- },
784
- "installment2DelinquentAfter": {
785
- "description": "Machine-set marker proving installment 2 reached its stored due date while unpaid",
786
- "format": "hyperscale-date-time",
787
- "type": "string"
788
- },
789
- "platformAccountId": {
790
- "description": "The product fee collection account",
791
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
792
- "type": "string",
793
- "x-hyperscale-fee-collection-port": true,
794
- "x-hyperscale-reference-filter": {
795
- "column": "role",
796
- "values": [
797
- "customer_balance",
798
- "product_revenue"
799
- ]
800
- }
801
- },
802
- "platformFee": {
803
- "description": "Machine-computed 2% of principalAmount; callers never supply it",
804
- "pattern": "^[1-9][0-9]{0,17}$",
805
- "type": "string"
806
- },
807
- "principalAmount": {
808
- "description": "The principal in SAR minor units; the stored installment anchors partition it exactly",
809
- "pattern": "^[1-9][0-9]{0,17}$",
810
- "type": "string"
811
- },
812
- "servicingPoolAccountId": {
813
- "description": "The servicing pool account",
814
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
815
- "type": "string",
816
- "x-hyperscale-reference-filter": {
817
- "column": "role",
818
- "values": [
819
- "customer_balance"
820
- ]
821
- }
822
- }
823
- },
824
- "id": "borrower_loan",
825
- "idPrefix": "bl",
826
- "lifecycle": {
827
- "initial": "draft",
828
- "states": [
829
- "draft",
830
- "approved",
831
- "active",
832
- "installment_1_delinquent",
833
- "installment_2_delinquent",
834
- "written_off",
835
- "repaid"
836
- ],
837
- "transitions": {
838
- "advance": {
839
- "from": [
840
- "approved"
841
- ],
842
- "to": "active"
843
- },
844
- "approve": {
845
- "from": [
846
- "draft"
847
- ],
848
- "to": "approved"
849
- },
850
- "collect_installment_1": {
851
- "from": [
852
- "installment_1_delinquent",
853
- "installment_2_delinquent"
854
- ],
855
- "to": "active"
856
- },
857
- "collect_installment_2": {
858
- "from": [
859
- "installment_1_delinquent",
860
- "installment_2_delinquent"
861
- ],
862
- "to": "active"
863
- },
864
- "complete": {
865
- "from": [
866
- "active",
867
- "installment_1_delinquent",
868
- "installment_2_delinquent"
869
- ],
870
- "to": "repaid"
871
- },
872
- "mark_installment_1_delinquent": {
873
- "from": [
874
- "active",
875
- "installment_2_delinquent"
876
- ],
877
- "to": "installment_1_delinquent"
878
- },
879
- "mark_installment_2_delinquent": {
880
- "from": [
881
- "active",
882
- "installment_1_delinquent"
883
- ],
884
- "to": "installment_2_delinquent"
885
- },
886
- "write_off": {
887
- "from": [
888
- "draft",
889
- "approved",
890
- "active",
891
- "installment_1_delinquent",
892
- "installment_2_delinquent"
893
- ],
894
- "to": "written_off"
895
- }
896
- }
897
- },
898
- "parties": {
899
- "beneficiary": "borrowerProceedsAccountId"
900
- },
901
- "partitions": [
902
- {
903
- "pieceFields": [
904
- "installment1Amount",
905
- "installment2Amount"
906
- ],
907
- "totalField": "principalAmount"
908
- }
909
- ],
910
- "required": [
911
- "borrowerProceedsAccountId",
912
- "servicingPoolAccountId",
913
- "borrowerAccountId",
914
- "platformAccountId",
915
- "currency",
916
- "principalAmount",
917
- "firstRepaymentDueAt",
918
- "installment1Amount",
919
- "installment2Amount"
920
- ],
921
- "summary": "2-anchor obligation for borrower",
922
- "title": "Borrower loan"
923
- },
924
- {
925
- "actionOrder": [
926
- "create",
927
- "repay",
928
- "refund"
929
- ],
930
- "actions": {
931
- "create": {
932
- "effects": {
933
- "reads": [
934
- {
935
- "signature": "reads.requires_refs",
936
- "source": "requiresRefs"
937
- }
938
- ]
939
- },
940
- "moves": [],
941
- "publicAction": "createBorrowerLoanInstallment1Payment",
942
- "requiresRefs": [
943
- {
944
- "bind": {
945
- "borrowerAccountId": "fields.borrowerAccountId",
946
- "currency": "fields.currency",
947
- "servicingPoolAccountId": "fields.servicingPoolAccountId"
948
- },
949
- "field": "borrowerLoanId",
950
- "statuses": [
951
- "active",
952
- "installment_1_delinquent",
953
- "installment_2_delinquent"
954
- ]
955
- }
956
- ],
957
- "steps": [],
958
- "summary": "Create a payment record for installment 1"
959
- },
960
- "refund": {
961
- "effects": {
962
- "moves": [
963
- {
964
- "signature": "moves.transfer.internal",
965
- "source": "moves[0]"
966
- }
967
- ],
968
- "reads": [
969
- {
970
- "signature": "reads.requires_refs",
971
- "source": "requiresRefs"
972
- }
973
- ]
974
- },
975
- "moves": [
976
- {
977
- "bind": {
978
- "amount": {
979
- "from": "instance",
980
- "path": "fields.amount"
981
- },
982
- "currency": {
983
- "from": "instance",
984
- "path": "fields.currency"
985
- },
986
- "destinationAccountId": {
987
- "from": "instance",
988
- "path": "fields.borrowerAccountId"
989
- },
990
- "metadata.instrumentId": {
991
- "from": "const",
992
- "value": "borrower_loan_installment_1_payment"
993
- },
994
- "metadata.instrumentInstanceId": {
995
- "from": "instance",
996
- "path": "instrumentInstanceId"
997
- },
998
- "metadata.phase": {
999
- "from": "const",
1000
- "value": "refund"
1001
- },
1002
- "productId": {
1003
- "from": "instance",
1004
- "path": "productId"
1005
- },
1006
- "sourceAccountId": {
1007
- "from": "instance",
1008
- "path": "fields.servicingPoolAccountId"
1009
- }
1010
- },
1011
- "capture": {
1012
- "refundRefundTransferId": "transferId"
1013
- },
1014
- "key": "refund",
1015
- "operation": "internal_transfer.create"
1016
- }
1017
- ],
1018
- "publicAction": "refundBorrowerLoanInstallment1Payment",
1019
- "requiresRefs": [
1020
- {
1021
- "field": "borrowerLoanId",
1022
- "match": {
1023
- "fields.borrowerAccountId": "fields.borrowerAccountId",
1024
- "fields.currency": "fields.currency",
1025
- "fields.servicingPoolAccountId": "fields.servicingPoolAccountId"
1026
- },
1027
- "statuses": [
1028
- "active",
1029
- "installment_1_delinquent",
1030
- "installment_2_delinquent"
1031
- ]
1032
- }
1033
- ],
1034
- "steps": [],
1035
- "summary": "Refund this one stored installment 1 payment whole"
1036
- },
1037
- "repay": {
1038
- "effects": {
1039
- "moves": [
1040
- {
1041
- "signature": "moves.transfer.internal",
1042
- "source": "moves[0]"
1043
- }
1044
- ],
1045
- "reads": [
1046
- {
1047
- "signature": "reads.requires_refs",
1048
- "source": "requiresRefs"
1049
- }
1050
- ]
1051
- },
1052
- "moves": [
1053
- {
1054
- "bind": {
1055
- "amount": {
1056
- "from": "instance",
1057
- "path": "fields.amount"
1058
- },
1059
- "currency": {
1060
- "from": "instance",
1061
- "path": "fields.currency"
1062
- },
1063
- "destinationAccountId": {
1064
- "from": "instance",
1065
- "path": "fields.servicingPoolAccountId"
1066
- },
1067
- "metadata.instrumentId": {
1068
- "from": "const",
1069
- "value": "borrower_loan_installment_1_payment"
1070
- },
1071
- "metadata.instrumentInstanceId": {
1072
- "from": "instance",
1073
- "path": "instrumentInstanceId"
1074
- },
1075
- "metadata.phase": {
1076
- "from": "const",
1077
- "value": "repay"
1078
- },
1079
- "productId": {
1080
- "from": "instance",
1081
- "path": "productId"
1082
- },
1083
- "sourceAccountId": {
1084
- "from": "instance",
1085
- "path": "fields.borrowerAccountId"
1086
- }
1087
- },
1088
- "capture": {
1089
- "repayRepaymentTransferId": "transferId"
1090
- },
1091
- "key": "repayment",
1092
- "operation": "internal_transfer.create"
1093
- }
1094
- ],
1095
- "publicAction": "repayBorrowerLoanInstallment1Payment",
1096
- "requiresExposure": [
1097
- {
1098
- "amountField": "amount",
1099
- "anchorField": "borrowerLoanId",
1100
- "capField": "installment1Amount",
1101
- "capOnAnchor": true,
1102
- "childInstrumentId": 7,
1103
- "statuses": [
1104
- "paid"
1105
- ]
1106
- }
1107
- ],
1108
- "requiresRefs": [
1109
- {
1110
- "field": "borrowerLoanId",
1111
- "match": {
1112
- "fields.borrowerAccountId": "fields.borrowerAccountId",
1113
- "fields.currency": "fields.currency",
1114
- "fields.servicingPoolAccountId": "fields.servicingPoolAccountId"
1115
- },
1116
- "statuses": [
1117
- "active",
1118
- "installment_1_delinquent",
1119
- "installment_2_delinquent"
1120
- ]
1121
- }
1122
- ],
1123
- "steps": [],
1124
- "summary": "Pay a partial or full amount against installment 1"
1125
- }
1126
- },
1127
- "description": "One partial or full payment bound to installment 1 of borrower_loan; the operation name fixes the anchor and borrowerLoanId fixes the obligation",
1128
- "fields": {
1129
- "amount": {
1130
- "description": "Positive payment amount capped with its paid siblings at installment1Amount",
1131
- "pattern": "^[1-9][0-9]{0,17}$",
1132
- "type": "string"
1133
- },
1134
- "borrowerAccountId": {
1135
- "description": "The borrower account",
1136
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
1137
- "type": "string",
1138
- "x-hyperscale-reference-filter": {
1139
- "column": "role",
1140
- "values": [
1141
- "customer_balance"
1142
- ]
1143
- }
1144
- },
1145
- "borrowerLoanId": {
1146
- "description": "The exact borrower loan this payment belongs to",
1147
- "pattern": "^bl_(sandbox|live)_[a-z0-9]{8,64}$",
1148
- "type": "string"
1149
- },
1150
- "currency": {
1151
- "description": "ISO 4217 currency code",
1152
- "maxLength": 3,
1153
- "minLength": 3,
1154
- "pattern": "^[A-Z]{3}$",
1155
- "type": "string"
1156
- },
1157
- "servicingPoolAccountId": {
1158
- "description": "The servicing pool account",
1159
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
1160
- "type": "string",
1161
- "x-hyperscale-reference-filter": {
1162
- "column": "role",
1163
- "values": [
1164
- "customer_balance"
1165
- ]
1166
- }
1167
- }
1168
- },
1169
- "id": "borrower_loan_installment_1_payment",
1170
- "idPrefix": "zzaa",
1171
- "lifecycle": {
1172
- "initial": "created",
1173
- "states": [
1174
- "created",
1175
- "paid",
1176
- "refunded"
1177
- ],
1178
- "transitions": {
1179
- "refund": {
1180
- "from": [
1181
- "paid"
1182
- ],
1183
- "to": "refunded"
1184
- },
1185
- "repay": {
1186
- "from": [
1187
- "created"
1188
- ],
1189
- "to": "paid"
1190
- }
1191
- }
1192
- },
1193
- "parties": {
1194
- "beneficiary": "servicingPoolAccountId",
1195
- "payer": "borrowerAccountId"
1196
- },
1197
- "required": [
1198
- "servicingPoolAccountId",
1199
- "borrowerAccountId",
1200
- "amount",
1201
- "currency",
1202
- "borrowerLoanId"
1203
- ],
1204
- "summary": "Anchor-bound payment for installment 1",
1205
- "title": "Borrower loan Installment 1 Payment"
1206
- },
1207
- {
1208
- "actionOrder": [
1209
- "create",
1210
- "repay",
1211
- "refund"
1212
- ],
1213
- "actions": {
1214
- "create": {
1215
- "effects": {
1216
- "reads": [
1217
- {
1218
- "signature": "reads.requires_refs",
1219
- "source": "requiresRefs"
1220
- }
1221
- ]
1222
- },
1223
- "moves": [],
1224
- "publicAction": "createBorrowerLoanInstallment2Payment",
1225
- "requiresRefs": [
1226
- {
1227
- "bind": {
1228
- "borrowerAccountId": "fields.borrowerAccountId",
1229
- "currency": "fields.currency",
1230
- "servicingPoolAccountId": "fields.servicingPoolAccountId"
1231
- },
1232
- "field": "borrowerLoanId",
1233
- "statuses": [
1234
- "active",
1235
- "installment_1_delinquent",
1236
- "installment_2_delinquent"
1237
- ]
1238
- }
1239
- ],
1240
- "steps": [],
1241
- "summary": "Create a payment record for installment 2"
1242
- },
1243
- "refund": {
1244
- "effects": {
1245
- "moves": [
1246
- {
1247
- "signature": "moves.transfer.internal",
1248
- "source": "moves[0]"
1249
- }
1250
- ],
1251
- "reads": [
1252
- {
1253
- "signature": "reads.requires_refs",
1254
- "source": "requiresRefs"
1255
- }
1256
- ]
1257
- },
1258
- "moves": [
1259
- {
1260
- "bind": {
1261
- "amount": {
1262
- "from": "instance",
1263
- "path": "fields.amount"
1264
- },
1265
- "currency": {
1266
- "from": "instance",
1267
- "path": "fields.currency"
1268
- },
1269
- "destinationAccountId": {
1270
- "from": "instance",
1271
- "path": "fields.borrowerAccountId"
1272
- },
1273
- "metadata.instrumentId": {
1274
- "from": "const",
1275
- "value": "borrower_loan_installment_2_payment"
1276
- },
1277
- "metadata.instrumentInstanceId": {
1278
- "from": "instance",
1279
- "path": "instrumentInstanceId"
1280
- },
1281
- "metadata.phase": {
1282
- "from": "const",
1283
- "value": "refund"
1284
- },
1285
- "productId": {
1286
- "from": "instance",
1287
- "path": "productId"
1288
- },
1289
- "sourceAccountId": {
1290
- "from": "instance",
1291
- "path": "fields.servicingPoolAccountId"
1292
- }
1293
- },
1294
- "capture": {
1295
- "refundRefundTransferId": "transferId"
1296
- },
1297
- "key": "refund",
1298
- "operation": "internal_transfer.create"
1299
- }
1300
- ],
1301
- "publicAction": "refundBorrowerLoanInstallment2Payment",
1302
- "requiresRefs": [
1303
- {
1304
- "field": "borrowerLoanId",
1305
- "match": {
1306
- "fields.borrowerAccountId": "fields.borrowerAccountId",
1307
- "fields.currency": "fields.currency",
1308
- "fields.servicingPoolAccountId": "fields.servicingPoolAccountId"
1309
- },
1310
- "statuses": [
1311
- "active",
1312
- "installment_1_delinquent",
1313
- "installment_2_delinquent"
1314
- ]
1315
- }
1316
- ],
1317
- "steps": [],
1318
- "summary": "Refund this one stored installment 2 payment whole"
1319
- },
1320
- "repay": {
1321
- "effects": {
1322
- "moves": [
1323
- {
1324
- "signature": "moves.transfer.internal",
1325
- "source": "moves[0]"
1326
- }
1327
- ],
1328
- "reads": [
1329
- {
1330
- "signature": "reads.requires_refs",
1331
- "source": "requiresRefs"
1332
- }
1333
- ]
1334
- },
1335
- "moves": [
1336
- {
1337
- "bind": {
1338
- "amount": {
1339
- "from": "instance",
1340
- "path": "fields.amount"
1341
- },
1342
- "currency": {
1343
- "from": "instance",
1344
- "path": "fields.currency"
1345
- },
1346
- "destinationAccountId": {
1347
- "from": "instance",
1348
- "path": "fields.servicingPoolAccountId"
1349
- },
1350
- "metadata.instrumentId": {
1351
- "from": "const",
1352
- "value": "borrower_loan_installment_2_payment"
1353
- },
1354
- "metadata.instrumentInstanceId": {
1355
- "from": "instance",
1356
- "path": "instrumentInstanceId"
1357
- },
1358
- "metadata.phase": {
1359
- "from": "const",
1360
- "value": "repay"
1361
- },
1362
- "productId": {
1363
- "from": "instance",
1364
- "path": "productId"
1365
- },
1366
- "sourceAccountId": {
1367
- "from": "instance",
1368
- "path": "fields.borrowerAccountId"
1369
- }
1370
- },
1371
- "capture": {
1372
- "repayRepaymentTransferId": "transferId"
1373
- },
1374
- "key": "repayment",
1375
- "operation": "internal_transfer.create"
1376
- }
1377
- ],
1378
- "publicAction": "repayBorrowerLoanInstallment2Payment",
1379
- "requiresExposure": [
1380
- {
1381
- "amountField": "amount",
1382
- "anchorField": "borrowerLoanId",
1383
- "capField": "installment2Amount",
1384
- "capOnAnchor": true,
1385
- "childInstrumentId": "borrower_loan_installment_2_payment",
1386
- "statuses": [
1387
- "paid"
1388
- ]
1389
- }
1390
- ],
1391
- "requiresRefs": [
1392
- {
1393
- "field": "borrowerLoanId",
1394
- "match": {
1395
- "fields.borrowerAccountId": "fields.borrowerAccountId",
1396
- "fields.currency": "fields.currency",
1397
- "fields.servicingPoolAccountId": "fields.servicingPoolAccountId"
1398
- },
1399
- "statuses": [
1400
- "active",
1401
- "installment_1_delinquent",
1402
- "installment_2_delinquent"
1403
- ]
1404
- }
1405
- ],
1406
- "steps": [],
1407
- "summary": "Pay a partial or full amount against installment 2"
1408
- }
1409
- },
1410
- "description": "One partial or full payment bound to installment 2 of borrower_loan; the operation name fixes the anchor and borrowerLoanId fixes the obligation",
1411
- "fields": {
1412
- "amount": {
1413
- "description": "Positive payment amount capped with its paid siblings at installment2Amount",
1414
- "pattern": "^[1-9][0-9]{0,17}$",
1415
- "type": "string"
1416
- },
1417
- "borrowerAccountId": {
1418
- "description": "The borrower account",
1419
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
1420
- "type": "string",
1421
- "x-hyperscale-reference-filter": {
1422
- "column": "role",
1423
- "values": [
1424
- "customer_balance"
1425
- ]
1426
- }
1427
- },
1428
- "borrowerLoanId": {
1429
- "description": "The exact borrower loan this payment belongs to",
1430
- "pattern": "^bl_(sandbox|live)_[a-z0-9]{8,64}$",
1431
- "type": "string"
1432
- },
1433
- "currency": {
1434
- "description": "ISO 4217 currency code",
1435
- "maxLength": 3,
1436
- "minLength": 3,
1437
- "pattern": "^[A-Z]{3}$",
1438
- "type": "string"
1439
- },
1440
- "servicingPoolAccountId": {
1441
- "description": "The servicing pool account",
1442
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
1443
- "type": "string",
1444
- "x-hyperscale-reference-filter": {
1445
- "column": "role",
1446
- "values": [
1447
- "customer_balance"
1448
- ]
1449
- }
1450
- }
1451
- },
1452
- "id": "borrower_loan_installment_2_payment",
1453
- "idPrefix": "zzab",
1454
- "lifecycle": {
1455
- "initial": "created",
1456
- "states": [
1457
- "created",
1458
- "paid",
1459
- "refunded"
1460
- ],
1461
- "transitions": {
1462
- "refund": {
1463
- "from": [
1464
- "paid"
1465
- ],
1466
- "to": "refunded"
1467
- },
1468
- "repay": {
1469
- "from": [
1470
- "created"
1471
- ],
1472
- "to": "paid"
1473
- }
1474
- }
1475
- },
1476
- "parties": {
1477
- "beneficiary": "servicingPoolAccountId",
1478
- "payer": "borrowerAccountId"
1479
- },
1480
- "required": [
1481
- "servicingPoolAccountId",
1482
- "borrowerAccountId",
1483
- "amount",
1484
- "currency",
1485
- "borrowerLoanId"
1486
- ],
1487
- "summary": "Anchor-bound payment for installment 2",
1488
- "title": "Borrower loan Installment 2 Payment"
1489
- },
1490
- {
1491
- "actionOrder": [
1492
- "create",
1493
- "snapshot_lender_claims"
1494
- ],
1495
- "actions": {
1496
- "create": {
1497
- "moves": [],
1498
- "publicAction": "createRepaymentDistribution",
1499
- "steps": [],
1500
- "summary": "Open entitlement recording"
1501
- },
1502
- "snapshot_lender_claims": {
1503
- "captureInput": {
1504
- "snapshotEvidenceReference": "evidenceReference"
1505
- },
1506
- "effects": {
1507
- "decides": [
1508
- {
1509
- "signature": "decides.tenant_port",
1510
- "source": "port"
1511
- }
1512
- ]
1513
- },
1514
- "input": {
1515
- "additionalProperties": false,
1516
- "properties": {
1517
- "evidenceReference": {
1518
- "description": "Required decision reference retained in the operation receipt",
1519
- "maxLength": 180,
1520
- "minLength": 1,
1521
- "type": "string"
1522
- }
1523
- },
1524
- "required": [
1525
- "evidenceReference"
1526
- ],
1527
- "type": "object"
1528
- },
1529
- "moves": [],
1530
- "port": {
1531
- "allowedParties": [
1532
- "payer"
1533
- ]
1534
- },
1535
- "publicAction": "snapshotLenderClaimsRepaymentDistribution",
1536
- "steps": [],
1537
- "summary": "Freeze the entitlement set from stored evidence"
1538
- }
1539
- },
1540
- "aggregateInvariants": [
1541
- {
1542
- "childInstrumentId": "repayment_distribution_entitlement",
1543
- "childRefField": "repaymentDistributionId",
1544
- "childStatuses": [
1545
- "recorded",
1546
- "paid"
1547
- ],
1548
- "count": true,
1549
- "parentField": "maxRecipients"
1550
- }
1551
- ],
1552
- "description": "Evidence-frozen weighted distribution",
1553
- "fields": {
1554
- "currency": {
1555
- "description": "ISO 4217 currency code",
1556
- "maxLength": 3,
1557
- "minLength": 3,
1558
- "pattern": "^[A-Z]{3}$",
1559
- "type": "string"
1560
- },
1561
- "distributableAmount": {
1562
- "description": "Distribution pool in SAR minor units",
1563
- "pattern": "^[1-9][0-9]{0,17}$",
1564
- "type": "string"
1565
- },
1566
- "maxRecipients": {
1567
- "const": 250,
1568
- "description": "Exactly 250 frozen entitlement rows",
1569
- "type": "integer"
1570
- },
1571
- "returnRecordAt": {
1572
- "description": "Stored record date",
1573
- "format": "hyperscale-date-time",
1574
- "type": "string"
1575
- },
1576
- "servicingPoolAccountId": {
1577
- "description": "The servicing pool account",
1578
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
1579
- "type": "string",
1580
- "x-hyperscale-reference-filter": {
1581
- "column": "role",
1582
- "values": [
1583
- "customer_balance"
1584
- ]
1585
- }
1586
- }
1587
- },
1588
- "id": "repayment_distribution",
1589
- "idPrefix": "rd",
1590
- "lifecycle": {
1591
- "initial": "open",
1592
- "states": [
1593
- "open",
1594
- "snapshotted"
1595
- ],
1596
- "transitions": {
1597
- "snapshot_lender_claims": {
1598
- "from": [
1599
- "open"
1600
- ],
1601
- "to": "snapshotted"
1602
- }
1603
- }
1604
- },
1605
- "parties": {
1606
- "payer": "servicingPoolAccountId"
1607
- },
1608
- "required": [
1609
- "servicingPoolAccountId",
1610
- "currency",
1611
- "distributableAmount",
1612
- "returnRecordAt",
1613
- "maxRecipients"
1614
- ],
1615
- "summary": "Frozen largest-remainder distribution",
1616
- "title": "Repayment distribution"
1617
- },
1618
- {
1619
- "actionOrder": [
1620
- "create",
1621
- "payout"
1622
- ],
1623
- "actions": {
1624
- "create": {
1625
- "effects": {
1626
- "reads": [
1627
- {
1628
- "signature": "reads.requires_refs",
1629
- "source": "requiresRefs"
1630
- }
1631
- ]
1632
- },
1633
- "moves": [],
1634
- "publicAction": "createRepaymentDistributionEntitlement",
1635
- "requiresRefs": [
1636
- {
1637
- "bind": {
1638
- "currency": "fields.currency",
1639
- "servicingPoolAccountId": "fields.servicingPoolAccountId"
1640
- },
1641
- "field": "repaymentDistributionId",
1642
- "statuses": [
1643
- "open"
1644
- ]
1645
- }
1646
- ],
1647
- "steps": [],
1648
- "summary": "Record one entitlement before snapshot"
1649
- },
1650
- "payout": {
1651
- "distribute": {
1652
- "amountRef": "payoutShare",
1653
- "onZero": "skip_steps",
1654
- "pool": {
1655
- "from": "parent",
1656
- "path": "fields.distributableAmount"
1657
- },
1658
- "refField": "repaymentDistributionId",
1659
- "statuses": [
1660
- "recorded",
1661
- "paid"
1662
- ],
1663
- "weightField": "committedWeight"
1664
- },
1665
- "effects": {
1666
- "moves": [
1667
- {
1668
- "signature": "moves.transfer.internal",
1669
- "source": "moves[0]"
1670
- }
1671
- ],
1672
- "reads": [
1673
- {
1674
- "signature": "reads.requires_refs",
1675
- "source": "requiresRefs"
1676
- }
1677
- ]
1678
- },
1679
- "moves": [
1680
- {
1681
- "bind": {
1682
- "amount": {
1683
- "from": "instance",
1684
- "path": "refs.payoutShare"
1685
- },
1686
- "currency": {
1687
- "from": "instance",
1688
- "path": "fields.currency"
1689
- },
1690
- "destinationAccountId": {
1691
- "from": "instance",
1692
- "path": "fields.lenderAccountId"
1693
- },
1694
- "metadata.instrumentId": {
1695
- "from": "const",
1696
- "value": "repayment_distribution_entitlement"
1697
- },
1698
- "metadata.instrumentInstanceId": {
1699
- "from": "instance",
1700
- "path": "instrumentInstanceId"
1701
- },
1702
- "metadata.phase": {
1703
- "from": "const",
1704
- "value": "payout"
1705
- },
1706
- "productId": {
1707
- "from": "instance",
1708
- "path": "productId"
1709
- },
1710
- "sourceAccountId": {
1711
- "from": "instance",
1712
- "path": "fields.servicingPoolAccountId"
1713
- }
1714
- },
1715
- "capture": {
1716
- "payoutPayoutTransferId": "transferId"
1717
- },
1718
- "key": "payout",
1719
- "operation": "internal_transfer.create"
1720
- }
1721
- ],
1722
- "publicAction": "payoutRepaymentDistributionEntitlement",
1723
- "requiresRefs": [
1724
- {
1725
- "field": "repaymentDistributionId",
1726
- "match": {
1727
- "fields.currency": "fields.currency",
1728
- "fields.servicingPoolAccountId": "fields.servicingPoolAccountId"
1729
- },
1730
- "statuses": [
1731
- "snapshotted"
1732
- ]
1733
- }
1734
- ],
1735
- "steps": [],
1736
- "summary": "Pay the deterministic largest-remainder share once"
1737
- }
1738
- },
1739
- "description": "One frozen weighted entitlement in repayment_distribution",
1740
- "fields": {
1741
- "committedWeight": {
1742
- "description": "Stored non-negative entitlement weight",
1743
- "pattern": "^[1-9][0-9]{0,17}$",
1744
- "type": "string"
1745
- },
1746
- "currency": {
1747
- "description": "ISO 4217 currency code",
1748
- "maxLength": 3,
1749
- "minLength": 3,
1750
- "pattern": "^[A-Z]{3}$",
1751
- "type": "string"
1752
- },
1753
- "lenderAccountId": {
1754
- "description": "The lender account",
1755
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
1756
- "type": "string",
1757
- "x-hyperscale-reference-filter": {
1758
- "column": "role",
1759
- "values": [
1760
- "customer_balance"
1761
- ]
1762
- }
1763
- },
1764
- "repaymentDistributionId": {
1765
- "description": "The exact repayment_distribution",
1766
- "pattern": "^rd_(sandbox|live)_[a-z0-9]{8,64}$",
1767
- "type": "string"
1768
- },
1769
- "servicingPoolAccountId": {
1770
- "description": "The servicing pool account",
1771
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
1772
- "type": "string",
1773
- "x-hyperscale-reference-filter": {
1774
- "column": "role",
1775
- "values": [
1776
- "customer_balance"
1777
- ]
1778
- }
1779
- }
1780
- },
1781
- "id": "repayment_distribution_entitlement",
1782
- "idPrefix": "zzac",
1783
- "lifecycle": {
1784
- "initial": "recorded",
1785
- "states": [
1786
- "recorded",
1787
- "paid"
1788
- ],
1789
- "transitions": {
1790
- "payout": {
1791
- "from": [
1792
- "recorded"
1793
- ],
1794
- "to": "paid"
1795
- }
1796
- }
1797
- },
1798
- "parties": {
1799
- "beneficiary": "lenderAccountId",
1800
- "payer": "servicingPoolAccountId"
1801
- },
1802
- "required": [
1803
- "lenderAccountId",
1804
- "servicingPoolAccountId",
1805
- "currency",
1806
- "repaymentDistributionId",
1807
- "committedWeight"
1808
- ],
1809
- "summary": "Frozen entitlement in repayment_distribution",
1810
- "title": "Repayment distribution Entitlement"
1811
- }
1812
- ],
1813
- "product": "crowdfunding_p2p",
1814
- "subjects": [],
1815
- "title": "Crowdfunding and peer lending",
1816
- "udl": 1,
1817
- "version": 1
1818
- }
1819
-