@finsys/core 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.
package/dist/index.d.cts CHANGED
@@ -405,6 +405,27 @@ declare enum FileFieldTableType {
405
405
  TIME_SERIES = "timeSeries",
406
406
  KEY_VALUE = "keyValue"
407
407
  }
408
+ /**
409
+ * Per-field extraction provenance (SYS-2737/SYS-2741). The single canonical
410
+ * envelope — finsys-api writes it (ihs_field_metadata), finsys-core surfaces it
411
+ * onto detail cells, both consumers render it. Vocabulary mirrors adapter_runs
412
+ * (SYS-2441) so FinXtract + adapter provenance converge at SYS-2499 Phase 5.
413
+ *
414
+ * source — who produced the value, e.g. "finxtract:ssm"
415
+ * confidence — normalized 0..1; null when derived/computed (no score)
416
+ * observedAt — ISO wall-clock of the extraction run
417
+ * sourceRunId — the extraction run/job id that wrote it
418
+ * origin — "extracted" (a real {value,confidence} leaf) vs "derived"
419
+ * (computed / no-confidence path). A "derived" field must render
420
+ * as "no confidence available", never a fabricated low score.
421
+ */
422
+ interface IhsFieldProvenance {
423
+ source: string;
424
+ confidence: number | null;
425
+ observedAt: string;
426
+ sourceRunId: string | null;
427
+ origin: 'extracted' | 'derived';
428
+ }
408
429
  interface FileFieldTableItem {
409
430
  displayName: string;
410
431
  timePeriods: string[];
@@ -412,6 +433,14 @@ interface FileFieldTableItem {
412
433
  formattedData: Record<string, string>;
413
434
  type: FileFieldTableType;
414
435
  isNumeric: boolean;
436
+ /**
437
+ * SYS-2741: per-cell extraction provenance, keyed exactly like `data` (period
438
+ * key for TIME_SERIES, `'value'` for KEY_VALUE). `confidence` carries only
439
+ * scored (origin 'extracted') cells so a numeric dot never renders for a
440
+ * derived value; `provenance` carries the full envelope for every known cell.
441
+ */
442
+ confidence?: Record<string, number>;
443
+ provenance?: Record<string, IhsFieldProvenance>;
415
444
  }
416
445
  interface FileFieldTableData {
417
446
  name: string;
@@ -430,7 +459,7 @@ declare function groupColumnsByTimePeriod(columnNames: string[]): Record<string,
430
459
  declare function groupFieldsByPattern(fields: FieldData[]): Record<string, FieldData[]>;
431
460
  /** Returns human-friendly display names for field groups. */
432
461
  declare function getGroupDisplayNames(): Record<string, string>;
433
- declare function buildFileFieldTables(ihsData: Record<string, unknown>): Record<string, FileFieldTableData>;
462
+ declare function buildFileFieldTables(ihsData: Record<string, unknown>, fieldProvenance?: Record<string, IhsFieldProvenance>): Record<string, FileFieldTableData>;
434
463
  declare function processIhsDetails(ihsData: Record<string, unknown>): IhsFieldDetail[];
435
464
  declare function groupDetailsByCategory(details: IhsFieldDetail[]): IhsDetailCategory[];
436
465
 
@@ -1220,4 +1249,4 @@ interface FieldMapEntry {
1220
1249
  readonly transform?: "identity" | "pct_to_ratio01" | "to_boolean" | "to_integer";
1221
1250
  }
1222
1251
 
1223
- export { ADAPTER_CATEGORY_IDS, ALL_AGGREGATION_OPS, type AdapterCategory, AdapterError, type AdapterErrorReason, type AdapterExtraction, type AdapterManifest, type AggregationOp, type ApplicantIdentity, BASE_FIELD_SPECS, BasicFormField, type CanonicalFieldName, type CanonicalFieldSpec, type CanonicalFieldValue, type CanonicalFieldValues, type Category, type CategorySchema, type Choice, DEFAULT_VALIDATOR_DEFINITIONS, type DeclarativeImplementation, type DocExtractionResult, DocExtractionStatus, type DropdownOption, type EditorValidator, ExtractionFileType, type ExtractionJobRecord, ExtractionJobStatus, type ExtractionStatusResult, FIELD_TYPE_DEFINITIONS, type FieldData, type FieldGroup, type FieldMapEntry, type FieldReference, FieldType, type FileFieldTableData, type FileFieldTableItem, FileFieldTableType, FileFormField, FormField, FormFieldCategory, type FormFieldInputType, type FormFieldType, type FormFieldTypeDefinitions, FormFieldValidator, FormSpec, type FormValidatorDefinitions, IHS_FAILURE_STATUSES, IHS_TERMINAL_STATUSES, IHS_VALID_STATUSES, type IhsDetailCategory, type IhsFieldDetail, IhsStatus, IhsValueFormat, type InstanceValue, type PageConfig, type RHFSchemaOutput, type RHFStep, type RawPayload, type ResolvedField, Role, type SourceAdapter, type SurveyElementJSON, type SurveyJSON, type SurveyPageJSON, type TypescriptImplementation, type UnifiedFormConfig, type Validator, allCategories, applyAggregation, applyDynamicTitles, assertAdapterCategory, buildFileFieldTables, categoryFieldsOf, categoryForField, categorySchemaOf, evaluateExpression, extractTimePeriods, generateRHFSchema, generateSurveyJson, getBaseCategories, getBaseFieldNames, getBaseFieldSpecMap, getBaseFieldSpecs, getCategoryName, getDisplayName, getDisplayNames, getGroupDisplayNames, getPastMonthLabel, getPastYearLabel, getStepDefaultValues, getStepSchema, groupColumnsByTimePeriod, groupDetailsByCategory, groupFieldsByCategory, groupFieldsByPattern, isAdapterCategory, isFailureIhsStatus, isTerminalIhsStatus, isValidIhsStatus, processIhsDetails, resolveExtractionStatus, resolvePageFields, validateFormConfig, validateFormSpec, validatePagesConfig };
1252
+ export { ADAPTER_CATEGORY_IDS, ALL_AGGREGATION_OPS, type AdapterCategory, AdapterError, type AdapterErrorReason, type AdapterExtraction, type AdapterManifest, type AggregationOp, type ApplicantIdentity, BASE_FIELD_SPECS, BasicFormField, type CanonicalFieldName, type CanonicalFieldSpec, type CanonicalFieldValue, type CanonicalFieldValues, type Category, type CategorySchema, type Choice, DEFAULT_VALIDATOR_DEFINITIONS, type DeclarativeImplementation, type DocExtractionResult, DocExtractionStatus, type DropdownOption, type EditorValidator, ExtractionFileType, type ExtractionJobRecord, ExtractionJobStatus, type ExtractionStatusResult, FIELD_TYPE_DEFINITIONS, type FieldData, type FieldGroup, type FieldMapEntry, type FieldReference, FieldType, type FileFieldTableData, type FileFieldTableItem, FileFieldTableType, FileFormField, FormField, FormFieldCategory, type FormFieldInputType, type FormFieldType, type FormFieldTypeDefinitions, FormFieldValidator, FormSpec, type FormValidatorDefinitions, IHS_FAILURE_STATUSES, IHS_TERMINAL_STATUSES, IHS_VALID_STATUSES, type IhsDetailCategory, type IhsFieldDetail, type IhsFieldProvenance, IhsStatus, IhsValueFormat, type InstanceValue, type PageConfig, type RHFSchemaOutput, type RHFStep, type RawPayload, type ResolvedField, Role, type SourceAdapter, type SurveyElementJSON, type SurveyJSON, type SurveyPageJSON, type TypescriptImplementation, type UnifiedFormConfig, type Validator, allCategories, applyAggregation, applyDynamicTitles, assertAdapterCategory, buildFileFieldTables, categoryFieldsOf, categoryForField, categorySchemaOf, evaluateExpression, extractTimePeriods, generateRHFSchema, generateSurveyJson, getBaseCategories, getBaseFieldNames, getBaseFieldSpecMap, getBaseFieldSpecs, getCategoryName, getDisplayName, getDisplayNames, getGroupDisplayNames, getPastMonthLabel, getPastYearLabel, getStepDefaultValues, getStepSchema, groupColumnsByTimePeriod, groupDetailsByCategory, groupFieldsByCategory, groupFieldsByPattern, isAdapterCategory, isFailureIhsStatus, isTerminalIhsStatus, isValidIhsStatus, processIhsDetails, resolveExtractionStatus, resolvePageFields, validateFormConfig, validateFormSpec, validatePagesConfig };
package/dist/index.d.ts CHANGED
@@ -405,6 +405,27 @@ declare enum FileFieldTableType {
405
405
  TIME_SERIES = "timeSeries",
406
406
  KEY_VALUE = "keyValue"
407
407
  }
408
+ /**
409
+ * Per-field extraction provenance (SYS-2737/SYS-2741). The single canonical
410
+ * envelope — finsys-api writes it (ihs_field_metadata), finsys-core surfaces it
411
+ * onto detail cells, both consumers render it. Vocabulary mirrors adapter_runs
412
+ * (SYS-2441) so FinXtract + adapter provenance converge at SYS-2499 Phase 5.
413
+ *
414
+ * source — who produced the value, e.g. "finxtract:ssm"
415
+ * confidence — normalized 0..1; null when derived/computed (no score)
416
+ * observedAt — ISO wall-clock of the extraction run
417
+ * sourceRunId — the extraction run/job id that wrote it
418
+ * origin — "extracted" (a real {value,confidence} leaf) vs "derived"
419
+ * (computed / no-confidence path). A "derived" field must render
420
+ * as "no confidence available", never a fabricated low score.
421
+ */
422
+ interface IhsFieldProvenance {
423
+ source: string;
424
+ confidence: number | null;
425
+ observedAt: string;
426
+ sourceRunId: string | null;
427
+ origin: 'extracted' | 'derived';
428
+ }
408
429
  interface FileFieldTableItem {
409
430
  displayName: string;
410
431
  timePeriods: string[];
@@ -412,6 +433,14 @@ interface FileFieldTableItem {
412
433
  formattedData: Record<string, string>;
413
434
  type: FileFieldTableType;
414
435
  isNumeric: boolean;
436
+ /**
437
+ * SYS-2741: per-cell extraction provenance, keyed exactly like `data` (period
438
+ * key for TIME_SERIES, `'value'` for KEY_VALUE). `confidence` carries only
439
+ * scored (origin 'extracted') cells so a numeric dot never renders for a
440
+ * derived value; `provenance` carries the full envelope for every known cell.
441
+ */
442
+ confidence?: Record<string, number>;
443
+ provenance?: Record<string, IhsFieldProvenance>;
415
444
  }
416
445
  interface FileFieldTableData {
417
446
  name: string;
@@ -430,7 +459,7 @@ declare function groupColumnsByTimePeriod(columnNames: string[]): Record<string,
430
459
  declare function groupFieldsByPattern(fields: FieldData[]): Record<string, FieldData[]>;
431
460
  /** Returns human-friendly display names for field groups. */
432
461
  declare function getGroupDisplayNames(): Record<string, string>;
433
- declare function buildFileFieldTables(ihsData: Record<string, unknown>): Record<string, FileFieldTableData>;
462
+ declare function buildFileFieldTables(ihsData: Record<string, unknown>, fieldProvenance?: Record<string, IhsFieldProvenance>): Record<string, FileFieldTableData>;
434
463
  declare function processIhsDetails(ihsData: Record<string, unknown>): IhsFieldDetail[];
435
464
  declare function groupDetailsByCategory(details: IhsFieldDetail[]): IhsDetailCategory[];
436
465
 
@@ -1220,4 +1249,4 @@ interface FieldMapEntry {
1220
1249
  readonly transform?: "identity" | "pct_to_ratio01" | "to_boolean" | "to_integer";
1221
1250
  }
1222
1251
 
1223
- export { ADAPTER_CATEGORY_IDS, ALL_AGGREGATION_OPS, type AdapterCategory, AdapterError, type AdapterErrorReason, type AdapterExtraction, type AdapterManifest, type AggregationOp, type ApplicantIdentity, BASE_FIELD_SPECS, BasicFormField, type CanonicalFieldName, type CanonicalFieldSpec, type CanonicalFieldValue, type CanonicalFieldValues, type Category, type CategorySchema, type Choice, DEFAULT_VALIDATOR_DEFINITIONS, type DeclarativeImplementation, type DocExtractionResult, DocExtractionStatus, type DropdownOption, type EditorValidator, ExtractionFileType, type ExtractionJobRecord, ExtractionJobStatus, type ExtractionStatusResult, FIELD_TYPE_DEFINITIONS, type FieldData, type FieldGroup, type FieldMapEntry, type FieldReference, FieldType, type FileFieldTableData, type FileFieldTableItem, FileFieldTableType, FileFormField, FormField, FormFieldCategory, type FormFieldInputType, type FormFieldType, type FormFieldTypeDefinitions, FormFieldValidator, FormSpec, type FormValidatorDefinitions, IHS_FAILURE_STATUSES, IHS_TERMINAL_STATUSES, IHS_VALID_STATUSES, type IhsDetailCategory, type IhsFieldDetail, IhsStatus, IhsValueFormat, type InstanceValue, type PageConfig, type RHFSchemaOutput, type RHFStep, type RawPayload, type ResolvedField, Role, type SourceAdapter, type SurveyElementJSON, type SurveyJSON, type SurveyPageJSON, type TypescriptImplementation, type UnifiedFormConfig, type Validator, allCategories, applyAggregation, applyDynamicTitles, assertAdapterCategory, buildFileFieldTables, categoryFieldsOf, categoryForField, categorySchemaOf, evaluateExpression, extractTimePeriods, generateRHFSchema, generateSurveyJson, getBaseCategories, getBaseFieldNames, getBaseFieldSpecMap, getBaseFieldSpecs, getCategoryName, getDisplayName, getDisplayNames, getGroupDisplayNames, getPastMonthLabel, getPastYearLabel, getStepDefaultValues, getStepSchema, groupColumnsByTimePeriod, groupDetailsByCategory, groupFieldsByCategory, groupFieldsByPattern, isAdapterCategory, isFailureIhsStatus, isTerminalIhsStatus, isValidIhsStatus, processIhsDetails, resolveExtractionStatus, resolvePageFields, validateFormConfig, validateFormSpec, validatePagesConfig };
1252
+ export { ADAPTER_CATEGORY_IDS, ALL_AGGREGATION_OPS, type AdapterCategory, AdapterError, type AdapterErrorReason, type AdapterExtraction, type AdapterManifest, type AggregationOp, type ApplicantIdentity, BASE_FIELD_SPECS, BasicFormField, type CanonicalFieldName, type CanonicalFieldSpec, type CanonicalFieldValue, type CanonicalFieldValues, type Category, type CategorySchema, type Choice, DEFAULT_VALIDATOR_DEFINITIONS, type DeclarativeImplementation, type DocExtractionResult, DocExtractionStatus, type DropdownOption, type EditorValidator, ExtractionFileType, type ExtractionJobRecord, ExtractionJobStatus, type ExtractionStatusResult, FIELD_TYPE_DEFINITIONS, type FieldData, type FieldGroup, type FieldMapEntry, type FieldReference, FieldType, type FileFieldTableData, type FileFieldTableItem, FileFieldTableType, FileFormField, FormField, FormFieldCategory, type FormFieldInputType, type FormFieldType, type FormFieldTypeDefinitions, FormFieldValidator, FormSpec, type FormValidatorDefinitions, IHS_FAILURE_STATUSES, IHS_TERMINAL_STATUSES, IHS_VALID_STATUSES, type IhsDetailCategory, type IhsFieldDetail, type IhsFieldProvenance, IhsStatus, IhsValueFormat, type InstanceValue, type PageConfig, type RHFSchemaOutput, type RHFStep, type RawPayload, type ResolvedField, Role, type SourceAdapter, type SurveyElementJSON, type SurveyJSON, type SurveyPageJSON, type TypescriptImplementation, type UnifiedFormConfig, type Validator, allCategories, applyAggregation, applyDynamicTitles, assertAdapterCategory, buildFileFieldTables, categoryFieldsOf, categoryForField, categorySchemaOf, evaluateExpression, extractTimePeriods, generateRHFSchema, generateSurveyJson, getBaseCategories, getBaseFieldNames, getBaseFieldSpecMap, getBaseFieldSpecs, getCategoryName, getDisplayName, getDisplayNames, getGroupDisplayNames, getPastMonthLabel, getPastYearLabel, getStepDefaultValues, getStepSchema, groupColumnsByTimePeriod, groupDetailsByCategory, groupFieldsByCategory, groupFieldsByPattern, isAdapterCategory, isFailureIhsStatus, isTerminalIhsStatus, isValidIhsStatus, processIhsDetails, resolveExtractionStatus, resolvePageFields, validateFormConfig, validateFormSpec, validatePagesConfig };
package/dist/index.js CHANGED
@@ -9365,7 +9365,7 @@ function formatValue(value, numeric) {
9365
9365
  }
9366
9366
  return String(value);
9367
9367
  }
9368
- function buildTableForGroup(groupName, fields, ihsData) {
9368
+ function buildTableForGroup(groupName, fields, ihsData, fieldProvenance) {
9369
9369
  const allColumns = [];
9370
9370
  for (const field of fields) {
9371
9371
  if (field.ihs_column_names) {
@@ -9384,11 +9384,20 @@ function buildTableForGroup(groupName, fields, ihsData) {
9384
9384
  const numeric = isNumericField(baseName);
9385
9385
  const data = {};
9386
9386
  const formattedData = {};
9387
+ const confidence = {};
9388
+ const provenance = {};
9387
9389
  for (const period of periods) {
9388
9390
  const colName = periodMap[period];
9389
9391
  const value = colName ? ihsData[colName] ?? null : null;
9390
9392
  data[period] = value;
9391
9393
  formattedData[period] = formatValue(value, numeric);
9394
+ const prov = colName ? fieldProvenance?.[colName] : void 0;
9395
+ if (prov) {
9396
+ provenance[period] = prov;
9397
+ if (prov.origin === "extracted" && typeof prov.confidence === "number" && !Number.isNaN(prov.confidence)) {
9398
+ confidence[period] = prov.confidence;
9399
+ }
9400
+ }
9392
9401
  }
9393
9402
  items.push({
9394
9403
  displayName: getDisplayName(baseName),
@@ -9396,7 +9405,9 @@ function buildTableForGroup(groupName, fields, ihsData) {
9396
9405
  data,
9397
9406
  formattedData,
9398
9407
  type: tableType,
9399
- isNumeric: numeric
9408
+ isNumeric: numeric,
9409
+ ...Object.keys(confidence).length ? { confidence } : {},
9410
+ ...Object.keys(provenance).length ? { provenance } : {}
9400
9411
  });
9401
9412
  }
9402
9413
  const hasData = items.some(
@@ -9408,13 +9419,16 @@ function buildTableForGroup(groupName, fields, ihsData) {
9408
9419
  for (const colName of allColumns) {
9409
9420
  const value = ihsData[colName] ?? null;
9410
9421
  const numeric = isNumericField(colName);
9422
+ const prov = fieldProvenance?.[colName];
9411
9423
  items.push({
9412
9424
  displayName: getDisplayName(colName),
9413
9425
  timePeriods: [],
9414
9426
  data: { value },
9415
9427
  formattedData: { value: formatValue(value, numeric) },
9416
9428
  type: tableType,
9417
- isNumeric: numeric
9429
+ isNumeric: numeric,
9430
+ ...prov && prov.origin === "extracted" && typeof prov.confidence === "number" && !Number.isNaN(prov.confidence) ? { confidence: { value: prov.confidence } } : {},
9431
+ ...prov ? { provenance: { value: prov } } : {}
9418
9432
  });
9419
9433
  }
9420
9434
  const hasData = items.some((item) => {
@@ -9424,13 +9438,13 @@ function buildTableForGroup(groupName, fields, ihsData) {
9424
9438
  return { name: groupName, displayName: groupDisplayName, type: tableType, items, hasData };
9425
9439
  }
9426
9440
  }
9427
- function buildFileFieldTables(ihsData) {
9441
+ function buildFileFieldTables(ihsData, fieldProvenance) {
9428
9442
  const specs = getBaseFieldSpecs();
9429
9443
  const fileFields = specs.filter((f) => f.type === "file" && f.ihs_column_names?.length);
9430
9444
  const grouped = groupFieldsByPattern(fileFields);
9431
9445
  const tables = {};
9432
9446
  for (const [groupName, fields] of Object.entries(grouped)) {
9433
- const table = buildTableForGroup(groupName, fields, ihsData);
9447
+ const table = buildTableForGroup(groupName, fields, ihsData, fieldProvenance);
9434
9448
  if (table && table.hasData) {
9435
9449
  tables[groupName] = table;
9436
9450
  }