@hyperscale0/hsx 3.2.0 → 3.3.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.
@@ -0,0 +1,1286 @@
1
+ header reporting
2
+
3
+ instrument portfolio(on: ref<financing.installments>[], default_days: integer(1, 3650) = 90, retention_years: integer(1, 100) = 10, aging_first_days: integer(1, 3650) = 30, aging_second_days: integer(1, 3650) = 60, aging_third_days: integer(1, 3650) = 90, ratio_scale: integer(1, 1000000) = 10000, ratio_rounding: enum(floor, halfUp) = floor, lock_wait_ms: integer(1, 2000) = 2000, capture_ms: integer(1, 10000) = 10000, max_rows: integer(1, 100000) = 10000, max_join_rows: integer(1, 1000000) = 100000, max_bytes: integer(1024, 16777216) = 8388608) {
4
+ summary: "Declared financing reports evaluated over frozen Product facts."
5
+ fields {}
6
+ lifecycle { states: [declared], initial: declared }
7
+ action create {}
8
+ constraints { aging_first_days: less_than(aging_second_days), aging_second_days: less_than(aging_third_days) }
9
+ reports: [
10
+ {
11
+ identity: { id: "portfolio_aging", version: 1, description: "Period-end outstanding principal by oldest unpaid installment. Remaining scheduled profit is distinct from accrued profit. Restructuring evidence is unavailable." },
12
+ scope: { kind: "product", classification: "internal", currency: "SAR" },
13
+ datasets: [
14
+ {
15
+ id: "facilities",
16
+ source: "instrument",
17
+ instruments: on,
18
+ rowKey: "facilityId",
19
+ columns: [
20
+ {
21
+ name: "facilityId",
22
+ field: "id",
23
+ type: { kind: "text" },
24
+ required: true
25
+ },
26
+ {
27
+ name: "borrowerAccount",
28
+ field: "borrower",
29
+ type: { kind: "text" },
30
+ required: true
31
+ },
32
+ {
33
+ name: "state",
34
+ field: "status",
35
+ type: { kind: "text" },
36
+ required: true
37
+ },
38
+ {
39
+ name: "originalPrincipal",
40
+ field: "principal",
41
+ type: { kind: "money", currency: "SAR" },
42
+ required: true
43
+ },
44
+ {
45
+ name: "scheduleCount",
46
+ field: "months",
47
+ type: { kind: "integer" },
48
+ required: true
49
+ },
50
+ {
51
+ name: "recordedCreation",
52
+ field: "createdAt",
53
+ type: { kind: "date" },
54
+ required: true
55
+ }
56
+ ],
57
+ expressions: [
58
+ {
59
+ id: "activeState",
60
+ op: "literal",
61
+ type: { kind: "text" },
62
+ value: "active"
63
+ },
64
+ {
65
+ id: "paidState",
66
+ op: "literal",
67
+ type: { kind: "text" },
68
+ value: "paid"
69
+ },
70
+ {
71
+ id: "writtenState",
72
+ op: "literal",
73
+ type: { kind: "text" },
74
+ value: "written_off"
75
+ },
76
+ { id: "active", op: "equal", left: "state", right: "activeState" },
77
+ { id: "paid", op: "equal", left: "state", right: "paidState" },
78
+ { id: "writtenOff", op: "equal", left: "state", right: "writtenState" },
79
+ { id: "activeOrPaid", op: "or", left: "active", right: "paid" },
80
+ { id: "financed", op: "or", left: "active", right: "writtenOff" }
81
+ ],
82
+ selection: "active"
83
+ },
84
+ {
85
+ id: "schedule",
86
+ source: "instrument",
87
+ instruments: child(on, slice),
88
+ rowKey: "sliceId",
89
+ columns: [
90
+ {
91
+ name: "sliceId",
92
+ field: "id",
93
+ type: { kind: "text" },
94
+ required: true
95
+ },
96
+ {
97
+ name: "planId",
98
+ field: "plan",
99
+ type: { kind: "text" },
100
+ required: true
101
+ },
102
+ {
103
+ name: "due",
104
+ field: "dueAt",
105
+ type: { kind: "date" },
106
+ required: true
107
+ },
108
+ {
109
+ name: "principal",
110
+ field: "principalReceivable.balance",
111
+ type: { kind: "money", currency: "SAR" },
112
+ required: true
113
+ },
114
+ {
115
+ name: "profit",
116
+ field: "profitReceivable.balance",
117
+ type: { kind: "money", currency: "SAR" },
118
+ required: true
119
+ },
120
+ {
121
+ name: "scheduledPrincipal",
122
+ field: "principal",
123
+ type: { kind: "money", currency: "SAR" },
124
+ required: true
125
+ }
126
+ ],
127
+ expressions: [
128
+ {
129
+ id: "zeroMoney",
130
+ op: "literal",
131
+ type: { kind: "money", currency: "SAR" },
132
+ value: "0"
133
+ },
134
+ {
135
+ id: "zeroDays",
136
+ op: "literal",
137
+ type: { kind: "integer" },
138
+ value: 0
139
+ },
140
+ { id: "observed", op: "parameter", name: "observationAt" },
141
+ { id: "scheduledOutstanding", op: "sum", left: "principal", right: "profit" },
142
+ { id: "unpaid", op: "less", left: "zeroMoney", right: "scheduledOutstanding" },
143
+ { id: "elapsed", op: "daysBetween", left: "due", right: "observed" },
144
+ { id: "nonnegativeDays", op: "maximum", left: "elapsed", right: "zeroDays" },
145
+ { id: "daysPastDue", op: "choose", condition: "unpaid", yes: "nonnegativeDays", no: "zeroDays" }
146
+ ]
147
+ },
148
+ {
149
+ id: "borrowerAccounts",
150
+ source: "account",
151
+ instruments: [ ],
152
+ rowKey: "accountId",
153
+ columns: [
154
+ {
155
+ name: "accountId",
156
+ field: "id",
157
+ type: { kind: "text" },
158
+ required: true
159
+ },
160
+ {
161
+ name: "participant",
162
+ field: "ownerParticipantId",
163
+ type: { kind: "text" },
164
+ required: false
165
+ }
166
+ ],
167
+ expressions: [ ]
168
+ },
169
+ {
170
+ id: "borrowers",
171
+ source: "identity",
172
+ instruments: [ ],
173
+ rowKey: "customerId",
174
+ columns: [
175
+ {
176
+ name: "customerId",
177
+ field: "id",
178
+ type: { kind: "text" },
179
+ required: true
180
+ },
181
+ {
182
+ name: "participantId",
183
+ field: "participantId",
184
+ type: { kind: "text" },
185
+ required: true
186
+ },
187
+ {
188
+ name: "entityId",
189
+ field: "entityId",
190
+ type: { kind: "text" },
191
+ required: true
192
+ }
193
+ ],
194
+ expressions: [ ]
195
+ }
196
+ ],
197
+ time: { timezone: "Asia/Riyadh", boundary: "startInclusiveEndExclusive", observation: "periodEnd", history: "retainedOnly" },
198
+ selection: { dataset: "facilities" },
199
+ calculation: {
200
+ joins: [
201
+ {
202
+ dataset: "schedule",
203
+ local: "facilityId",
204
+ foreign: "planId",
205
+ cardinality: "many",
206
+ missing: "refuse",
207
+ aggregates: [
208
+ { name: "outstandingPrincipal", op: "sum", value: "principal" },
209
+ { name: "remainingScheduledProfit", op: "sum", value: "profit" },
210
+ { name: "scheduledPrincipalTotal", op: "sum", value: "scheduledPrincipal" },
211
+ { name: "capturedScheduleCount", op: "count" },
212
+ { name: "oldestUnpaidDays", op: "maximum", value: "daysPastDue" }
213
+ ]
214
+ },
215
+ {
216
+ dataset: "borrowerAccounts",
217
+ local: "borrowerAccount",
218
+ foreign: "accountId",
219
+ cardinality: "one",
220
+ missing: "refuse",
221
+ aggregates: [
222
+ { name: "borrowerParticipant", op: "minimum", value: "participant" }
223
+ ]
224
+ },
225
+ {
226
+ dataset: "borrowers",
227
+ local: "borrowerParticipant",
228
+ foreign: "participantId",
229
+ cardinality: "one",
230
+ missing: "refuse",
231
+ aggregates: [
232
+ { name: "borrowerEntity", op: "minimum", value: "entityId" }
233
+ ]
234
+ }
235
+ ],
236
+ expressions: [
237
+ {
238
+ id: "day0",
239
+ op: "literal",
240
+ type: { kind: "integer" },
241
+ value: 0
242
+ },
243
+ {
244
+ id: "day30",
245
+ op: "literal",
246
+ type: { kind: "integer" },
247
+ value: aging_first_days
248
+ },
249
+ {
250
+ id: "day60",
251
+ op: "literal",
252
+ type: { kind: "integer" },
253
+ value: aging_second_days
254
+ },
255
+ {
256
+ id: "day90",
257
+ op: "literal",
258
+ type: { kind: "integer" },
259
+ value: aging_third_days
260
+ },
261
+ {
262
+ id: "band0",
263
+ op: "literal",
264
+ type: { kind: "text" },
265
+ value: "current"
266
+ },
267
+ {
268
+ id: "band30",
269
+ op: "literal",
270
+ type: { kind: "text" },
271
+ value: "first"
272
+ },
273
+ {
274
+ id: "band60",
275
+ op: "literal",
276
+ type: { kind: "text" },
277
+ value: "second"
278
+ },
279
+ {
280
+ id: "band90",
281
+ op: "literal",
282
+ type: { kind: "text" },
283
+ value: "third"
284
+ },
285
+ {
286
+ id: "bandLate",
287
+ op: "literal",
288
+ type: { kind: "text" },
289
+ value: "later"
290
+ },
291
+ { id: "current", op: "atMost", left: "oldestUnpaidDays", right: "day0" },
292
+ { id: "first", op: "atMost", left: "oldestUnpaidDays", right: "day30" },
293
+ { id: "second", op: "atMost", left: "oldestUnpaidDays", right: "day60" },
294
+ { id: "third", op: "atMost", left: "oldestUnpaidDays", right: "day90" },
295
+ { id: "lateBand", op: "choose", condition: "third", yes: "band90", no: "bandLate" },
296
+ { id: "secondBand", op: "choose", condition: "second", yes: "band60", no: "lateBand" },
297
+ { id: "firstBand", op: "choose", condition: "first", yes: "band30", no: "secondBand" },
298
+ { id: "agingBand", op: "choose", condition: "current", yes: "band0", no: "firstBand" }
299
+ ],
300
+ groupBy: [ "agingBand" ],
301
+ aggregates: [
302
+ { name: "facilities", op: "count" },
303
+ { name: "principalMinor", op: "sum", value: "outstandingPrincipal" },
304
+ { name: "scheduledProfitMinor", op: "sum", value: "remainingScheduledProfit" }
305
+ ],
306
+ resultExpressions: [ ]
307
+ },
308
+ validation: {
309
+ empty: "noEligibleFacilities",
310
+ required: [ "borrowerEntity" ],
311
+ reconcile: [ ],
312
+ rowReconcile: [
313
+ { left: "originalPrincipal", right: "scheduledPrincipalTotal" },
314
+ { left: "scheduleCount", right: "capturedScheduleCount" }
315
+ ],
316
+ unavailableFacts: [ ],
317
+ lockTimeoutMs: lock_wait_ms,
318
+ captureTimeoutMs: capture_ms,
319
+ maxRows: max_rows,
320
+ maxJoinRows: max_join_rows,
321
+ maxBytes: max_bytes
322
+ },
323
+ output: {
324
+ profile: "internal.v1",
325
+ formats: [ "json", "csv" ],
326
+ columns: [
327
+ {
328
+ name: "agingBand",
329
+ label: "agingBand",
330
+ type: { kind: "text" }
331
+ },
332
+ {
333
+ name: "facilities",
334
+ label: "facilities",
335
+ type: { kind: "integer" }
336
+ },
337
+ {
338
+ name: "principalMinor",
339
+ label: "principalMinor",
340
+ type: { kind: "money", currency: "SAR" }
341
+ },
342
+ {
343
+ name: "scheduledProfitMinor",
344
+ label: "scheduledProfitMinor",
345
+ type: { kind: "money", currency: "SAR" }
346
+ }
347
+ ],
348
+ sort: [ "agingBand" ]
349
+ },
350
+ authority: {
351
+ request: [ "owner", "finance" ],
352
+ read: [ "owner", "admin", "operations", "finance", "viewer" ],
353
+ release: [ ],
354
+ independentApproval: true,
355
+ retention: { policy: "report_replay", years: retention_years }
356
+ }
357
+ },
358
+ {
359
+ identity: { id: "origination_cohorts", version: 1, description: "Origination cohort performance. Refuses until business-effective origination dates and dated repayment allocation are retained; record creation time is not origination." },
360
+ scope: { kind: "product", classification: "internal", currency: "SAR" },
361
+ datasets: [
362
+ {
363
+ id: "facilities",
364
+ source: "instrument",
365
+ instruments: on,
366
+ rowKey: "facilityId",
367
+ columns: [
368
+ {
369
+ name: "facilityId",
370
+ field: "id",
371
+ type: { kind: "text" },
372
+ required: true
373
+ },
374
+ {
375
+ name: "borrowerAccount",
376
+ field: "borrower",
377
+ type: { kind: "text" },
378
+ required: true
379
+ },
380
+ {
381
+ name: "state",
382
+ field: "status",
383
+ type: { kind: "text" },
384
+ required: true
385
+ },
386
+ {
387
+ name: "originalPrincipal",
388
+ field: "principal",
389
+ type: { kind: "money", currency: "SAR" },
390
+ required: true
391
+ },
392
+ {
393
+ name: "scheduleCount",
394
+ field: "months",
395
+ type: { kind: "integer" },
396
+ required: true
397
+ },
398
+ {
399
+ name: "recordedCreation",
400
+ field: "createdAt",
401
+ type: { kind: "date" },
402
+ required: true
403
+ }
404
+ ],
405
+ expressions: [
406
+ {
407
+ id: "activeState",
408
+ op: "literal",
409
+ type: { kind: "text" },
410
+ value: "active"
411
+ },
412
+ {
413
+ id: "paidState",
414
+ op: "literal",
415
+ type: { kind: "text" },
416
+ value: "paid"
417
+ },
418
+ {
419
+ id: "writtenState",
420
+ op: "literal",
421
+ type: { kind: "text" },
422
+ value: "written_off"
423
+ },
424
+ { id: "active", op: "equal", left: "state", right: "activeState" },
425
+ { id: "paid", op: "equal", left: "state", right: "paidState" },
426
+ { id: "writtenOff", op: "equal", left: "state", right: "writtenState" },
427
+ { id: "activeOrPaid", op: "or", left: "active", right: "paid" },
428
+ { id: "financed", op: "or", left: "active", right: "writtenOff" }
429
+ ],
430
+ selection: "financed"
431
+ },
432
+ {
433
+ id: "schedule",
434
+ source: "instrument",
435
+ instruments: child(on, slice),
436
+ rowKey: "sliceId",
437
+ columns: [
438
+ {
439
+ name: "sliceId",
440
+ field: "id",
441
+ type: { kind: "text" },
442
+ required: true
443
+ },
444
+ {
445
+ name: "planId",
446
+ field: "plan",
447
+ type: { kind: "text" },
448
+ required: true
449
+ },
450
+ {
451
+ name: "due",
452
+ field: "dueAt",
453
+ type: { kind: "date" },
454
+ required: true
455
+ },
456
+ {
457
+ name: "principal",
458
+ field: "principalReceivable.balance",
459
+ type: { kind: "money", currency: "SAR" },
460
+ required: true
461
+ },
462
+ {
463
+ name: "profit",
464
+ field: "profitReceivable.balance",
465
+ type: { kind: "money", currency: "SAR" },
466
+ required: true
467
+ },
468
+ {
469
+ name: "scheduledPrincipal",
470
+ field: "principal",
471
+ type: { kind: "money", currency: "SAR" },
472
+ required: true
473
+ }
474
+ ],
475
+ expressions: [
476
+ {
477
+ id: "zeroMoney",
478
+ op: "literal",
479
+ type: { kind: "money", currency: "SAR" },
480
+ value: "0"
481
+ },
482
+ {
483
+ id: "zeroDays",
484
+ op: "literal",
485
+ type: { kind: "integer" },
486
+ value: 0
487
+ },
488
+ { id: "observed", op: "parameter", name: "observationAt" },
489
+ { id: "scheduledOutstanding", op: "sum", left: "principal", right: "profit" },
490
+ { id: "unpaid", op: "less", left: "zeroMoney", right: "scheduledOutstanding" },
491
+ { id: "elapsed", op: "daysBetween", left: "due", right: "observed" },
492
+ { id: "nonnegativeDays", op: "maximum", left: "elapsed", right: "zeroDays" },
493
+ { id: "daysPastDue", op: "choose", condition: "unpaid", yes: "nonnegativeDays", no: "zeroDays" }
494
+ ]
495
+ },
496
+ {
497
+ id: "borrowerAccounts",
498
+ source: "account",
499
+ instruments: [ ],
500
+ rowKey: "accountId",
501
+ columns: [
502
+ {
503
+ name: "accountId",
504
+ field: "id",
505
+ type: { kind: "text" },
506
+ required: true
507
+ },
508
+ {
509
+ name: "participant",
510
+ field: "ownerParticipantId",
511
+ type: { kind: "text" },
512
+ required: false
513
+ }
514
+ ],
515
+ expressions: [ ]
516
+ },
517
+ {
518
+ id: "borrowers",
519
+ source: "identity",
520
+ instruments: [ ],
521
+ rowKey: "customerId",
522
+ columns: [
523
+ {
524
+ name: "customerId",
525
+ field: "id",
526
+ type: { kind: "text" },
527
+ required: true
528
+ },
529
+ {
530
+ name: "participantId",
531
+ field: "participantId",
532
+ type: { kind: "text" },
533
+ required: true
534
+ },
535
+ {
536
+ name: "entityId",
537
+ field: "entityId",
538
+ type: { kind: "text" },
539
+ required: true
540
+ }
541
+ ],
542
+ expressions: [ ]
543
+ }
544
+ ],
545
+ time: { timezone: "Asia/Riyadh", boundary: "startInclusiveEndExclusive", observation: "periodEnd", history: "retainedOnly" },
546
+ selection: { dataset: "facilities" },
547
+ calculation: {
548
+ joins: [
549
+ {
550
+ dataset: "schedule",
551
+ local: "facilityId",
552
+ foreign: "planId",
553
+ cardinality: "many",
554
+ missing: "refuse",
555
+ aggregates: [
556
+ { name: "outstandingPrincipal", op: "sum", value: "principal" },
557
+ { name: "remainingScheduledProfit", op: "sum", value: "profit" },
558
+ { name: "scheduledPrincipalTotal", op: "sum", value: "scheduledPrincipal" },
559
+ { name: "capturedScheduleCount", op: "count" },
560
+ { name: "oldestUnpaidDays", op: "maximum", value: "daysPastDue" }
561
+ ]
562
+ },
563
+ {
564
+ dataset: "borrowerAccounts",
565
+ local: "borrowerAccount",
566
+ foreign: "accountId",
567
+ cardinality: "one",
568
+ missing: "refuse",
569
+ aggregates: [
570
+ { name: "borrowerParticipant", op: "minimum", value: "participant" }
571
+ ]
572
+ },
573
+ {
574
+ dataset: "borrowers",
575
+ local: "borrowerParticipant",
576
+ foreign: "participantId",
577
+ cardinality: "one",
578
+ missing: "refuse",
579
+ aggregates: [
580
+ { name: "borrowerEntity", op: "minimum", value: "entityId" }
581
+ ]
582
+ }
583
+ ],
584
+ expressions: [
585
+ { id: "recordedMonth", op: "bucket", value: "recordedCreation", unit: "month" }
586
+ ],
587
+ groupBy: [ "recordedMonth" ],
588
+ aggregates: [
589
+ { name: "facilities", op: "count" },
590
+ { name: "principalMinor", op: "sum", value: "outstandingPrincipal" }
591
+ ],
592
+ resultExpressions: [ ]
593
+ },
594
+ validation: {
595
+ empty: "noEligibleFacilities",
596
+ required: [ "borrowerEntity" ],
597
+ reconcile: [ ],
598
+ rowReconcile: [
599
+ { left: "originalPrincipal", right: "scheduledPrincipalTotal" },
600
+ { left: "scheduleCount", right: "capturedScheduleCount" }
601
+ ],
602
+ unavailableFacts: [ "business-effective origination timestamp", "dated repayment allocation and recovery history" ],
603
+ lockTimeoutMs: lock_wait_ms,
604
+ captureTimeoutMs: capture_ms,
605
+ maxRows: max_rows,
606
+ maxJoinRows: max_join_rows,
607
+ maxBytes: max_bytes
608
+ },
609
+ output: {
610
+ profile: "internal.v1",
611
+ formats: [ "json", "csv" ],
612
+ columns: [
613
+ {
614
+ name: "recordedMonth",
615
+ label: "recordedMonth",
616
+ type: { kind: "text" }
617
+ },
618
+ {
619
+ name: "facilities",
620
+ label: "facilities",
621
+ type: { kind: "integer" }
622
+ },
623
+ {
624
+ name: "principalMinor",
625
+ label: "principalMinor",
626
+ type: { kind: "money", currency: "SAR" }
627
+ }
628
+ ],
629
+ sort: [ "recordedMonth" ]
630
+ },
631
+ authority: {
632
+ request: [ "owner", "finance" ],
633
+ read: [ "owner", "admin", "operations", "finance", "viewer" ],
634
+ release: [ ],
635
+ independentApproval: true,
636
+ retention: { policy: "report_replay", years: retention_years }
637
+ }
638
+ },
639
+ {
640
+ identity: { id: "period_end_outstanding_principal_default_rate", version: 1, description: "Current active facilities with any unpaid installment at least the declared default days past due, observed at period end. Cure when arrears clear. Count and outstanding-principal weighted rates in the declared scale exclude paid and written-off facilities; write-offs are counted separately. This is a stock measure, not a new-default incidence or origination cohort rate." },
641
+ scope: { kind: "product", classification: "internal", currency: "SAR" },
642
+ datasets: [
643
+ {
644
+ id: "facilities",
645
+ source: "instrument",
646
+ instruments: on,
647
+ rowKey: "facilityId",
648
+ columns: [
649
+ {
650
+ name: "facilityId",
651
+ field: "id",
652
+ type: { kind: "text" },
653
+ required: true
654
+ },
655
+ {
656
+ name: "borrowerAccount",
657
+ field: "borrower",
658
+ type: { kind: "text" },
659
+ required: true
660
+ },
661
+ {
662
+ name: "state",
663
+ field: "status",
664
+ type: { kind: "text" },
665
+ required: true
666
+ },
667
+ {
668
+ name: "originalPrincipal",
669
+ field: "principal",
670
+ type: { kind: "money", currency: "SAR" },
671
+ required: true
672
+ },
673
+ {
674
+ name: "scheduleCount",
675
+ field: "months",
676
+ type: { kind: "integer" },
677
+ required: true
678
+ },
679
+ {
680
+ name: "recordedCreation",
681
+ field: "createdAt",
682
+ type: { kind: "date" },
683
+ required: true
684
+ }
685
+ ],
686
+ expressions: [
687
+ {
688
+ id: "activeState",
689
+ op: "literal",
690
+ type: { kind: "text" },
691
+ value: "active"
692
+ },
693
+ {
694
+ id: "paidState",
695
+ op: "literal",
696
+ type: { kind: "text" },
697
+ value: "paid"
698
+ },
699
+ {
700
+ id: "writtenState",
701
+ op: "literal",
702
+ type: { kind: "text" },
703
+ value: "written_off"
704
+ },
705
+ { id: "active", op: "equal", left: "state", right: "activeState" },
706
+ { id: "paid", op: "equal", left: "state", right: "paidState" },
707
+ { id: "writtenOff", op: "equal", left: "state", right: "writtenState" },
708
+ { id: "activeOrPaid", op: "or", left: "active", right: "paid" },
709
+ { id: "financed", op: "or", left: "active", right: "writtenOff" }
710
+ ],
711
+ selection: "financed"
712
+ },
713
+ {
714
+ id: "schedule",
715
+ source: "instrument",
716
+ instruments: child(on, slice),
717
+ rowKey: "sliceId",
718
+ columns: [
719
+ {
720
+ name: "sliceId",
721
+ field: "id",
722
+ type: { kind: "text" },
723
+ required: true
724
+ },
725
+ {
726
+ name: "planId",
727
+ field: "plan",
728
+ type: { kind: "text" },
729
+ required: true
730
+ },
731
+ {
732
+ name: "due",
733
+ field: "dueAt",
734
+ type: { kind: "date" },
735
+ required: true
736
+ },
737
+ {
738
+ name: "principal",
739
+ field: "principalReceivable.balance",
740
+ type: { kind: "money", currency: "SAR" },
741
+ required: true
742
+ },
743
+ {
744
+ name: "profit",
745
+ field: "profitReceivable.balance",
746
+ type: { kind: "money", currency: "SAR" },
747
+ required: true
748
+ },
749
+ {
750
+ name: "scheduledPrincipal",
751
+ field: "principal",
752
+ type: { kind: "money", currency: "SAR" },
753
+ required: true
754
+ }
755
+ ],
756
+ expressions: [
757
+ {
758
+ id: "zeroMoney",
759
+ op: "literal",
760
+ type: { kind: "money", currency: "SAR" },
761
+ value: "0"
762
+ },
763
+ {
764
+ id: "zeroDays",
765
+ op: "literal",
766
+ type: { kind: "integer" },
767
+ value: 0
768
+ },
769
+ { id: "observed", op: "parameter", name: "observationAt" },
770
+ { id: "scheduledOutstanding", op: "sum", left: "principal", right: "profit" },
771
+ { id: "unpaid", op: "less", left: "zeroMoney", right: "scheduledOutstanding" },
772
+ { id: "elapsed", op: "daysBetween", left: "due", right: "observed" },
773
+ { id: "nonnegativeDays", op: "maximum", left: "elapsed", right: "zeroDays" },
774
+ { id: "daysPastDue", op: "choose", condition: "unpaid", yes: "nonnegativeDays", no: "zeroDays" }
775
+ ]
776
+ },
777
+ {
778
+ id: "borrowerAccounts",
779
+ source: "account",
780
+ instruments: [ ],
781
+ rowKey: "accountId",
782
+ columns: [
783
+ {
784
+ name: "accountId",
785
+ field: "id",
786
+ type: { kind: "text" },
787
+ required: true
788
+ },
789
+ {
790
+ name: "participant",
791
+ field: "ownerParticipantId",
792
+ type: { kind: "text" },
793
+ required: false
794
+ }
795
+ ],
796
+ expressions: [ ]
797
+ },
798
+ {
799
+ id: "borrowers",
800
+ source: "identity",
801
+ instruments: [ ],
802
+ rowKey: "customerId",
803
+ columns: [
804
+ {
805
+ name: "customerId",
806
+ field: "id",
807
+ type: { kind: "text" },
808
+ required: true
809
+ },
810
+ {
811
+ name: "participantId",
812
+ field: "participantId",
813
+ type: { kind: "text" },
814
+ required: true
815
+ },
816
+ {
817
+ name: "entityId",
818
+ field: "entityId",
819
+ type: { kind: "text" },
820
+ required: true
821
+ }
822
+ ],
823
+ expressions: [ ]
824
+ }
825
+ ],
826
+ time: { timezone: "Asia/Riyadh", boundary: "startInclusiveEndExclusive", observation: "periodEnd", history: "retainedOnly" },
827
+ selection: { dataset: "facilities" },
828
+ calculation: {
829
+ joins: [
830
+ {
831
+ dataset: "schedule",
832
+ local: "facilityId",
833
+ foreign: "planId",
834
+ cardinality: "many",
835
+ missing: "refuse",
836
+ aggregates: [
837
+ { name: "outstandingPrincipal", op: "sum", value: "principal" },
838
+ { name: "remainingScheduledProfit", op: "sum", value: "profit" },
839
+ { name: "scheduledPrincipalTotal", op: "sum", value: "scheduledPrincipal" },
840
+ { name: "capturedScheduleCount", op: "count" },
841
+ { name: "oldestUnpaidDays", op: "maximum", value: "daysPastDue" }
842
+ ]
843
+ },
844
+ {
845
+ dataset: "borrowerAccounts",
846
+ local: "borrowerAccount",
847
+ foreign: "accountId",
848
+ cardinality: "one",
849
+ missing: "refuse",
850
+ aggregates: [
851
+ { name: "borrowerParticipant", op: "minimum", value: "participant" }
852
+ ]
853
+ },
854
+ {
855
+ dataset: "borrowers",
856
+ local: "borrowerParticipant",
857
+ foreign: "participantId",
858
+ cardinality: "one",
859
+ missing: "refuse",
860
+ aggregates: [
861
+ { name: "borrowerEntity", op: "minimum", value: "entityId" }
862
+ ]
863
+ }
864
+ ],
865
+ expressions: [
866
+ {
867
+ id: "threshold",
868
+ op: "literal",
869
+ type: { kind: "integer" },
870
+ value: default_days
871
+ },
872
+ {
873
+ id: "zero",
874
+ op: "literal",
875
+ type: { kind: "integer" },
876
+ value: 0
877
+ },
878
+ {
879
+ id: "one",
880
+ op: "literal",
881
+ type: { kind: "integer" },
882
+ value: 1
883
+ },
884
+ {
885
+ id: "zeroMoney",
886
+ op: "literal",
887
+ type: { kind: "money", currency: "SAR" },
888
+ value: "0"
889
+ },
890
+ { id: "pastThreshold", op: "atMost", left: "threshold", right: "oldestUnpaidDays" },
891
+ { id: "isDefault", op: "and", left: "active", right: "pastThreshold" },
892
+ { id: "activeCount", op: "choose", condition: "active", yes: "one", no: "zero" },
893
+ { id: "defaultCount", op: "choose", condition: "isDefault", yes: "one", no: "zero" },
894
+ { id: "writeOffCount", op: "choose", condition: "writtenOff", yes: "one", no: "zero" },
895
+ { id: "activePrincipal", op: "choose", condition: "active", yes: "outstandingPrincipal", no: "zeroMoney" },
896
+ { id: "defaultPrincipal", op: "choose", condition: "isDefault", yes: "outstandingPrincipal", no: "zeroMoney" }
897
+ ],
898
+ groupBy: [ ],
899
+ aggregates: [
900
+ { name: "activeFacilities", op: "sum", value: "activeCount" },
901
+ { name: "defaultFacilities", op: "sum", value: "defaultCount" },
902
+ { name: "writtenOffFacilities", op: "sum", value: "writeOffCount" },
903
+ { name: "activePrincipalMinor", op: "sum", value: "activePrincipal" },
904
+ { name: "defaultPrincipalMinor", op: "sum", value: "defaultPrincipal" }
905
+ ],
906
+ resultExpressions: [
907
+ { id: "countRate", op: "ratio", numerator: "defaultFacilities", denominator: "activeFacilities", scale: ratio_scale, rounding: ratio_rounding, zero: "null" },
908
+ { id: "principalRate", op: "ratio", numerator: "defaultPrincipalMinor", denominator: "activePrincipalMinor", scale: ratio_scale, rounding: ratio_rounding, zero: "null" },
909
+ {
910
+ id: "restructuringEvidence",
911
+ op: "literal",
912
+ type: { kind: "text" },
913
+ value: "unavailable"
914
+ },
915
+ {
916
+ id: "defaultDays",
917
+ op: "literal",
918
+ type: { kind: "integer" },
919
+ value: default_days
920
+ },
921
+ {
922
+ id: "rateScale",
923
+ op: "literal",
924
+ type: { kind: "integer" },
925
+ value: ratio_scale
926
+ }
927
+ ]
928
+ },
929
+ validation: {
930
+ empty: "refuse",
931
+ required: [ "borrowerEntity" ],
932
+ reconcile: [ ],
933
+ rowReconcile: [
934
+ { left: "originalPrincipal", right: "scheduledPrincipalTotal" },
935
+ { left: "scheduleCount", right: "capturedScheduleCount" }
936
+ ],
937
+ unavailableFacts: [ ],
938
+ lockTimeoutMs: lock_wait_ms,
939
+ captureTimeoutMs: capture_ms,
940
+ maxRows: max_rows,
941
+ maxJoinRows: max_join_rows,
942
+ maxBytes: max_bytes
943
+ },
944
+ output: {
945
+ profile: "internal.v1",
946
+ formats: [ "json", "csv" ],
947
+ columns: [
948
+ {
949
+ name: "activeFacilities",
950
+ label: "activeFacilities",
951
+ type: { kind: "integer" }
952
+ },
953
+ {
954
+ name: "defaultFacilities",
955
+ label: "defaultFacilities",
956
+ type: { kind: "integer" }
957
+ },
958
+ {
959
+ name: "writtenOffFacilities",
960
+ label: "writtenOffFacilities",
961
+ type: { kind: "integer" }
962
+ },
963
+ {
964
+ name: "activePrincipalMinor",
965
+ label: "activePrincipalMinor",
966
+ type: { kind: "money", currency: "SAR" }
967
+ },
968
+ {
969
+ name: "defaultPrincipalMinor",
970
+ label: "defaultPrincipalMinor",
971
+ type: { kind: "money", currency: "SAR" }
972
+ },
973
+ {
974
+ name: "countRate",
975
+ label: "countRate",
976
+ type: { kind: "integer" }
977
+ },
978
+ {
979
+ name: "principalRate",
980
+ label: "principalRate",
981
+ type: { kind: "integer" }
982
+ },
983
+ {
984
+ name: "restructuringEvidence",
985
+ label: "restructuringEvidence",
986
+ type: { kind: "text" }
987
+ },
988
+ {
989
+ name: "defaultDays",
990
+ label: "defaultDays",
991
+ type: { kind: "integer" }
992
+ },
993
+ {
994
+ name: "rateScale",
995
+ label: "rateScale",
996
+ type: { kind: "integer" }
997
+ }
998
+ ],
999
+ sort: [ "activeFacilities" ]
1000
+ },
1001
+ authority: {
1002
+ request: [ "owner", "finance" ],
1003
+ read: [ "owner", "admin", "operations", "finance", "viewer" ],
1004
+ release: [ ],
1005
+ independentApproval: true,
1006
+ retention: { policy: "report_replay", years: retention_years }
1007
+ }
1008
+ },
1009
+ {
1010
+ identity: { id: "bureau_facility", version: 1, description: "Bureau facility definition only. No submission, provider layout or transport is admitted until the member specification and required governed facts exist." },
1011
+ scope: { kind: "product", classification: "internal", currency: "SAR" },
1012
+ datasets: [
1013
+ {
1014
+ id: "facilities",
1015
+ source: "instrument",
1016
+ instruments: on,
1017
+ rowKey: "facilityId",
1018
+ columns: [
1019
+ {
1020
+ name: "facilityId",
1021
+ field: "id",
1022
+ type: { kind: "text" },
1023
+ required: true
1024
+ },
1025
+ {
1026
+ name: "borrowerAccount",
1027
+ field: "borrower",
1028
+ type: { kind: "text" },
1029
+ required: true
1030
+ },
1031
+ {
1032
+ name: "state",
1033
+ field: "status",
1034
+ type: { kind: "text" },
1035
+ required: true
1036
+ },
1037
+ {
1038
+ name: "originalPrincipal",
1039
+ field: "principal",
1040
+ type: { kind: "money", currency: "SAR" },
1041
+ required: true
1042
+ },
1043
+ {
1044
+ name: "scheduleCount",
1045
+ field: "months",
1046
+ type: { kind: "integer" },
1047
+ required: true
1048
+ },
1049
+ {
1050
+ name: "recordedCreation",
1051
+ field: "createdAt",
1052
+ type: { kind: "date" },
1053
+ required: true
1054
+ }
1055
+ ],
1056
+ expressions: [
1057
+ {
1058
+ id: "activeState",
1059
+ op: "literal",
1060
+ type: { kind: "text" },
1061
+ value: "active"
1062
+ },
1063
+ {
1064
+ id: "paidState",
1065
+ op: "literal",
1066
+ type: { kind: "text" },
1067
+ value: "paid"
1068
+ },
1069
+ {
1070
+ id: "writtenState",
1071
+ op: "literal",
1072
+ type: { kind: "text" },
1073
+ value: "written_off"
1074
+ },
1075
+ { id: "active", op: "equal", left: "state", right: "activeState" },
1076
+ { id: "paid", op: "equal", left: "state", right: "paidState" },
1077
+ { id: "writtenOff", op: "equal", left: "state", right: "writtenState" },
1078
+ { id: "activeOrPaid", op: "or", left: "active", right: "paid" },
1079
+ { id: "financed", op: "or", left: "active", right: "writtenOff" }
1080
+ ],
1081
+ selection: "financed"
1082
+ },
1083
+ {
1084
+ id: "schedule",
1085
+ source: "instrument",
1086
+ instruments: child(on, slice),
1087
+ rowKey: "sliceId",
1088
+ columns: [
1089
+ {
1090
+ name: "sliceId",
1091
+ field: "id",
1092
+ type: { kind: "text" },
1093
+ required: true
1094
+ },
1095
+ {
1096
+ name: "planId",
1097
+ field: "plan",
1098
+ type: { kind: "text" },
1099
+ required: true
1100
+ },
1101
+ {
1102
+ name: "due",
1103
+ field: "dueAt",
1104
+ type: { kind: "date" },
1105
+ required: true
1106
+ },
1107
+ {
1108
+ name: "principal",
1109
+ field: "principalReceivable.balance",
1110
+ type: { kind: "money", currency: "SAR" },
1111
+ required: true
1112
+ },
1113
+ {
1114
+ name: "profit",
1115
+ field: "profitReceivable.balance",
1116
+ type: { kind: "money", currency: "SAR" },
1117
+ required: true
1118
+ },
1119
+ {
1120
+ name: "scheduledPrincipal",
1121
+ field: "principal",
1122
+ type: { kind: "money", currency: "SAR" },
1123
+ required: true
1124
+ }
1125
+ ],
1126
+ expressions: [
1127
+ {
1128
+ id: "zeroMoney",
1129
+ op: "literal",
1130
+ type: { kind: "money", currency: "SAR" },
1131
+ value: "0"
1132
+ },
1133
+ {
1134
+ id: "zeroDays",
1135
+ op: "literal",
1136
+ type: { kind: "integer" },
1137
+ value: 0
1138
+ },
1139
+ { id: "observed", op: "parameter", name: "observationAt" },
1140
+ { id: "scheduledOutstanding", op: "sum", left: "principal", right: "profit" },
1141
+ { id: "unpaid", op: "less", left: "zeroMoney", right: "scheduledOutstanding" },
1142
+ { id: "elapsed", op: "daysBetween", left: "due", right: "observed" },
1143
+ { id: "nonnegativeDays", op: "maximum", left: "elapsed", right: "zeroDays" },
1144
+ { id: "daysPastDue", op: "choose", condition: "unpaid", yes: "nonnegativeDays", no: "zeroDays" }
1145
+ ]
1146
+ },
1147
+ {
1148
+ id: "borrowerAccounts",
1149
+ source: "account",
1150
+ instruments: [ ],
1151
+ rowKey: "accountId",
1152
+ columns: [
1153
+ {
1154
+ name: "accountId",
1155
+ field: "id",
1156
+ type: { kind: "text" },
1157
+ required: true
1158
+ },
1159
+ {
1160
+ name: "participant",
1161
+ field: "ownerParticipantId",
1162
+ type: { kind: "text" },
1163
+ required: false
1164
+ }
1165
+ ],
1166
+ expressions: [ ]
1167
+ },
1168
+ {
1169
+ id: "borrowers",
1170
+ source: "identity",
1171
+ instruments: [ ],
1172
+ rowKey: "customerId",
1173
+ columns: [
1174
+ {
1175
+ name: "customerId",
1176
+ field: "id",
1177
+ type: { kind: "text" },
1178
+ required: true
1179
+ },
1180
+ {
1181
+ name: "participantId",
1182
+ field: "participantId",
1183
+ type: { kind: "text" },
1184
+ required: true
1185
+ },
1186
+ {
1187
+ name: "entityId",
1188
+ field: "entityId",
1189
+ type: { kind: "text" },
1190
+ required: true
1191
+ }
1192
+ ],
1193
+ expressions: [ ]
1194
+ }
1195
+ ],
1196
+ time: { timezone: "Asia/Riyadh", boundary: "startInclusiveEndExclusive", observation: "periodEnd", history: "retainedOnly" },
1197
+ selection: { dataset: "facilities" },
1198
+ calculation: {
1199
+ joins: [
1200
+ {
1201
+ dataset: "schedule",
1202
+ local: "facilityId",
1203
+ foreign: "planId",
1204
+ cardinality: "many",
1205
+ missing: "refuse",
1206
+ aggregates: [
1207
+ { name: "outstandingPrincipal", op: "sum", value: "principal" },
1208
+ { name: "remainingScheduledProfit", op: "sum", value: "profit" },
1209
+ { name: "scheduledPrincipalTotal", op: "sum", value: "scheduledPrincipal" },
1210
+ { name: "capturedScheduleCount", op: "count" },
1211
+ { name: "oldestUnpaidDays", op: "maximum", value: "daysPastDue" }
1212
+ ]
1213
+ },
1214
+ {
1215
+ dataset: "borrowerAccounts",
1216
+ local: "borrowerAccount",
1217
+ foreign: "accountId",
1218
+ cardinality: "one",
1219
+ missing: "refuse",
1220
+ aggregates: [
1221
+ { name: "borrowerParticipant", op: "minimum", value: "participant" }
1222
+ ]
1223
+ },
1224
+ {
1225
+ dataset: "borrowers",
1226
+ local: "borrowerParticipant",
1227
+ foreign: "participantId",
1228
+ cardinality: "one",
1229
+ missing: "refuse",
1230
+ aggregates: [
1231
+ { name: "borrowerEntity", op: "minimum", value: "entityId" }
1232
+ ]
1233
+ }
1234
+ ],
1235
+ expressions: [ ],
1236
+ groupBy: [ ],
1237
+ aggregates: [ ],
1238
+ resultExpressions: [ ]
1239
+ },
1240
+ validation: {
1241
+ empty: "refuse",
1242
+ required: [ "borrowerEntity" ],
1243
+ reconcile: [ ],
1244
+ rowReconcile: [
1245
+ { left: "originalPrincipal", right: "scheduledPrincipalTotal" },
1246
+ { left: "scheduleCount", right: "capturedScheduleCount" }
1247
+ ],
1248
+ unavailableFacts: [ "approved member format contract", "versioned borrower identity and dispute facts", "business-effective origination and repayment allocation history" ],
1249
+ lockTimeoutMs: lock_wait_ms,
1250
+ captureTimeoutMs: capture_ms,
1251
+ maxRows: max_rows,
1252
+ maxJoinRows: max_join_rows,
1253
+ maxBytes: max_bytes
1254
+ },
1255
+ output: {
1256
+ profile: "internal.v1",
1257
+ formats: [ "json", "csv" ],
1258
+ columns: [
1259
+ {
1260
+ name: "facilityId",
1261
+ label: "facilityId",
1262
+ type: { kind: "text" }
1263
+ },
1264
+ {
1265
+ name: "borrowerEntity",
1266
+ label: "borrowerEntity",
1267
+ type: { kind: "text" }
1268
+ },
1269
+ {
1270
+ name: "outstandingPrincipal",
1271
+ label: "outstandingPrincipal",
1272
+ type: { kind: "money", currency: "SAR" }
1273
+ }
1274
+ ],
1275
+ sort: [ "facilityId" ]
1276
+ },
1277
+ authority: {
1278
+ request: [ "owner", "finance" ],
1279
+ read: [ "owner", "admin", "operations", "finance", "viewer" ],
1280
+ release: [ ],
1281
+ independentApproval: true,
1282
+ retention: { policy: "report_replay", years: retention_years }
1283
+ }
1284
+ }
1285
+ ]
1286
+ }