@finsys/core 2.4.0 → 2.6.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.
- package/dist/data/adapter-categories.json +156 -0
- package/dist/data/form-field-base-specs.json +0 -20
- package/dist/index.cjs +274 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +467 -1
- package/dist/index.d.ts +467 -1
- package/dist/index.js +267 -36
- package/dist/index.js.map +1 -1
- package/dist/schema/adapter-manifest.schema.json +101 -0
- package/package.json +6 -1
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
ALL_AGGREGATION_OPS: () => ALL_AGGREGATION_OPS,
|
|
34
|
+
AdapterError: () => AdapterError,
|
|
33
35
|
BASE_FIELD_SPECS: () => BASE_FIELD_SPECS,
|
|
34
36
|
BasicFormField: () => BasicFormField,
|
|
35
37
|
DEFAULT_VALIDATOR_DEFINITIONS: () => DEFAULT_VALIDATOR_DEFINITIONS,
|
|
@@ -50,8 +52,13 @@ __export(index_exports, {
|
|
|
50
52
|
IhsStatus: () => IhsStatus,
|
|
51
53
|
IhsValueFormat: () => IhsValueFormat,
|
|
52
54
|
Role: () => Role,
|
|
55
|
+
allCategories: () => allCategories,
|
|
56
|
+
applyAggregation: () => applyAggregation,
|
|
53
57
|
applyDynamicTitles: () => applyDynamicTitles,
|
|
54
58
|
buildFileFieldTables: () => buildFileFieldTables,
|
|
59
|
+
categoryFieldsOf: () => categoryFieldsOf,
|
|
60
|
+
categoryForField: () => categoryForField,
|
|
61
|
+
categorySchemaOf: () => categorySchemaOf,
|
|
55
62
|
evaluateExpression: () => evaluateExpression,
|
|
56
63
|
extractTimePeriods: () => extractTimePeriods,
|
|
57
64
|
generateRHFSchema: () => generateRHFSchema,
|
|
@@ -95,7 +102,7 @@ function getPastYearLabel(yearsAgo) {
|
|
|
95
102
|
const date = /* @__PURE__ */ new Date();
|
|
96
103
|
return (date.getFullYear() - yearsAgo).toString();
|
|
97
104
|
}
|
|
98
|
-
function evaluateExpression(expression,
|
|
105
|
+
function evaluateExpression(expression, data2) {
|
|
99
106
|
if (!expression) return true;
|
|
100
107
|
try {
|
|
101
108
|
let jsExpression = expression.replace(/\{([^}]+)\}/g, (_, key) => {
|
|
@@ -119,7 +126,7 @@ function evaluateExpression(expression, data) {
|
|
|
119
126
|
(_, ref, val) => `!(${ref} || []).includes('${val}')`
|
|
120
127
|
);
|
|
121
128
|
const func = new Function(`return ${jsExpression};`);
|
|
122
|
-
return !!func.call(
|
|
129
|
+
return !!func.call(data2 || {});
|
|
123
130
|
} catch (e) {
|
|
124
131
|
return false;
|
|
125
132
|
}
|
|
@@ -265,16 +272,16 @@ function groupFieldsByCategory(fields, categories) {
|
|
|
265
272
|
// src/rhf-generator.ts
|
|
266
273
|
var import_zod = require("zod");
|
|
267
274
|
function applyVisibilityValidation(baseObject, fields) {
|
|
268
|
-
return baseObject.superRefine((
|
|
275
|
+
return baseObject.superRefine((data2, ctx) => {
|
|
269
276
|
fields.forEach((field) => {
|
|
270
277
|
const isRequired = field.isRequired !== false && field.required !== false && field.type !== "html";
|
|
271
278
|
if (!isRequired) return;
|
|
272
279
|
let isVisible = field.visible !== false;
|
|
273
280
|
if (isVisible && field.visibleIf) {
|
|
274
|
-
isVisible = evaluateExpression(field.visibleIf,
|
|
281
|
+
isVisible = evaluateExpression(field.visibleIf, data2);
|
|
275
282
|
}
|
|
276
283
|
if (isVisible) {
|
|
277
|
-
const value =
|
|
284
|
+
const value = data2[field.name];
|
|
278
285
|
const isEmpty = value === void 0 || value === null || value === "" || Array.isArray(value) && value.length === 0;
|
|
279
286
|
if (isEmpty) {
|
|
280
287
|
ctx.addIssue({
|
|
@@ -735,22 +742,22 @@ var ajv = new Ajv({ allErrors: true, strict: false });
|
|
|
735
742
|
var addFormatsFn = import_ajv_formats.default.default || import_ajv_formats.default;
|
|
736
743
|
addFormatsFn(ajv);
|
|
737
744
|
ajv.addSchema(unified_form_schema_default, "unified-form.schema.json");
|
|
738
|
-
function validateFormConfig(
|
|
745
|
+
function validateFormConfig(data2) {
|
|
739
746
|
const validate = ajv.getSchema("unified-form.schema.json");
|
|
740
747
|
if (!validate) {
|
|
741
748
|
return { valid: false, message: "Could not load unified form schema" };
|
|
742
749
|
}
|
|
743
|
-
const valid = validate(
|
|
750
|
+
const valid = validate(data2);
|
|
744
751
|
return {
|
|
745
752
|
valid: !!valid,
|
|
746
753
|
errors: validate.errors || void 0
|
|
747
754
|
};
|
|
748
755
|
}
|
|
749
|
-
function validateFormSpec(
|
|
750
|
-
return validateFormConfig(
|
|
756
|
+
function validateFormSpec(data2) {
|
|
757
|
+
return validateFormConfig(data2);
|
|
751
758
|
}
|
|
752
|
-
function validatePagesConfig(
|
|
753
|
-
return validateFormConfig(
|
|
759
|
+
function validatePagesConfig(data2) {
|
|
760
|
+
return validateFormConfig(data2);
|
|
754
761
|
}
|
|
755
762
|
|
|
756
763
|
// src/form-field-category.ts
|
|
@@ -1207,10 +1214,10 @@ var _FormSpec = class _FormSpec {
|
|
|
1207
1214
|
if (Array.isArray(jsonData.fields)) {
|
|
1208
1215
|
fieldObjects = jsonData.fields;
|
|
1209
1216
|
} else if (typeof jsonData.fields === "object" && jsonData.fields !== null) {
|
|
1210
|
-
fieldObjects = Object.entries(jsonData.fields).map(([name,
|
|
1217
|
+
fieldObjects = Object.entries(jsonData.fields).map(([name, data2]) => {
|
|
1211
1218
|
return {
|
|
1212
1219
|
name,
|
|
1213
|
-
...
|
|
1220
|
+
...data2
|
|
1214
1221
|
};
|
|
1215
1222
|
});
|
|
1216
1223
|
}
|
|
@@ -7974,7 +7981,6 @@ var form_field_base_specs_default = {
|
|
|
7974
7981
|
name: "bank_statement_t1",
|
|
7975
7982
|
displayName: "Bank Statement (Month T-1)",
|
|
7976
7983
|
type: "file",
|
|
7977
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
7978
7984
|
ihs_column_names: [
|
|
7979
7985
|
"accountHolderNameT1",
|
|
7980
7986
|
"statementDateT1",
|
|
@@ -7991,7 +7997,6 @@ var form_field_base_specs_default = {
|
|
|
7991
7997
|
name: "bank_statement_t2",
|
|
7992
7998
|
displayName: "Bank Statement (Month T-2)",
|
|
7993
7999
|
type: "file",
|
|
7994
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
7995
8000
|
ihs_column_names: [
|
|
7996
8001
|
"accountHolderNameT2",
|
|
7997
8002
|
"statementDateT2",
|
|
@@ -8008,7 +8013,6 @@ var form_field_base_specs_default = {
|
|
|
8008
8013
|
name: "bank_statement_t3",
|
|
8009
8014
|
displayName: "Bank Statement (Month T-3)",
|
|
8010
8015
|
type: "file",
|
|
8011
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8012
8016
|
ihs_column_names: [
|
|
8013
8017
|
"accountHolderNameT3",
|
|
8014
8018
|
"statementDateT3",
|
|
@@ -8025,7 +8029,6 @@ var form_field_base_specs_default = {
|
|
|
8025
8029
|
name: "bank_statement_t4",
|
|
8026
8030
|
displayName: "Bank Statement (Month T-4)",
|
|
8027
8031
|
type: "file",
|
|
8028
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8029
8032
|
ihs_column_names: [
|
|
8030
8033
|
"accountHolderNameT4",
|
|
8031
8034
|
"statementDateT4",
|
|
@@ -8042,7 +8045,6 @@ var form_field_base_specs_default = {
|
|
|
8042
8045
|
name: "bank_statement_t5",
|
|
8043
8046
|
displayName: "Bank Statement (Month T-5)",
|
|
8044
8047
|
type: "file",
|
|
8045
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8046
8048
|
ihs_column_names: [
|
|
8047
8049
|
"accountHolderNameT5",
|
|
8048
8050
|
"statementDateT5",
|
|
@@ -8059,7 +8061,6 @@ var form_field_base_specs_default = {
|
|
|
8059
8061
|
name: "bank_statement_t6",
|
|
8060
8062
|
displayName: "Bank Statement (Month T-6)",
|
|
8061
8063
|
type: "file",
|
|
8062
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8063
8064
|
ihs_column_names: [
|
|
8064
8065
|
"accountHolderNameT6",
|
|
8065
8066
|
"statementDateT6",
|
|
@@ -8076,7 +8077,6 @@ var form_field_base_specs_default = {
|
|
|
8076
8077
|
name: "financials",
|
|
8077
8078
|
displayName: "Audited Financial Statement",
|
|
8078
8079
|
type: "file",
|
|
8079
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8080
8080
|
ihs_column_names: [
|
|
8081
8081
|
"shareCapital",
|
|
8082
8082
|
"totalEquityT1",
|
|
@@ -8098,7 +8098,6 @@ var form_field_base_specs_default = {
|
|
|
8098
8098
|
name: "financials_fincap_t1",
|
|
8099
8099
|
displayName: "Audited Financial Statement (T-1) (FinCap)",
|
|
8100
8100
|
type: "file",
|
|
8101
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8102
8101
|
ihs_column_names: [
|
|
8103
8102
|
"nonCurrentAssetsSubsidiaryCompaniesT1",
|
|
8104
8103
|
"nonCurrentAssetsAssociatedCompaniesT1",
|
|
@@ -8343,7 +8342,6 @@ var form_field_base_specs_default = {
|
|
|
8343
8342
|
name: "financials_fincap_t2",
|
|
8344
8343
|
displayName: "Audited Financial Statement (T-2) (FinCap)",
|
|
8345
8344
|
type: "file",
|
|
8346
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8347
8345
|
ihs_column_names: [
|
|
8348
8346
|
"nonCurrentAssetsSubsidiaryCompaniesT3",
|
|
8349
8347
|
"nonCurrentAssetsAssociatedCompaniesT3",
|
|
@@ -8470,7 +8468,6 @@ var form_field_base_specs_default = {
|
|
|
8470
8468
|
name: "form9",
|
|
8471
8469
|
displayName: "Form 9 / Section 17 / Form D",
|
|
8472
8470
|
type: "file",
|
|
8473
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8474
8471
|
ihs_column_names: [
|
|
8475
8472
|
"incorporatedDate",
|
|
8476
8473
|
"companyName",
|
|
@@ -8482,7 +8479,6 @@ var form_field_base_specs_default = {
|
|
|
8482
8479
|
name: "ssm",
|
|
8483
8480
|
displayName: "SSM Company Profile",
|
|
8484
8481
|
type: "file",
|
|
8485
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8486
8482
|
ihs_column_names: [
|
|
8487
8483
|
"ssmCompanyName",
|
|
8488
8484
|
"ssmCompanyRegNo",
|
|
@@ -8507,7 +8503,6 @@ var form_field_base_specs_default = {
|
|
|
8507
8503
|
name: "ic",
|
|
8508
8504
|
displayName: "Identification Card (Front)",
|
|
8509
8505
|
type: "file",
|
|
8510
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8511
8506
|
ihs_column_names: [
|
|
8512
8507
|
"icNumber",
|
|
8513
8508
|
"icName",
|
|
@@ -8525,7 +8520,6 @@ var form_field_base_specs_default = {
|
|
|
8525
8520
|
name: "epf_statement_t1",
|
|
8526
8521
|
displayName: "Employees' Provident Fund (T-1)",
|
|
8527
8522
|
type: "file",
|
|
8528
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8529
8523
|
ihs_column_names: [
|
|
8530
8524
|
"epfAccountHolderNameT1",
|
|
8531
8525
|
"epfAccountHolderAddressT1",
|
|
@@ -8543,7 +8537,6 @@ var form_field_base_specs_default = {
|
|
|
8543
8537
|
name: "epf_statement_t2",
|
|
8544
8538
|
displayName: "Employees' Provident Fund (T-2)",
|
|
8545
8539
|
type: "file",
|
|
8546
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8547
8540
|
ihs_column_names: [
|
|
8548
8541
|
"epfAccountHolderNameT2",
|
|
8549
8542
|
"epfAccountHolderAddressT2",
|
|
@@ -8561,7 +8554,6 @@ var form_field_base_specs_default = {
|
|
|
8561
8554
|
name: "payslip_statement_t1",
|
|
8562
8555
|
displayName: "Payslip Statement (Month T-1)",
|
|
8563
8556
|
type: "file",
|
|
8564
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8565
8557
|
ihs_column_names: [
|
|
8566
8558
|
"payslipEmployerNameT1",
|
|
8567
8559
|
"payslipEmployeeNameT1",
|
|
@@ -8585,7 +8577,6 @@ var form_field_base_specs_default = {
|
|
|
8585
8577
|
name: "payslip_statement_t2",
|
|
8586
8578
|
displayName: "Payslip Statement (Month T-2)",
|
|
8587
8579
|
type: "file",
|
|
8588
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8589
8580
|
ihs_column_names: [
|
|
8590
8581
|
"payslipEmployerNameT2",
|
|
8591
8582
|
"payslipEmployeeNameT2",
|
|
@@ -8609,7 +8600,6 @@ var form_field_base_specs_default = {
|
|
|
8609
8600
|
name: "payslip_statement_t3",
|
|
8610
8601
|
displayName: "Payslip Statement (Month T-3)",
|
|
8611
8602
|
type: "file",
|
|
8612
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8613
8603
|
ihs_column_names: [
|
|
8614
8604
|
"payslipEmployerNameT3",
|
|
8615
8605
|
"payslipEmployeeNameT3",
|
|
@@ -8633,7 +8623,6 @@ var form_field_base_specs_default = {
|
|
|
8633
8623
|
name: "payslip_statement_t4",
|
|
8634
8624
|
displayName: "Payslip Statement (Month T-4)",
|
|
8635
8625
|
type: "file",
|
|
8636
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8637
8626
|
ihs_column_names: [
|
|
8638
8627
|
"payslipEmployerNameT4",
|
|
8639
8628
|
"payslipEmployeeNameT4",
|
|
@@ -8657,7 +8646,6 @@ var form_field_base_specs_default = {
|
|
|
8657
8646
|
name: "payslip_statement_t5",
|
|
8658
8647
|
displayName: "Payslip Statement (Month T-5)",
|
|
8659
8648
|
type: "file",
|
|
8660
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8661
8649
|
ihs_column_names: [
|
|
8662
8650
|
"payslipEmployerNameT5",
|
|
8663
8651
|
"payslipEmployeeNameT5",
|
|
@@ -8681,7 +8669,6 @@ var form_field_base_specs_default = {
|
|
|
8681
8669
|
name: "payslip_statement_t6",
|
|
8682
8670
|
displayName: "Payslip Statement (Month T-6)",
|
|
8683
8671
|
type: "file",
|
|
8684
|
-
enableIf: "{formOfDisclosure} contains 'consented'",
|
|
8685
8672
|
ihs_column_names: [
|
|
8686
8673
|
"payslipEmployerNameT6",
|
|
8687
8674
|
"payslipEmployeeNameT6",
|
|
@@ -9488,18 +9475,18 @@ function buildTableForGroup(groupName, fields, ihsData) {
|
|
|
9488
9475
|
const items = [];
|
|
9489
9476
|
for (const [baseName, periodMap] of Object.entries(columnGroups)) {
|
|
9490
9477
|
const numeric = isNumericField(baseName);
|
|
9491
|
-
const
|
|
9478
|
+
const data2 = {};
|
|
9492
9479
|
const formattedData = {};
|
|
9493
9480
|
for (const period of periods) {
|
|
9494
9481
|
const colName = periodMap[period];
|
|
9495
9482
|
const value = colName ? ihsData[colName] ?? null : null;
|
|
9496
|
-
|
|
9483
|
+
data2[period] = value;
|
|
9497
9484
|
formattedData[period] = formatValue(value, numeric);
|
|
9498
9485
|
}
|
|
9499
9486
|
items.push({
|
|
9500
9487
|
displayName: getDisplayName(baseName),
|
|
9501
9488
|
timePeriods: periods,
|
|
9502
|
-
data,
|
|
9489
|
+
data: data2,
|
|
9503
9490
|
formattedData,
|
|
9504
9491
|
type: tableType,
|
|
9505
9492
|
isNumeric: numeric
|
|
@@ -9856,8 +9843,254 @@ function resolveExtractionStatus(ihsRecord, jobRecords) {
|
|
|
9856
9843
|
);
|
|
9857
9844
|
return { documents, summary };
|
|
9858
9845
|
}
|
|
9846
|
+
|
|
9847
|
+
// src/adapter.ts
|
|
9848
|
+
var AdapterError = class extends Error {
|
|
9849
|
+
constructor(reason, message, cause) {
|
|
9850
|
+
super(message);
|
|
9851
|
+
this.name = "AdapterError";
|
|
9852
|
+
this.reason = reason;
|
|
9853
|
+
this.cause = cause;
|
|
9854
|
+
}
|
|
9855
|
+
};
|
|
9856
|
+
|
|
9857
|
+
// src/adapter-aggregation.ts
|
|
9858
|
+
var ALL_AGGREGATION_OPS = [
|
|
9859
|
+
"sum",
|
|
9860
|
+
"mean",
|
|
9861
|
+
"latest",
|
|
9862
|
+
"max",
|
|
9863
|
+
"count"
|
|
9864
|
+
];
|
|
9865
|
+
function applyAggregation(op, instances) {
|
|
9866
|
+
if (instances.length === 0) {
|
|
9867
|
+
return op === "count" ? 0 : null;
|
|
9868
|
+
}
|
|
9869
|
+
if (op === "count") {
|
|
9870
|
+
return instances.reduce(
|
|
9871
|
+
(acc, i) => i.value !== null && i.value !== void 0 ? acc + 1 : acc,
|
|
9872
|
+
0
|
|
9873
|
+
);
|
|
9874
|
+
}
|
|
9875
|
+
if (op === "latest") {
|
|
9876
|
+
let pick = instances[0];
|
|
9877
|
+
for (let i = 1; i < instances.length; i++) {
|
|
9878
|
+
if (instances[i].observedAt > pick.observedAt) pick = instances[i];
|
|
9879
|
+
}
|
|
9880
|
+
return pick.value;
|
|
9881
|
+
}
|
|
9882
|
+
const nums = [];
|
|
9883
|
+
for (const i of instances) {
|
|
9884
|
+
if (typeof i.value === "number" && Number.isFinite(i.value)) {
|
|
9885
|
+
nums.push(i.value);
|
|
9886
|
+
} else if (i.value !== null && typeof i.value !== "undefined") {
|
|
9887
|
+
throw new Error(
|
|
9888
|
+
`applyAggregation: '${op}' requires numeric values; got ${typeof i.value}`
|
|
9889
|
+
);
|
|
9890
|
+
}
|
|
9891
|
+
}
|
|
9892
|
+
if (nums.length === 0) return null;
|
|
9893
|
+
switch (op) {
|
|
9894
|
+
case "sum":
|
|
9895
|
+
return nums.reduce((a, b) => a + b, 0);
|
|
9896
|
+
case "mean":
|
|
9897
|
+
return nums.reduce((a, b) => a + b, 0) / nums.length;
|
|
9898
|
+
case "max":
|
|
9899
|
+
return nums.reduce((a, b) => a > b ? a : b);
|
|
9900
|
+
}
|
|
9901
|
+
}
|
|
9902
|
+
|
|
9903
|
+
// src/data/adapter-categories.json
|
|
9904
|
+
var adapter_categories_default = {
|
|
9905
|
+
schemaVersion: "1.0.0",
|
|
9906
|
+
categories: [
|
|
9907
|
+
{
|
|
9908
|
+
id: "telco-carrier",
|
|
9909
|
+
displayName: "Telco Carrier",
|
|
9910
|
+
description: "Mobile carrier bill-payment + account-history signals. Any telco vendor (Celcom, Maxis, DiGi, U-Mobile, etc.) implementing this category produces the same canonical field set.",
|
|
9911
|
+
canonicalTable: "ihs_alt_data_telco",
|
|
9912
|
+
fields: [
|
|
9913
|
+
{
|
|
9914
|
+
name: "telcoOnTimePaymentRatio24m",
|
|
9915
|
+
type: "number",
|
|
9916
|
+
unit: "ratio",
|
|
9917
|
+
range: [0, 1],
|
|
9918
|
+
description: "Fraction of bills paid on time over the last 24 months. Strongest single telco predictor; \u22650.95 is the clean-history signal."
|
|
9919
|
+
},
|
|
9920
|
+
{
|
|
9921
|
+
name: "telcoTenureMonths",
|
|
9922
|
+
type: "number",
|
|
9923
|
+
unit: "months",
|
|
9924
|
+
range: [0, 600],
|
|
9925
|
+
description: "Account age. \u226548 months is the thin-file uplift trigger."
|
|
9926
|
+
},
|
|
9927
|
+
{
|
|
9928
|
+
name: "telcoSuspensionsCount24m",
|
|
9929
|
+
type: "number",
|
|
9930
|
+
unit: "count",
|
|
9931
|
+
range: [0, 100],
|
|
9932
|
+
description: "Non-payment-driven account suspensions in the last 24 months. \u22653 is a strong distress signal."
|
|
9933
|
+
},
|
|
9934
|
+
{
|
|
9935
|
+
name: "telcoLateDays24m",
|
|
9936
|
+
type: "number",
|
|
9937
|
+
unit: "days",
|
|
9938
|
+
range: [0, 800],
|
|
9939
|
+
description: "Cumulative days late across all bills in the trailing 24-month window."
|
|
9940
|
+
},
|
|
9941
|
+
{
|
|
9942
|
+
name: "telcoHandsetFinancingActive",
|
|
9943
|
+
type: "boolean",
|
|
9944
|
+
description: "Has an active handset-EMI account currently. Proxy for financing capacity already extended."
|
|
9945
|
+
},
|
|
9946
|
+
{
|
|
9947
|
+
name: "telcoHandsetFinancingDelinquent",
|
|
9948
|
+
type: "boolean",
|
|
9949
|
+
description: "Recent handset-EMI delinquency in the last 24 months. Distress signal even with otherwise clean bill payment."
|
|
9950
|
+
},
|
|
9951
|
+
{
|
|
9952
|
+
name: "telcoArpuMyr",
|
|
9953
|
+
type: "number",
|
|
9954
|
+
unit: "MYR",
|
|
9955
|
+
range: [0, 1e4],
|
|
9956
|
+
description: "Average Revenue Per User (monthly) in Malaysian Ringgit. Coarse spending-capacity proxy."
|
|
9957
|
+
}
|
|
9958
|
+
]
|
|
9959
|
+
},
|
|
9960
|
+
{
|
|
9961
|
+
id: "payment-network",
|
|
9962
|
+
displayName: "Payment Network",
|
|
9963
|
+
description: "Merchant-side payment-flow signals from POS / gateway networks (iPay88, GHL, etc.). Captures actual transaction velocity rather than self-reported revenue.",
|
|
9964
|
+
canonicalTable: "ihs_alt_data_payments",
|
|
9965
|
+
fields: [
|
|
9966
|
+
{
|
|
9967
|
+
name: "paymentsMonthlyVolumeMyrT3",
|
|
9968
|
+
type: "number",
|
|
9969
|
+
unit: "MYR",
|
|
9970
|
+
range: [0, 1e8],
|
|
9971
|
+
description: "Mean monthly inbound transaction volume (RM) over the trailing 3 months."
|
|
9972
|
+
},
|
|
9973
|
+
{
|
|
9974
|
+
name: "paymentsMonthlyVolumeMyrT12",
|
|
9975
|
+
type: "number",
|
|
9976
|
+
unit: "MYR",
|
|
9977
|
+
range: [0, 1e8],
|
|
9978
|
+
description: "Mean monthly inbound transaction volume (RM) over the trailing 12 months. Pair with T3 for trend direction."
|
|
9979
|
+
},
|
|
9980
|
+
{
|
|
9981
|
+
name: "paymentsArpuStability12m",
|
|
9982
|
+
type: "number",
|
|
9983
|
+
unit: "ratio",
|
|
9984
|
+
range: [0, 1],
|
|
9985
|
+
description: "Coefficient-of-variation inverse over monthly ARPU in the trailing 12 months. Closer to 1 = steadier; closer to 0 = volatile."
|
|
9986
|
+
},
|
|
9987
|
+
{
|
|
9988
|
+
name: "paymentsDisputeRate12m",
|
|
9989
|
+
type: "number",
|
|
9990
|
+
unit: "ratio",
|
|
9991
|
+
range: [0, 1],
|
|
9992
|
+
description: "Fraction of transactions disputed or refunded in the trailing 12 months."
|
|
9993
|
+
},
|
|
9994
|
+
{
|
|
9995
|
+
name: "paymentsCustomerConcentrationTop5Pct",
|
|
9996
|
+
type: "number",
|
|
9997
|
+
unit: "ratio",
|
|
9998
|
+
range: [0, 1],
|
|
9999
|
+
description: "Revenue share from the top-5 recurring customers. Above ~0.7 is concentration risk."
|
|
10000
|
+
},
|
|
10001
|
+
{
|
|
10002
|
+
name: "paymentsActiveTenureMonths",
|
|
10003
|
+
type: "number",
|
|
10004
|
+
unit: "months",
|
|
10005
|
+
range: [0, 600],
|
|
10006
|
+
description: "Months since first transaction on the payment network. Establishment / continuity proxy."
|
|
10007
|
+
}
|
|
10008
|
+
]
|
|
10009
|
+
},
|
|
10010
|
+
{
|
|
10011
|
+
id: "bank-statement",
|
|
10012
|
+
displayName: "Bank Statement",
|
|
10013
|
+
description: "Per-month bank-statement extractions. Naturally multi-instance: one statement per (account, month). Eval components typically aggregate across instances (sum closing balance, max debit, count of bounced transactions).",
|
|
10014
|
+
canonicalTable: "ihs_alt_data_bank_statements",
|
|
10015
|
+
fields: [
|
|
10016
|
+
{
|
|
10017
|
+
name: "bankStatementMonth",
|
|
10018
|
+
type: "string",
|
|
10019
|
+
description: "Statement period in YYYY-MM format. Used as the instance_key discriminator + by the `latest` aggregation operator."
|
|
10020
|
+
},
|
|
10021
|
+
{
|
|
10022
|
+
name: "bankClosingBalanceMyr",
|
|
10023
|
+
type: "number",
|
|
10024
|
+
unit: "MYR",
|
|
10025
|
+
range: [-1e8, 1e8],
|
|
10026
|
+
description: "Closing balance for the statement period."
|
|
10027
|
+
},
|
|
10028
|
+
{
|
|
10029
|
+
name: "bankTotalCreditsMyr",
|
|
10030
|
+
type: "number",
|
|
10031
|
+
unit: "MYR",
|
|
10032
|
+
range: [0, 1e8],
|
|
10033
|
+
description: "Sum of credit transactions during the period."
|
|
10034
|
+
},
|
|
10035
|
+
{
|
|
10036
|
+
name: "bankTotalDebitsMyr",
|
|
10037
|
+
type: "number",
|
|
10038
|
+
unit: "MYR",
|
|
10039
|
+
range: [0, 1e8],
|
|
10040
|
+
description: "Sum of debit transactions during the period."
|
|
10041
|
+
},
|
|
10042
|
+
{
|
|
10043
|
+
name: "bankLargestSingleCreditMyr",
|
|
10044
|
+
type: "number",
|
|
10045
|
+
unit: "MYR",
|
|
10046
|
+
range: [0, 1e8],
|
|
10047
|
+
description: "Largest single inbound transaction in the period. Useful for spotting one-off injections vs steady revenue."
|
|
10048
|
+
},
|
|
10049
|
+
{
|
|
10050
|
+
name: "bankBouncedTransactionsCount",
|
|
10051
|
+
type: "number",
|
|
10052
|
+
unit: "count",
|
|
10053
|
+
range: [0, 1e3],
|
|
10054
|
+
description: "Bounced / returned transactions in the period. Distress signal at counts > 0."
|
|
10055
|
+
}
|
|
10056
|
+
]
|
|
10057
|
+
}
|
|
10058
|
+
]
|
|
10059
|
+
};
|
|
10060
|
+
|
|
10061
|
+
// src/adapter-categories.ts
|
|
10062
|
+
var data = adapter_categories_default;
|
|
10063
|
+
function categorySchemaOf(id) {
|
|
10064
|
+
const found = data.categories.find((c) => c.id === id);
|
|
10065
|
+
if (!found) {
|
|
10066
|
+
throw new Error(
|
|
10067
|
+
`Unknown adapter category: ${id}. Available: ${data.categories.map((c) => c.id).join(", ")}`
|
|
10068
|
+
);
|
|
10069
|
+
}
|
|
10070
|
+
return found;
|
|
10071
|
+
}
|
|
10072
|
+
function categoryFieldsOf(id) {
|
|
10073
|
+
return categorySchemaOf(id).fields.map((f) => f.name);
|
|
10074
|
+
}
|
|
10075
|
+
function allCategories() {
|
|
10076
|
+
return data.categories;
|
|
10077
|
+
}
|
|
10078
|
+
var fieldToCategory = (() => {
|
|
10079
|
+
const m = /* @__PURE__ */ new Map();
|
|
10080
|
+
for (const cat of data.categories) {
|
|
10081
|
+
for (const f of cat.fields) {
|
|
10082
|
+
m.set(f.name, cat.id);
|
|
10083
|
+
}
|
|
10084
|
+
}
|
|
10085
|
+
return m;
|
|
10086
|
+
})();
|
|
10087
|
+
function categoryForField(field) {
|
|
10088
|
+
return fieldToCategory.get(field) ?? null;
|
|
10089
|
+
}
|
|
9859
10090
|
// Annotate the CommonJS export names for ESM import in node:
|
|
9860
10091
|
0 && (module.exports = {
|
|
10092
|
+
ALL_AGGREGATION_OPS,
|
|
10093
|
+
AdapterError,
|
|
9861
10094
|
BASE_FIELD_SPECS,
|
|
9862
10095
|
BasicFormField,
|
|
9863
10096
|
DEFAULT_VALIDATOR_DEFINITIONS,
|
|
@@ -9878,8 +10111,13 @@ function resolveExtractionStatus(ihsRecord, jobRecords) {
|
|
|
9878
10111
|
IhsStatus,
|
|
9879
10112
|
IhsValueFormat,
|
|
9880
10113
|
Role,
|
|
10114
|
+
allCategories,
|
|
10115
|
+
applyAggregation,
|
|
9881
10116
|
applyDynamicTitles,
|
|
9882
10117
|
buildFileFieldTables,
|
|
10118
|
+
categoryFieldsOf,
|
|
10119
|
+
categoryForField,
|
|
10120
|
+
categorySchemaOf,
|
|
9883
10121
|
evaluateExpression,
|
|
9884
10122
|
extractTimePeriods,
|
|
9885
10123
|
generateRHFSchema,
|