@finsys/core 4.7.0 → 4.8.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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "schemaVersion": "1.1.0",
2
+ "schemaVersion": "1.2.0",
3
3
  "categories": [
4
4
  {
5
5
  "id": "telco-carrier",
@@ -51,6 +51,30 @@
51
51
  "unit": "MYR",
52
52
  "range": [0, 10000],
53
53
  "description": "Average Revenue Per User (monthly) in Malaysian Ringgit. Coarse spending-capacity proxy."
54
+ },
55
+ {
56
+ "name": "telcoPaymentReliabilityTier",
57
+ "type": "string",
58
+ "kind": "enum",
59
+ "description": "Coarse bill-payment reliability bucket, for partners that return a tier label instead of a continuous ratio. Parallel signal to telcoOnTimePaymentRatio24m. Labels are vendor-declared (see the adapter manifest's enumValues); ordering and scoring live in the consumer's per-value mapping."
60
+ },
61
+ {
62
+ "name": "telcoTenureTier",
63
+ "type": "string",
64
+ "kind": "enum",
65
+ "description": "Coarse account-age bucket, for partners that return a tenure tier label instead of a continuous month count. Parallel signal to telcoTenureMonths. Labels are vendor-declared (see the adapter manifest's enumValues)."
66
+ },
67
+ {
68
+ "name": "telcoDistressTier",
69
+ "type": "string",
70
+ "kind": "enum",
71
+ "description": "Coarse account-distress bucket, for partners that return a distress tier label instead of discrete counts. Parallel signal to telcoSuspensionsCount24m / telcoLateDays24m. Labels are vendor-declared (see the adapter manifest's enumValues)."
72
+ },
73
+ {
74
+ "name": "telcoHandsetRiskTier",
75
+ "type": "string",
76
+ "kind": "enum",
77
+ "description": "Coarse handset-financing risk bucket, for partners that return a tier label instead of the discrete handset flags. Parallel signal to telcoHandsetFinancingActive / telcoHandsetFinancingDelinquent. Labels are vendor-declared (see the adapter manifest's enumValues)."
54
78
  }
55
79
  ]
56
80
  },
