@hyperscale0/hsx 5.8.0 → 6.1.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 (45) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +3 -4
  3. package/bin/hsx.ts +0 -5
  4. package/dist/bin/hsx.d.ts +0 -4
  5. package/dist/bin/hsx.d.ts.map +1 -1
  6. package/dist/bin/hsx.js +0 -4
  7. package/dist/bin/hsx.js.map +1 -1
  8. package/dist/src/attachment-economics.d.ts +5 -0
  9. package/dist/src/attachment-economics.d.ts.map +1 -0
  10. package/dist/src/attachment-economics.js +55 -0
  11. package/dist/src/attachment-economics.js.map +1 -0
  12. package/dist/src/compile.d.ts.map +1 -1
  13. package/dist/src/compile.js +9 -21
  14. package/dist/src/compile.js.map +1 -1
  15. package/dist/src/examples-bundle.d.ts.map +1 -1
  16. package/dist/src/examples-bundle.js +3 -4
  17. package/dist/src/examples-bundle.js.map +1 -1
  18. package/dist/src/headers.d.ts +1 -1
  19. package/dist/src/headers.d.ts.map +1 -1
  20. package/dist/src/headers.js +0 -1
  21. package/dist/src/headers.js.map +1 -1
  22. package/dist/src/parse.js +2 -0
  23. package/dist/src/parse.js.map +1 -1
  24. package/dist/src/std-bundle.d.ts.map +1 -1
  25. package/dist/src/std-bundle.js +1 -2
  26. package/dist/src/std-bundle.js.map +1 -1
  27. package/dist/src/version.d.ts +1 -1
  28. package/dist/src/version.js +1 -1
  29. package/docs/README.md +39 -20
  30. package/examples/insurance.hsx +1 -0
  31. package/examples/money.hsx +1 -0
  32. package/examples/wallet.hsx +1 -0
  33. package/package.json +5 -6
  34. package/src/attachment-economics.ts +103 -0
  35. package/src/compile.ts +15 -22
  36. package/src/examples-bundle.ts +3 -4
  37. package/src/headers.ts +0 -1
  38. package/src/parse.ts +2 -0
  39. package/src/std-bundle.ts +1 -2
  40. package/src/version.ts +1 -1
  41. package/std/reporting.hsx +105 -676
  42. package/docs/examples.md +0 -22
  43. package/docs/headers.md +0 -46
  44. package/examples/travel.hsx +0 -29
  45. package/std/travel.hsx +0 -123
package/std/reporting.hsx CHANGED
@@ -6,9 +6,7 @@ header reporting
6
6
  // The default-rate report measures period-end stock, not new default incidence.
7
7
  // Paid facilities are excluded and write-offs counted separately. Amounts are SAR
8
8
  // minor units; declared scale and rounding govern ratios. Missing identity joins
9
- // or unreconciled schedule counts refuse. Origination cohorts and bureau output
10
- // explicitly refuse until their unavailable governed facts exist. No bureau
11
- // submission, provider layout, external transport or restructuring proof is supplied.
9
+ // or unreconciled schedule counts refuse.
12
10
 
13
11
  // Cost: portfolio.create declares no transfers, owned accounts or invocations.
14
12
  // That zero instruction count does not price report capture, rendering, storage or
@@ -376,7 +374,7 @@ instrument portfolio(on: ref<financing.installments>[], default_days: integer(1,
376
374
  }
377
375
  },
378
376
  {
379
- 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." },
377
+ 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." },
380
378
  scope: { kind: "product", classification: "internal", currency: "SAR" },
381
379
  datasets: [
382
380
  {
@@ -609,24 +607,78 @@ instrument portfolio(on: ref<financing.installments>[], default_days: integer(1,
609
607
  }
610
608
  ],
611
609
  expressions: [
612
- { id: "recordedMonth", op: "bucket", value: "recordedCreation", unit: "month" }
610
+ {
611
+ id: "threshold",
612
+ op: "literal",
613
+ type: { kind: "integer" },
614
+ value: default_days
615
+ },
616
+ {
617
+ id: "zero",
618
+ op: "literal",
619
+ type: { kind: "integer" },
620
+ value: 0
621
+ },
622
+ {
623
+ id: "one",
624
+ op: "literal",
625
+ type: { kind: "integer" },
626
+ value: 1
627
+ },
628
+ {
629
+ id: "zeroMoney",
630
+ op: "literal",
631
+ type: { kind: "money", currency: "SAR" },
632
+ value: "0"
633
+ },
634
+ { id: "pastThreshold", op: "atMost", left: "threshold", right: "oldestUnpaidDays" },
635
+ { id: "isDefault", op: "and", left: "active", right: "pastThreshold" },
636
+ { id: "activeCount", op: "choose", condition: "active", yes: "one", no: "zero" },
637
+ { id: "defaultCount", op: "choose", condition: "isDefault", yes: "one", no: "zero" },
638
+ { id: "writeOffCount", op: "choose", condition: "writtenOff", yes: "one", no: "zero" },
639
+ { id: "activePrincipal", op: "choose", condition: "active", yes: "outstandingPrincipal", no: "zeroMoney" },
640
+ { id: "defaultPrincipal", op: "choose", condition: "isDefault", yes: "outstandingPrincipal", no: "zeroMoney" }
613
641
  ],
614
- groupBy: [ "recordedMonth" ],
642
+ groupBy: [ ],
615
643
  aggregates: [
616
- { name: "facilities", op: "count" },
617
- { name: "principalMinor", op: "sum", value: "outstandingPrincipal" }
644
+ { name: "activeFacilities", op: "sum", value: "activeCount" },
645
+ { name: "defaultFacilities", op: "sum", value: "defaultCount" },
646
+ { name: "writtenOffFacilities", op: "sum", value: "writeOffCount" },
647
+ { name: "activePrincipalMinor", op: "sum", value: "activePrincipal" },
648
+ { name: "defaultPrincipalMinor", op: "sum", value: "defaultPrincipal" }
618
649
  ],
619
- resultExpressions: [ ]
650
+ resultExpressions: [
651
+ { id: "countRate", op: "ratio", numerator: "defaultFacilities", denominator: "activeFacilities", scale: ratio_scale, rounding: ratio_rounding, zero: "null" },
652
+ { id: "principalRate", op: "ratio", numerator: "defaultPrincipalMinor", denominator: "activePrincipalMinor", scale: ratio_scale, rounding: ratio_rounding, zero: "null" },
653
+ {
654
+ id: "restructuringEvidence",
655
+ op: "literal",
656
+ type: { kind: "text" },
657
+ value: "unavailable"
658
+ },
659
+ {
660
+ id: "defaultDays",
661
+ op: "literal",
662
+ type: { kind: "integer" },
663
+ value: default_days
664
+ },
665
+ {
666
+ id: "rateScale",
667
+ op: "literal",
668
+ type: { kind: "integer" },
669
+ value: ratio_scale
670
+ }
671
+ ]
620
672
  },
621
673
  validation: {
622
- empty: "noEligibleFacilities",
674
+ empty: "refuse",
623
675
  required: [ "borrowerEntity" ],
624
676
  reconcile: [ ],
625
677
  rowReconcile: [
626
678
  { left: "originalPrincipal", right: "scheduledPrincipalTotal" },
627
679
  { left: "scheduleCount", right: "capturedScheduleCount" }
628
680
  ],
629
- unavailableFacts: [ "business-effective origination timestamp", "dated repayment allocation and recovery history" ],
681
+ unavailableFacts: [ ],
630
682
  lockTimeoutMs: lock_wait_ms,
631
683
  captureTimeoutMs: capture_ms,
632
684
  maxRows: max_rows,
@@ -638,395 +690,54 @@ instrument portfolio(on: ref<financing.installments>[], default_days: integer(1,
638
690
  formats: [ "json", "csv" ],
639
691
  columns: [
640
692
  {
641
- name: "recordedMonth",
642
- label: "recordedMonth",
643
- type: { kind: "text" }
693
+ name: "activeFacilities",
694
+ label: "activeFacilities",
695
+ type: { kind: "integer" }
644
696
  },
645
697
  {
646
- name: "facilities",
647
- label: "facilities",
698
+ name: "defaultFacilities",
699
+ label: "defaultFacilities",
648
700
  type: { kind: "integer" }
649
701
  },
650
702
  {
651
- name: "principalMinor",
652
- label: "principalMinor",
703
+ name: "writtenOffFacilities",
704
+ label: "writtenOffFacilities",
705
+ type: { kind: "integer" }
706
+ },
707
+ {
708
+ name: "activePrincipalMinor",
709
+ label: "activePrincipalMinor",
710
+ type: { kind: "money", currency: "SAR" }
711
+ },
712
+ {
713
+ name: "defaultPrincipalMinor",
714
+ label: "defaultPrincipalMinor",
653
715
  type: { kind: "money", currency: "SAR" }
654
- }
655
- ],
656
- sort: [ "recordedMonth" ]
657
- },
658
- authority: {
659
- request: [ "owner", "finance" ],
660
- read: [ "owner", "admin", "operations", "finance", "viewer" ],
661
- release: [ ],
662
- retention: { policy: "report_replay", years: retention_years }
663
- }
664
- },
665
- {
666
- 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." },
667
- scope: { kind: "product", classification: "internal", currency: "SAR" },
668
- datasets: [
669
- {
670
- id: "facilities",
671
- source: "instrument",
672
- instruments: on,
673
- rowKey: "facilityId",
674
- columns: [
675
- {
676
- name: "facilityId",
677
- field: "id",
678
- type: { kind: "text" },
679
- required: true
680
- },
681
- {
682
- name: "borrowerAccount",
683
- field: "borrower",
684
- type: { kind: "text" },
685
- required: true
686
- },
687
- {
688
- name: "state",
689
- field: "status",
690
- type: { kind: "text" },
691
- required: true
692
- },
693
- {
694
- name: "originalPrincipal",
695
- field: "principal",
696
- type: { kind: "money", currency: "SAR" },
697
- required: true
698
- },
699
- {
700
- name: "scheduleCount",
701
- field: "months",
702
- type: { kind: "integer" },
703
- required: true
704
- },
705
- {
706
- name: "recordedCreation",
707
- field: "createdAt",
708
- type: { kind: "date" },
709
- required: true
710
- }
711
- ],
712
- expressions: [
713
- {
714
- id: "activeState",
715
- op: "literal",
716
- type: { kind: "text" },
717
- value: "active"
718
- },
719
- {
720
- id: "paidState",
721
- op: "literal",
722
- type: { kind: "text" },
723
- value: "paid"
724
- },
725
- {
726
- id: "writtenState",
727
- op: "literal",
728
- type: { kind: "text" },
729
- value: "written_off"
730
- },
731
- { id: "active", op: "equal", left: "state", right: "activeState" },
732
- { id: "paid", op: "equal", left: "state", right: "paidState" },
733
- { id: "writtenOff", op: "equal", left: "state", right: "writtenState" },
734
- { id: "activeOrPaid", op: "or", left: "active", right: "paid" },
735
- { id: "financed", op: "or", left: "active", right: "writtenOff" }
736
- ],
737
- selection: "financed"
738
- },
739
- {
740
- id: "schedule",
741
- source: "instrument",
742
- instruments: child(on, slice),
743
- rowKey: "sliceId",
744
- columns: [
745
- {
746
- name: "sliceId",
747
- field: "id",
748
- type: { kind: "text" },
749
- required: true
750
- },
751
- {
752
- name: "planId",
753
- field: "plan",
754
- type: { kind: "text" },
755
- required: true
756
- },
757
- {
758
- name: "due",
759
- field: "dueAt",
760
- type: { kind: "date" },
761
- required: true
762
- },
763
- {
764
- name: "principal",
765
- field: "principalReceivable.balance",
766
- type: { kind: "money", currency: "SAR" },
767
- required: true
768
- },
769
- {
770
- name: "profit",
771
- field: "profitReceivable.balance",
772
- type: { kind: "money", currency: "SAR" },
773
- required: true
774
- },
775
- {
776
- name: "earnedProfit",
777
- field: "profitEarned.balance",
778
- type: { kind: "money", currency: "SAR" },
779
- required: true
780
- },
781
- {
782
- name: "scheduledPrincipal",
783
- field: "principal",
784
- type: { kind: "money", currency: "SAR" },
785
- required: true
786
- }
787
- ],
788
- expressions: [
789
- {
790
- id: "zeroMoney",
791
- op: "literal",
792
- type: { kind: "money", currency: "SAR" },
793
- value: "0"
794
- },
795
- {
796
- id: "zeroDays",
797
- op: "literal",
798
- type: { kind: "integer" },
799
- value: 0
800
- },
801
- { id: "observed", op: "parameter", name: "observationAt" },
802
- { id: "scheduledOutstanding", op: "sum", left: "principal", right: "profit" },
803
- { id: "totalOutstanding", op: "sum", left: "scheduledOutstanding", right: "earnedProfit" },
804
- { id: "unpaid", op: "less", left: "zeroMoney", right: "totalOutstanding" },
805
- { id: "elapsed", op: "daysBetween", left: "due", right: "observed" },
806
- { id: "nonnegativeDays", op: "maximum", left: "elapsed", right: "zeroDays" },
807
- { id: "daysPastDue", op: "choose", condition: "unpaid", yes: "nonnegativeDays", no: "zeroDays" }
808
- ]
809
- },
810
- {
811
- id: "borrowerAccounts",
812
- source: "account",
813
- instruments: [ ],
814
- rowKey: "accountId",
815
- columns: [
816
- {
817
- name: "accountId",
818
- field: "id",
819
- type: { kind: "text" },
820
- required: true
821
- },
822
- {
823
- name: "participant",
824
- field: "ownerParticipantId",
825
- type: { kind: "text" },
826
- required: false
827
- }
828
- ],
829
- expressions: [ ]
830
- },
831
- {
832
- id: "borrowers",
833
- source: "identity",
834
- instruments: [ ],
835
- rowKey: "customerId",
836
- columns: [
837
- {
838
- name: "customerId",
839
- field: "id",
840
- type: { kind: "text" },
841
- required: true
842
- },
843
- {
844
- name: "participantId",
845
- field: "participantId",
846
- type: { kind: "text" },
847
- required: true
848
- },
849
- {
850
- name: "entityId",
851
- field: "entityId",
852
- type: { kind: "text" },
853
- required: true
854
- }
855
- ],
856
- expressions: [ ]
857
- }
858
- ],
859
- time: { timezone: "Asia/Riyadh", boundary: "startInclusiveEndExclusive", observation: "periodEnd", history: "retainedOnly" },
860
- selection: { dataset: "facilities" },
861
- calculation: {
862
- joins: [
863
- {
864
- dataset: "schedule",
865
- local: "facilityId",
866
- foreign: "planId",
867
- cardinality: "many",
868
- missing: "refuse",
869
- aggregates: [
870
- { name: "outstandingPrincipal", op: "sum", value: "principal" },
871
- { name: "remainingScheduledProfit", op: "sum", value: "profit" },
872
- { name: "scheduledPrincipalTotal", op: "sum", value: "scheduledPrincipal" },
873
- { name: "capturedScheduleCount", op: "count" },
874
- { name: "oldestUnpaidDays", op: "maximum", value: "daysPastDue" }
875
- ]
876
- },
877
- {
878
- dataset: "borrowerAccounts",
879
- local: "borrowerAccount",
880
- foreign: "accountId",
881
- cardinality: "one",
882
- missing: "refuse",
883
- aggregates: [
884
- { name: "borrowerParticipant", op: "minimum", value: "participant" }
885
- ]
886
- },
887
- {
888
- dataset: "borrowers",
889
- local: "borrowerParticipant",
890
- foreign: "participantId",
891
- cardinality: "one",
892
- missing: "refuse",
893
- aggregates: [
894
- { name: "borrowerEntity", op: "minimum", value: "entityId" }
895
- ]
896
- }
897
- ],
898
- expressions: [
899
- {
900
- id: "threshold",
901
- op: "literal",
902
- type: { kind: "integer" },
903
- value: default_days
904
- },
905
- {
906
- id: "zero",
907
- op: "literal",
908
- type: { kind: "integer" },
909
- value: 0
910
- },
911
- {
912
- id: "one",
913
- op: "literal",
914
- type: { kind: "integer" },
915
- value: 1
916
- },
917
- {
918
- id: "zeroMoney",
919
- op: "literal",
920
- type: { kind: "money", currency: "SAR" },
921
- value: "0"
922
- },
923
- { id: "pastThreshold", op: "atMost", left: "threshold", right: "oldestUnpaidDays" },
924
- { id: "isDefault", op: "and", left: "active", right: "pastThreshold" },
925
- { id: "activeCount", op: "choose", condition: "active", yes: "one", no: "zero" },
926
- { id: "defaultCount", op: "choose", condition: "isDefault", yes: "one", no: "zero" },
927
- { id: "writeOffCount", op: "choose", condition: "writtenOff", yes: "one", no: "zero" },
928
- { id: "activePrincipal", op: "choose", condition: "active", yes: "outstandingPrincipal", no: "zeroMoney" },
929
- { id: "defaultPrincipal", op: "choose", condition: "isDefault", yes: "outstandingPrincipal", no: "zeroMoney" }
930
- ],
931
- groupBy: [ ],
932
- aggregates: [
933
- { name: "activeFacilities", op: "sum", value: "activeCount" },
934
- { name: "defaultFacilities", op: "sum", value: "defaultCount" },
935
- { name: "writtenOffFacilities", op: "sum", value: "writeOffCount" },
936
- { name: "activePrincipalMinor", op: "sum", value: "activePrincipal" },
937
- { name: "defaultPrincipalMinor", op: "sum", value: "defaultPrincipal" }
938
- ],
939
- resultExpressions: [
940
- { id: "countRate", op: "ratio", numerator: "defaultFacilities", denominator: "activeFacilities", scale: ratio_scale, rounding: ratio_rounding, zero: "null" },
941
- { id: "principalRate", op: "ratio", numerator: "defaultPrincipalMinor", denominator: "activePrincipalMinor", scale: ratio_scale, rounding: ratio_rounding, zero: "null" },
942
- {
943
- id: "restructuringEvidence",
944
- op: "literal",
945
- type: { kind: "text" },
946
- value: "unavailable"
947
- },
948
- {
949
- id: "defaultDays",
950
- op: "literal",
951
- type: { kind: "integer" },
952
- value: default_days
953
- },
954
- {
955
- id: "rateScale",
956
- op: "literal",
957
- type: { kind: "integer" },
958
- value: ratio_scale
959
- }
960
- ]
961
- },
962
- validation: {
963
- empty: "refuse",
964
- required: [ "borrowerEntity" ],
965
- reconcile: [ ],
966
- rowReconcile: [
967
- { left: "originalPrincipal", right: "scheduledPrincipalTotal" },
968
- { left: "scheduleCount", right: "capturedScheduleCount" }
969
- ],
970
- unavailableFacts: [ ],
971
- lockTimeoutMs: lock_wait_ms,
972
- captureTimeoutMs: capture_ms,
973
- maxRows: max_rows,
974
- maxJoinRows: max_join_rows,
975
- maxBytes: max_bytes
976
- },
977
- output: {
978
- profile: "internal.v1",
979
- formats: [ "json", "csv" ],
980
- columns: [
981
- {
982
- name: "activeFacilities",
983
- label: "activeFacilities",
984
- type: { kind: "integer" }
985
- },
986
- {
987
- name: "defaultFacilities",
988
- label: "defaultFacilities",
989
- type: { kind: "integer" }
990
- },
991
- {
992
- name: "writtenOffFacilities",
993
- label: "writtenOffFacilities",
994
- type: { kind: "integer" }
995
- },
996
- {
997
- name: "activePrincipalMinor",
998
- label: "activePrincipalMinor",
999
- type: { kind: "money", currency: "SAR" }
1000
- },
1001
- {
1002
- name: "defaultPrincipalMinor",
1003
- label: "defaultPrincipalMinor",
1004
- type: { kind: "money", currency: "SAR" }
1005
- },
1006
- {
1007
- name: "countRate",
1008
- label: "countRate",
1009
- type: { kind: "integer" }
1010
- },
1011
- {
1012
- name: "principalRate",
1013
- label: "principalRate",
1014
- type: { kind: "integer" }
1015
- },
1016
- {
1017
- name: "restructuringEvidence",
1018
- label: "restructuringEvidence",
1019
- type: { kind: "text" }
1020
- },
1021
- {
1022
- name: "defaultDays",
1023
- label: "defaultDays",
1024
- type: { kind: "integer" }
1025
- },
1026
- {
1027
- name: "rateScale",
1028
- label: "rateScale",
1029
- type: { kind: "integer" }
716
+ },
717
+ {
718
+ name: "countRate",
719
+ label: "countRate",
720
+ type: { kind: "integer" }
721
+ },
722
+ {
723
+ name: "principalRate",
724
+ label: "principalRate",
725
+ type: { kind: "integer" }
726
+ },
727
+ {
728
+ name: "restructuringEvidence",
729
+ label: "restructuringEvidence",
730
+ type: { kind: "text" }
731
+ },
732
+ {
733
+ name: "defaultDays",
734
+ label: "defaultDays",
735
+ type: { kind: "integer" }
736
+ },
737
+ {
738
+ name: "rateScale",
739
+ label: "rateScale",
740
+ type: { kind: "integer" }
1030
741
  }
1031
742
  ],
1032
743
  sort: [ "activeFacilities" ]
@@ -1037,288 +748,6 @@ instrument portfolio(on: ref<financing.installments>[], default_days: integer(1,
1037
748
  release: [ ],
1038
749
  retention: { policy: "report_replay", years: retention_years }
1039
750
  }
1040
- },
1041
- {
1042
- 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." },
1043
- scope: { kind: "product", classification: "internal", currency: "SAR" },
1044
- datasets: [
1045
- {
1046
- id: "facilities",
1047
- source: "instrument",
1048
- instruments: on,
1049
- rowKey: "facilityId",
1050
- columns: [
1051
- {
1052
- name: "facilityId",
1053
- field: "id",
1054
- type: { kind: "text" },
1055
- required: true
1056
- },
1057
- {
1058
- name: "borrowerAccount",
1059
- field: "borrower",
1060
- type: { kind: "text" },
1061
- required: true
1062
- },
1063
- {
1064
- name: "state",
1065
- field: "status",
1066
- type: { kind: "text" },
1067
- required: true
1068
- },
1069
- {
1070
- name: "originalPrincipal",
1071
- field: "principal",
1072
- type: { kind: "money", currency: "SAR" },
1073
- required: true
1074
- },
1075
- {
1076
- name: "scheduleCount",
1077
- field: "months",
1078
- type: { kind: "integer" },
1079
- required: true
1080
- },
1081
- {
1082
- name: "recordedCreation",
1083
- field: "createdAt",
1084
- type: { kind: "date" },
1085
- required: true
1086
- }
1087
- ],
1088
- expressions: [
1089
- {
1090
- id: "activeState",
1091
- op: "literal",
1092
- type: { kind: "text" },
1093
- value: "active"
1094
- },
1095
- {
1096
- id: "paidState",
1097
- op: "literal",
1098
- type: { kind: "text" },
1099
- value: "paid"
1100
- },
1101
- {
1102
- id: "writtenState",
1103
- op: "literal",
1104
- type: { kind: "text" },
1105
- value: "written_off"
1106
- },
1107
- { id: "active", op: "equal", left: "state", right: "activeState" },
1108
- { id: "paid", op: "equal", left: "state", right: "paidState" },
1109
- { id: "writtenOff", op: "equal", left: "state", right: "writtenState" },
1110
- { id: "activeOrPaid", op: "or", left: "active", right: "paid" },
1111
- { id: "financed", op: "or", left: "active", right: "writtenOff" }
1112
- ],
1113
- selection: "financed"
1114
- },
1115
- {
1116
- id: "schedule",
1117
- source: "instrument",
1118
- instruments: child(on, slice),
1119
- rowKey: "sliceId",
1120
- columns: [
1121
- {
1122
- name: "sliceId",
1123
- field: "id",
1124
- type: { kind: "text" },
1125
- required: true
1126
- },
1127
- {
1128
- name: "planId",
1129
- field: "plan",
1130
- type: { kind: "text" },
1131
- required: true
1132
- },
1133
- {
1134
- name: "due",
1135
- field: "dueAt",
1136
- type: { kind: "date" },
1137
- required: true
1138
- },
1139
- {
1140
- name: "principal",
1141
- field: "principalReceivable.balance",
1142
- type: { kind: "money", currency: "SAR" },
1143
- required: true
1144
- },
1145
- {
1146
- name: "profit",
1147
- field: "profitReceivable.balance",
1148
- type: { kind: "money", currency: "SAR" },
1149
- required: true
1150
- },
1151
- {
1152
- name: "earnedProfit",
1153
- field: "profitEarned.balance",
1154
- type: { kind: "money", currency: "SAR" },
1155
- required: true
1156
- },
1157
- {
1158
- name: "scheduledPrincipal",
1159
- field: "principal",
1160
- type: { kind: "money", currency: "SAR" },
1161
- required: true
1162
- }
1163
- ],
1164
- expressions: [
1165
- {
1166
- id: "zeroMoney",
1167
- op: "literal",
1168
- type: { kind: "money", currency: "SAR" },
1169
- value: "0"
1170
- },
1171
- {
1172
- id: "zeroDays",
1173
- op: "literal",
1174
- type: { kind: "integer" },
1175
- value: 0
1176
- },
1177
- { id: "observed", op: "parameter", name: "observationAt" },
1178
- { id: "scheduledOutstanding", op: "sum", left: "principal", right: "profit" },
1179
- { id: "totalOutstanding", op: "sum", left: "scheduledOutstanding", right: "earnedProfit" },
1180
- { id: "unpaid", op: "less", left: "zeroMoney", right: "totalOutstanding" },
1181
- { id: "elapsed", op: "daysBetween", left: "due", right: "observed" },
1182
- { id: "nonnegativeDays", op: "maximum", left: "elapsed", right: "zeroDays" },
1183
- { id: "daysPastDue", op: "choose", condition: "unpaid", yes: "nonnegativeDays", no: "zeroDays" }
1184
- ]
1185
- },
1186
- {
1187
- id: "borrowerAccounts",
1188
- source: "account",
1189
- instruments: [ ],
1190
- rowKey: "accountId",
1191
- columns: [
1192
- {
1193
- name: "accountId",
1194
- field: "id",
1195
- type: { kind: "text" },
1196
- required: true
1197
- },
1198
- {
1199
- name: "participant",
1200
- field: "ownerParticipantId",
1201
- type: { kind: "text" },
1202
- required: false
1203
- }
1204
- ],
1205
- expressions: [ ]
1206
- },
1207
- {
1208
- id: "borrowers",
1209
- source: "identity",
1210
- instruments: [ ],
1211
- rowKey: "customerId",
1212
- columns: [
1213
- {
1214
- name: "customerId",
1215
- field: "id",
1216
- type: { kind: "text" },
1217
- required: true
1218
- },
1219
- {
1220
- name: "participantId",
1221
- field: "participantId",
1222
- type: { kind: "text" },
1223
- required: true
1224
- },
1225
- {
1226
- name: "entityId",
1227
- field: "entityId",
1228
- type: { kind: "text" },
1229
- required: true
1230
- }
1231
- ],
1232
- expressions: [ ]
1233
- }
1234
- ],
1235
- time: { timezone: "Asia/Riyadh", boundary: "startInclusiveEndExclusive", observation: "periodEnd", history: "retainedOnly" },
1236
- selection: { dataset: "facilities" },
1237
- calculation: {
1238
- joins: [
1239
- {
1240
- dataset: "schedule",
1241
- local: "facilityId",
1242
- foreign: "planId",
1243
- cardinality: "many",
1244
- missing: "refuse",
1245
- aggregates: [
1246
- { name: "outstandingPrincipal", op: "sum", value: "principal" },
1247
- { name: "remainingScheduledProfit", op: "sum", value: "profit" },
1248
- { name: "scheduledPrincipalTotal", op: "sum", value: "scheduledPrincipal" },
1249
- { name: "capturedScheduleCount", op: "count" },
1250
- { name: "oldestUnpaidDays", op: "maximum", value: "daysPastDue" }
1251
- ]
1252
- },
1253
- {
1254
- dataset: "borrowerAccounts",
1255
- local: "borrowerAccount",
1256
- foreign: "accountId",
1257
- cardinality: "one",
1258
- missing: "refuse",
1259
- aggregates: [
1260
- { name: "borrowerParticipant", op: "minimum", value: "participant" }
1261
- ]
1262
- },
1263
- {
1264
- dataset: "borrowers",
1265
- local: "borrowerParticipant",
1266
- foreign: "participantId",
1267
- cardinality: "one",
1268
- missing: "refuse",
1269
- aggregates: [
1270
- { name: "borrowerEntity", op: "minimum", value: "entityId" }
1271
- ]
1272
- }
1273
- ],
1274
- expressions: [ ],
1275
- groupBy: [ ],
1276
- aggregates: [ ],
1277
- resultExpressions: [ ]
1278
- },
1279
- validation: {
1280
- empty: "refuse",
1281
- required: [ "borrowerEntity" ],
1282
- reconcile: [ ],
1283
- rowReconcile: [
1284
- { left: "originalPrincipal", right: "scheduledPrincipalTotal" },
1285
- { left: "scheduleCount", right: "capturedScheduleCount" }
1286
- ],
1287
- unavailableFacts: [ "approved member format contract", "versioned borrower identity and dispute facts", "business-effective origination and repayment allocation history" ],
1288
- lockTimeoutMs: lock_wait_ms,
1289
- captureTimeoutMs: capture_ms,
1290
- maxRows: max_rows,
1291
- maxJoinRows: max_join_rows,
1292
- maxBytes: max_bytes
1293
- },
1294
- output: {
1295
- profile: "internal.v1",
1296
- formats: [ "json", "csv" ],
1297
- columns: [
1298
- {
1299
- name: "facilityId",
1300
- label: "facilityId",
1301
- type: { kind: "text" }
1302
- },
1303
- {
1304
- name: "borrowerEntity",
1305
- label: "borrowerEntity",
1306
- type: { kind: "text" }
1307
- },
1308
- {
1309
- name: "outstandingPrincipal",
1310
- label: "outstandingPrincipal",
1311
- type: { kind: "money", currency: "SAR" }
1312
- }
1313
- ],
1314
- sort: [ "facilityId" ]
1315
- },
1316
- authority: {
1317
- request: [ "owner", "finance" ],
1318
- read: [ "owner", "admin", "operations", "finance", "viewer" ],
1319
- release: [ ],
1320
- retention: { policy: "report_replay", years: retention_years }
1321
- }
1322
751
  }
1323
752
  ]
1324
753
  }