package/dist/index.cjs CHANGED
@@ -10323,7 +10323,7 @@ function applyAggregation(op, instances) {
10323
10323
 
10324
10324
  // src/data/adapter-categories.json
10325
10325
  var adapter_categories_default = {
10326
- schemaVersion: "1.1.0",
10326
+ schemaVersion: "1.2.0",
10327
10327
  categories: [
10328
10328
  {
10329
10329
  id: "telco-carrier",
@@ -10375,6 +10375,30 @@ var adapter_categories_default = {
10375
10375
  unit: "MYR",
10376
10376
  range: [0, 1e4],
10377
10377
  description: "Average Revenue Per User (monthly) in Malaysian Ringgit. Coarse spending-capacity proxy."
10378
+ },
10379
+ {
10380
+ name: "telcoPaymentReliabilityTier",
10381
+ type: "string",
10382
+ kind: "enum",
10383
+ description: "Coarse bill-payment reliability bucket, for partners that return a tier label instead of a continuous ratio. Parallel signal to telcoOnTimePaymentRatio24m. Labels are vendor-declared (see the adapter manifest's enumValues); ordering and scoring live in the consumer's per-value mapping."
10384
+ },
10385
+ {
10386
+ name: "telcoTenureTier",
10387
+ type: "string",
10388
+ kind: "enum",
10389
+ description: "Coarse account-age bucket, for partners that return a tenure tier label instead of a continuous month count. Parallel signal to telcoTenureMonths. Labels are vendor-declared (see the adapter manifest's enumValues)."
10390
+ },
10391
+ {
10392
+ name: "telcoDistressTier",
10393
+ type: "string",
10394
+ kind: "enum",
10395
+ description: "Coarse account-distress bucket, for partners that return a distress tier label instead of discrete counts. Parallel signal to telcoSuspensionsCount24m / telcoLateDays24m. Labels are vendor-declared (see the adapter manifest's enumValues)."
10396
+ },
10397
+ {
10398
+ name: "telcoHandsetRiskTier",
10399
+ type: "string",
10400
+ kind: "enum",
10401
+ description: "Coarse handset-financing risk bucket, for partners that return a tier label instead of the discrete handset flags. Parallel signal to telcoHandsetFinancingActive / telcoHandsetFinancingDelinquent. Labels are vendor-declared (see the adapter manifest's enumValues)."
10378
10402
  }
10379
10403
  ]
10380
10404
  },
@@ -11822,6 +11846,7 @@ var VALID_FIELD_TYPES = [
11822
11846
  "boolean",
11823
11847
  "string"
11824
11848
  ];
11849
+ var VALID_FIELD_KINDS = ["enum"];
11825
11850
  function buildCategoryRegistry(raw) {
11826
11851
  if (!raw || typeof raw !== "object") {
11827
11852
  throw new Error("adapter category data: expected an object");
@@ -11889,6 +11914,12 @@ function buildCategoryRegistry(raw) {
11889
11914
  `adapter category data: canonical field "${f.name}" declared by more than one category (${prior.categories.join(" + ")} with ${describeFact(prior.fact)} + ${cat.id} with ${describeFact(f.fact)}) \u2014 field names must be globally unique unless every declaring category attests the same fact`
11890
11915
  );
11891
11916
  }
11917
+ if (prior.kind !== f.kind) {
11918
+ const describeKind = (kind) => kind === void 0 ? "no kind" : `kind "${kind}"`;
11919
+ throw new Error(
11920
+ `adapter category data: canonical field "${f.name}" declared with ${describeKind(prior.kind)} by ${prior.categories.join(" + ")} but ${describeKind(f.kind)} by ${cat.id} \u2014 shared-fact attestations must agree on kind`
11921
+ );
11922
+ }
11892
11923
  }
11893
11924
  if (f.fact !== void 0) {
11894
11925
  for (const [otherName, otherFact] of fieldToFact) {
@@ -11904,6 +11935,23 @@ function buildCategoryRegistry(raw) {
11904
11935
  `adapter category data: field "${f.name}" (${where}) has invalid type "${f.type}"`
11905
11936
  );
11906
11937
  }
11938
+ if (f.kind !== void 0) {
11939
+ if (!VALID_FIELD_KINDS.includes(f.kind)) {
11940
+ throw new Error(
11941
+ `adapter category data: field "${f.name}" (${where}) has invalid kind "${String(f.kind)}"`
11942
+ );
11943
+ }
11944
+ if (f.type !== "string") {
11945
+ throw new Error(
11946
+ `adapter category data: field "${f.name}" (${where}) is kind "enum" but type "${f.type}" \u2014 enum labels are string-normalized, so an enum field must be type "string"`
11947
+ );
11948
+ }
11949
+ if (f.range !== void 0) {
11950
+ throw new Error(
11951
+ `adapter category data: field "${f.name}" (${where}) is kind "enum" but declares a range \u2014 enum labels are unordered; ordering belongs to the consumer, never the data contract`
11952
+ );
11953
+ }
11954
+ }
11907
11955
  if (typeof f.description !== "string" || f.description.length === 0) {
11908
11956
  throw new Error(
11909
11957
  `adapter category data: field "${f.name}" (${where}) needs a non-empty description`
@@ -11922,14 +11970,15 @@ function buildCategoryRegistry(raw) {
11922
11970
  ...f.unit !== void 0 ? { unit: f.unit } : {},
11923
11971
  ...f.range !== void 0 ? { range: Object.freeze([f.range[0], f.range[1]]) } : {},
11924
11972
  description: f.description,
11925
- ...f.fact !== void 0 ? { fact: f.fact } : {}
11973
+ ...f.fact !== void 0 ? { fact: f.fact } : {},
11974
+ ...f.kind !== void 0 ? { kind: f.kind } : {}
11926
11975
  });
11927
11976
  fields.push(spec);
11928
11977
  if (prior) {
11929
11978
  prior.categories.push(cat.id);
11930
11979
  fieldToCategory.delete(f.name);
11931
11980
  } else {
11932
- declarations.set(f.name, { fact: f.fact, categories: [cat.id] });
11981
+ declarations.set(f.name, { fact: f.fact, kind: f.kind, categories: [cat.id] });
11933
11982
  fieldToCategory.set(f.name, cat.id);
11934
11983
  }
11935
11984
  if (f.fact !== void 0) {