@finsys/core 4.0.0 → 4.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.
package/dist/index.d.cts CHANGED
@@ -416,16 +416,34 @@ declare enum FileFieldTableType {
416
416
  * observedAt — ISO wall-clock of the extraction run
417
417
  * sourceRunId — the extraction run/job id that wrote it
418
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.
419
+ * (computed / no-confidence path) vs "manual" (SYS-2806, a
420
+ * lender-entered correction, committed once its edit overlay
421
+ * is approved). A "derived" field must render as "no
422
+ * confidence available", never a fabricated low score; a
423
+ * "manual" field must render as an edit indicator, not a
424
+ * confidence dot — confidence is always null for it too.
421
425
  */
426
+ /**
427
+ * Canonical origin values, single source of truth (Gemini-review finding:
428
+ * avoids duplicating the literal strings between the type and the runtime
429
+ * guard) -- mirrors the IhsStatus/IHS_VALID_STATUSES pattern in
430
+ * ihs-status.ts.
431
+ */
432
+ declare const IHS_FIELD_ORIGINS: readonly ["extracted", "derived", "manual"];
433
+ type IhsFieldOrigin = (typeof IHS_FIELD_ORIGINS)[number];
422
434
  interface IhsFieldProvenance {
423
435
  source: string;
424
436
  confidence: number | null;
425
437
  observedAt: string;
426
438
  sourceRunId: string | null;
427
- origin: 'extracted' | 'derived';
439
+ origin: IhsFieldOrigin;
428
440
  }
441
+ /**
442
+ * Type guard: narrows an unknown value to `IhsFieldOrigin` iff it is one of
443
+ * the three canonical origin strings. `origin` was previously validated
444
+ * only by the TS union — this is the first runtime check.
445
+ */
446
+ declare function isValidIhsFieldOrigin(origin: unknown): origin is IhsFieldOrigin;
429
447
  interface FileFieldTableItem {
430
448
  displayName: string;
431
449
  timePeriods: string[];
@@ -449,6 +467,22 @@ interface FileFieldTableData {
449
467
  items: FileFieldTableItem[];
450
468
  hasData: boolean;
451
469
  }
470
+ /**
471
+ * One sibling-table row as finsys-api's `docInstanceStorageService` writes
472
+ * it (SYS-2842) -- the unbounded counterpart to a T{n}-suffixed wide-table
473
+ * slot. `instanceKey` is the real, collision-free per-document key;
474
+ * `sourceLabel` is a human label when the doc type has one (e.g. a bank
475
+ * name); `timePeriod` is the same descriptive value column the legacy
476
+ * T{n} scheme used, kept for period-labeling and legacy provenance lookup
477
+ * (SYS-2886 Phase 5) -- no longer the row's key. Metric fields are the
478
+ * category's own base (unsuffixed) column names.
479
+ */
480
+ interface InstanceRow {
481
+ instanceKey: string;
482
+ sourceLabel?: string | null;
483
+ timePeriod?: string | null;
484
+ [metricKey: string]: unknown;
485
+ }
452
486
  /**
453
487
  * Per-document File metadata attached by finsys-api `getIhsDetailsById` as the
454
488
  * `documentMetadata` sibling map (SYS-2765), keyed by the document's raw stored
@@ -530,6 +564,31 @@ declare function groupColumnsByTimePeriod(columnNames: string[]): Record<string,
530
564
  declare function groupFieldsByPattern(fields: FieldData[]): Record<string, FieldData[]>;
531
565
  declare function getGroupDisplayNames(): Record<string, string>;
532
566
  declare function buildFileFieldTables(ihsData: Record<string, unknown>, fieldProvenance?: Record<string, IhsFieldProvenance>): Record<string, FileFieldTableData>;
567
+ /**
568
+ * Groups instance rows by base metric name -- the unbounded analog of
569
+ * groupColumnsByTimePeriod. `baseColumnNames` is the category's base
570
+ * (unsuffixed) field list; each returned group maps instance column
571
+ * label -> that metric's value on that row. Labels are disambiguated
572
+ * (see instanceColumnLabels) so two rows can never collide into the
573
+ * same key.
574
+ */
575
+ declare function groupColumnsByInstance(baseColumnNames: string[], instanceRows: InstanceRow[]): Record<string, Record<string, unknown>>;
576
+ /**
577
+ * Explicit base-column declaration for a category with NO catalog `file`
578
+ * spec -- e.g. invoice (SYS-2842 Phase 3), which was deliberately never
579
+ * registered in form-field-base-specs.json because getDocumentTypeGroups()
580
+ * is shared with resolveExtractionStatus, which assumes a category's wide-
581
+ * table columns exist to check "is this populated" against -- invoice has
582
+ * none (sibling-table only, no wideTableMirror). Registering it there would
583
+ * silently break resolveExtractionStatus's invoice status reporting. This
584
+ * override lets a category be instance-rendered without entering that
585
+ * shared registry at all.
586
+ */
587
+ interface CategorySpec {
588
+ displayName: string;
589
+ baseColumnNames: string[];
590
+ }
591
+ declare function buildFileFieldTablesFromInstances(instancesByCategory?: Record<string, InstanceRow[]>, fieldProvenance?: Record<string, IhsFieldProvenance>, categoryOverrides?: Record<string, CategorySpec>): Record<string, FileFieldTableData>;
533
592
  /** IHS doc-field key → human label (the fields that become document sections). */
534
593
  declare function getDocDisplayNames(): Record<string, string>;
535
594
  /** Doc types eligible for extraction (re-extract / view-JSON). */
@@ -652,11 +711,19 @@ declare function assertDocumentType(id: string): string;
652
711
  * Lender rejection is not represented by a distinct status: when a lender
653
712
  * rejects an application, finsys-api transitions the record back to
654
713
  * `APPLICATION_FINALIZED` from `LENDER_EVALUATION`.
714
+ *
715
+ * `EditingApplication` (SYS-2806) is a lender-scoped detour off
716
+ * `LenderEvaluation` for manually editing extracted field values — not
717
+ * reachable from `ApplicationFinalized`. A lender toggles into it and back
718
+ * out to `LenderEvaluation`; it never appears on a record no lender has
719
+ * claimed. See finsys-api's `updateIhsStatusByLender` for the transition
720
+ * guard.
655
721
  */
656
722
  declare enum IhsStatus {
657
723
  CreatingApplication = "CREATING_APPLICATION",
658
724
  ApplicationFinalized = "APPLICATION_FINALIZED",
659
725
  LenderEvaluation = "LENDER_EVALUATION",
726
+ EditingApplication = "EDITING_APPLICATION",
660
727
  Approved = "APPROVED",
661
728
  LouDelivered = "LOU_DELIVERED",
662
729
  AwaitingDisbursement = "AWAITING_DISBURSEMENT",
@@ -1392,4 +1459,4 @@ interface FieldMapEntry {
1392
1459
  readonly transform?: "identity" | "pct_to_ratio01" | "to_boolean" | "to_integer";
1393
1460
  }
1394
1461
 
1395
- 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 DocumentFileMetadata, type DocumentRow, type DocumentRowCapabilities, type DocumentTypeGroup, type DropdownOption, type EditorValidator, type 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 TaggedFieldData, type TimePeriodUnit, type TypescriptImplementation, type UnifiedFormConfig, type Validator, type WireFormat, allCategories, applyAggregation, applyDynamicTitles, assertAdapterCategory, assertDocumentType, buildDocumentRows, buildFileFieldTables, categoryFieldsOf, categoryForField, categorySchemaOf, evaluateExpression, extractTimePeriods, formatDocumentSize, formatDocumentType, formatDocumentUploaded, generateRHFSchema, generateSurveyJson, getBaseCategories, getBaseFieldNames, getBaseFieldSpecMap, getBaseFieldSpecs, getCategoryName, getDisplayName, getDisplayNames, getDocDisplayNames, getDocumentTypeGroups, getExtractableDocTypes, getGroupDisplayNames, getPastMonthLabel, getPastYearLabel, getReuploadableDocTypes, getStepDefaultValues, getStepSchema, groupColumnsByTimePeriod, groupDetailsByCategory, groupFieldsByCategory, groupFieldsByPattern, isAdapterCategory, isDocumentType, isFailureIhsStatus, isTerminalIhsStatus, isValidIhsStatus, parseFileField, processIhsDetails, resolveExtractionStatus, resolvePageFields, validateFormConfig, validateFormSpec, validatePagesConfig };
1462
+ 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 CategorySpec, type Choice, DEFAULT_VALIDATOR_DEFINITIONS, type DeclarativeImplementation, type DocExtractionResult, DocExtractionStatus, type DocumentFileMetadata, type DocumentRow, type DocumentRowCapabilities, type DocumentTypeGroup, type DropdownOption, type EditorValidator, type 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_FIELD_ORIGINS, IHS_TERMINAL_STATUSES, IHS_VALID_STATUSES, type IhsDetailCategory, type IhsFieldDetail, type IhsFieldOrigin, type IhsFieldProvenance, IhsStatus, IhsValueFormat, type InstanceRow, type InstanceValue, type PageConfig, type RHFSchemaOutput, type RHFStep, type RawPayload, type ResolvedField, Role, type SourceAdapter, type SurveyElementJSON, type SurveyJSON, type SurveyPageJSON, type TaggedFieldData, type TimePeriodUnit, type TypescriptImplementation, type UnifiedFormConfig, type Validator, type WireFormat, allCategories, applyAggregation, applyDynamicTitles, assertAdapterCategory, assertDocumentType, buildDocumentRows, buildFileFieldTables, buildFileFieldTablesFromInstances, categoryFieldsOf, categoryForField, categorySchemaOf, evaluateExpression, extractTimePeriods, formatDocumentSize, formatDocumentType, formatDocumentUploaded, generateRHFSchema, generateSurveyJson, getBaseCategories, getBaseFieldNames, getBaseFieldSpecMap, getBaseFieldSpecs, getCategoryName, getDisplayName, getDisplayNames, getDocDisplayNames, getDocumentTypeGroups, getExtractableDocTypes, getGroupDisplayNames, getPastMonthLabel, getPastYearLabel, getReuploadableDocTypes, getStepDefaultValues, getStepSchema, groupColumnsByInstance, groupColumnsByTimePeriod, groupDetailsByCategory, groupFieldsByCategory, groupFieldsByPattern, isAdapterCategory, isDocumentType, isFailureIhsStatus, isTerminalIhsStatus, isValidIhsFieldOrigin, isValidIhsStatus, parseFileField, processIhsDetails, resolveExtractionStatus, resolvePageFields, validateFormConfig, validateFormSpec, validatePagesConfig };
package/dist/index.d.ts CHANGED
@@ -416,16 +416,34 @@ declare enum FileFieldTableType {
416
416
  * observedAt — ISO wall-clock of the extraction run
417
417
  * sourceRunId — the extraction run/job id that wrote it
418
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.
419
+ * (computed / no-confidence path) vs "manual" (SYS-2806, a
420
+ * lender-entered correction, committed once its edit overlay
421
+ * is approved). A "derived" field must render as "no
422
+ * confidence available", never a fabricated low score; a
423
+ * "manual" field must render as an edit indicator, not a
424
+ * confidence dot — confidence is always null for it too.
421
425
  */
426
+ /**
427
+ * Canonical origin values, single source of truth (Gemini-review finding:
428
+ * avoids duplicating the literal strings between the type and the runtime
429
+ * guard) -- mirrors the IhsStatus/IHS_VALID_STATUSES pattern in
430
+ * ihs-status.ts.
431
+ */
432
+ declare const IHS_FIELD_ORIGINS: readonly ["extracted", "derived", "manual"];
433
+ type IhsFieldOrigin = (typeof IHS_FIELD_ORIGINS)[number];
422
434
  interface IhsFieldProvenance {
423
435
  source: string;
424
436
  confidence: number | null;
425
437
  observedAt: string;
426
438
  sourceRunId: string | null;
427
- origin: 'extracted' | 'derived';
439
+ origin: IhsFieldOrigin;
428
440
  }
441
+ /**
442
+ * Type guard: narrows an unknown value to `IhsFieldOrigin` iff it is one of
443
+ * the three canonical origin strings. `origin` was previously validated
444
+ * only by the TS union — this is the first runtime check.
445
+ */
446
+ declare function isValidIhsFieldOrigin(origin: unknown): origin is IhsFieldOrigin;
429
447
  interface FileFieldTableItem {
430
448
  displayName: string;
431
449
  timePeriods: string[];
@@ -449,6 +467,22 @@ interface FileFieldTableData {
449
467
  items: FileFieldTableItem[];
450
468
  hasData: boolean;
451
469
  }
470
+ /**
471
+ * One sibling-table row as finsys-api's `docInstanceStorageService` writes
472
+ * it (SYS-2842) -- the unbounded counterpart to a T{n}-suffixed wide-table
473
+ * slot. `instanceKey` is the real, collision-free per-document key;
474
+ * `sourceLabel` is a human label when the doc type has one (e.g. a bank
475
+ * name); `timePeriod` is the same descriptive value column the legacy
476
+ * T{n} scheme used, kept for period-labeling and legacy provenance lookup
477
+ * (SYS-2886 Phase 5) -- no longer the row's key. Metric fields are the
478
+ * category's own base (unsuffixed) column names.
479
+ */
480
+ interface InstanceRow {
481
+ instanceKey: string;
482
+ sourceLabel?: string | null;
483
+ timePeriod?: string | null;
484
+ [metricKey: string]: unknown;
485
+ }
452
486
  /**
453
487
  * Per-document File metadata attached by finsys-api `getIhsDetailsById` as the
454
488
  * `documentMetadata` sibling map (SYS-2765), keyed by the document's raw stored
@@ -530,6 +564,31 @@ declare function groupColumnsByTimePeriod(columnNames: string[]): Record<string,
530
564
  declare function groupFieldsByPattern(fields: FieldData[]): Record<string, FieldData[]>;
531
565
  declare function getGroupDisplayNames(): Record<string, string>;
532
566
  declare function buildFileFieldTables(ihsData: Record<string, unknown>, fieldProvenance?: Record<string, IhsFieldProvenance>): Record<string, FileFieldTableData>;
567
+ /**
568
+ * Groups instance rows by base metric name -- the unbounded analog of
569
+ * groupColumnsByTimePeriod. `baseColumnNames` is the category's base
570
+ * (unsuffixed) field list; each returned group maps instance column
571
+ * label -> that metric's value on that row. Labels are disambiguated
572
+ * (see instanceColumnLabels) so two rows can never collide into the
573
+ * same key.
574
+ */
575
+ declare function groupColumnsByInstance(baseColumnNames: string[], instanceRows: InstanceRow[]): Record<string, Record<string, unknown>>;
576
+ /**
577
+ * Explicit base-column declaration for a category with NO catalog `file`
578
+ * spec -- e.g. invoice (SYS-2842 Phase 3), which was deliberately never
579
+ * registered in form-field-base-specs.json because getDocumentTypeGroups()
580
+ * is shared with resolveExtractionStatus, which assumes a category's wide-
581
+ * table columns exist to check "is this populated" against -- invoice has
582
+ * none (sibling-table only, no wideTableMirror). Registering it there would
583
+ * silently break resolveExtractionStatus's invoice status reporting. This
584
+ * override lets a category be instance-rendered without entering that
585
+ * shared registry at all.
586
+ */
587
+ interface CategorySpec {
588
+ displayName: string;
589
+ baseColumnNames: string[];
590
+ }
591
+ declare function buildFileFieldTablesFromInstances(instancesByCategory?: Record<string, InstanceRow[]>, fieldProvenance?: Record<string, IhsFieldProvenance>, categoryOverrides?: Record<string, CategorySpec>): Record<string, FileFieldTableData>;
533
592
  /** IHS doc-field key → human label (the fields that become document sections). */
534
593
  declare function getDocDisplayNames(): Record<string, string>;
535
594
  /** Doc types eligible for extraction (re-extract / view-JSON). */
@@ -652,11 +711,19 @@ declare function assertDocumentType(id: string): string;
652
711
  * Lender rejection is not represented by a distinct status: when a lender
653
712
  * rejects an application, finsys-api transitions the record back to
654
713
  * `APPLICATION_FINALIZED` from `LENDER_EVALUATION`.
714
+ *
715
+ * `EditingApplication` (SYS-2806) is a lender-scoped detour off
716
+ * `LenderEvaluation` for manually editing extracted field values — not
717
+ * reachable from `ApplicationFinalized`. A lender toggles into it and back
718
+ * out to `LenderEvaluation`; it never appears on a record no lender has
719
+ * claimed. See finsys-api's `updateIhsStatusByLender` for the transition
720
+ * guard.
655
721
  */
656
722
  declare enum IhsStatus {
657
723
  CreatingApplication = "CREATING_APPLICATION",
658
724
  ApplicationFinalized = "APPLICATION_FINALIZED",
659
725
  LenderEvaluation = "LENDER_EVALUATION",
726
+ EditingApplication = "EDITING_APPLICATION",
660
727
  Approved = "APPROVED",
661
728
  LouDelivered = "LOU_DELIVERED",
662
729
  AwaitingDisbursement = "AWAITING_DISBURSEMENT",
@@ -1392,4 +1459,4 @@ interface FieldMapEntry {
1392
1459
  readonly transform?: "identity" | "pct_to_ratio01" | "to_boolean" | "to_integer";
1393
1460
  }
1394
1461
 
1395
- 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 DocumentFileMetadata, type DocumentRow, type DocumentRowCapabilities, type DocumentTypeGroup, type DropdownOption, type EditorValidator, type 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 TaggedFieldData, type TimePeriodUnit, type TypescriptImplementation, type UnifiedFormConfig, type Validator, type WireFormat, allCategories, applyAggregation, applyDynamicTitles, assertAdapterCategory, assertDocumentType, buildDocumentRows, buildFileFieldTables, categoryFieldsOf, categoryForField, categorySchemaOf, evaluateExpression, extractTimePeriods, formatDocumentSize, formatDocumentType, formatDocumentUploaded, generateRHFSchema, generateSurveyJson, getBaseCategories, getBaseFieldNames, getBaseFieldSpecMap, getBaseFieldSpecs, getCategoryName, getDisplayName, getDisplayNames, getDocDisplayNames, getDocumentTypeGroups, getExtractableDocTypes, getGroupDisplayNames, getPastMonthLabel, getPastYearLabel, getReuploadableDocTypes, getStepDefaultValues, getStepSchema, groupColumnsByTimePeriod, groupDetailsByCategory, groupFieldsByCategory, groupFieldsByPattern, isAdapterCategory, isDocumentType, isFailureIhsStatus, isTerminalIhsStatus, isValidIhsStatus, parseFileField, processIhsDetails, resolveExtractionStatus, resolvePageFields, validateFormConfig, validateFormSpec, validatePagesConfig };
1462
+ 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 CategorySpec, type Choice, DEFAULT_VALIDATOR_DEFINITIONS, type DeclarativeImplementation, type DocExtractionResult, DocExtractionStatus, type DocumentFileMetadata, type DocumentRow, type DocumentRowCapabilities, type DocumentTypeGroup, type DropdownOption, type EditorValidator, type 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_FIELD_ORIGINS, IHS_TERMINAL_STATUSES, IHS_VALID_STATUSES, type IhsDetailCategory, type IhsFieldDetail, type IhsFieldOrigin, type IhsFieldProvenance, IhsStatus, IhsValueFormat, type InstanceRow, type InstanceValue, type PageConfig, type RHFSchemaOutput, type RHFStep, type RawPayload, type ResolvedField, Role, type SourceAdapter, type SurveyElementJSON, type SurveyJSON, type SurveyPageJSON, type TaggedFieldData, type TimePeriodUnit, type TypescriptImplementation, type UnifiedFormConfig, type Validator, type WireFormat, allCategories, applyAggregation, applyDynamicTitles, assertAdapterCategory, assertDocumentType, buildDocumentRows, buildFileFieldTables, buildFileFieldTablesFromInstances, categoryFieldsOf, categoryForField, categorySchemaOf, evaluateExpression, extractTimePeriods, formatDocumentSize, formatDocumentType, formatDocumentUploaded, generateRHFSchema, generateSurveyJson, getBaseCategories, getBaseFieldNames, getBaseFieldSpecMap, getBaseFieldSpecs, getCategoryName, getDisplayName, getDisplayNames, getDocDisplayNames, getDocumentTypeGroups, getExtractableDocTypes, getGroupDisplayNames, getPastMonthLabel, getPastYearLabel, getReuploadableDocTypes, getStepDefaultValues, getStepSchema, groupColumnsByInstance, groupColumnsByTimePeriod, groupDetailsByCategory, groupFieldsByCategory, groupFieldsByPattern, isAdapterCategory, isDocumentType, isFailureIhsStatus, isTerminalIhsStatus, isValidIhsFieldOrigin, isValidIhsStatus, parseFileField, processIhsDetails, resolveExtractionStatus, resolvePageFields, validateFormConfig, validateFormSpec, validatePagesConfig };
package/dist/index.js CHANGED
@@ -9200,6 +9200,10 @@ var FileFieldTableType = /* @__PURE__ */ ((FileFieldTableType2) => {
9200
9200
  FileFieldTableType2["KEY_VALUE"] = "keyValue";
9201
9201
  return FileFieldTableType2;
9202
9202
  })(FileFieldTableType || {});
9203
+ var IHS_FIELD_ORIGINS = ["extracted", "derived", "manual"];
9204
+ function isValidIhsFieldOrigin(origin) {
9205
+ return typeof origin === "string" && IHS_FIELD_ORIGINS.includes(origin);
9206
+ }
9203
9207
 
9204
9208
  // src/document-types.ts
9205
9209
  var cached = null;
@@ -9597,6 +9601,124 @@ function buildFileFieldTables(ihsData, fieldProvenance) {
9597
9601
  }
9598
9602
  return tables;
9599
9603
  }
9604
+ function instanceColumnLabel(row) {
9605
+ const period = row.timePeriod || row.instanceKey;
9606
+ return row.sourceLabel ? `${period} \xB7 ${row.sourceLabel}` : period;
9607
+ }
9608
+ function instanceColumnLabels(rows) {
9609
+ const seenCounts = /* @__PURE__ */ new Map();
9610
+ return rows.map((row) => {
9611
+ const raw = instanceColumnLabel(row);
9612
+ const occurrence = (seenCounts.get(raw) ?? 0) + 1;
9613
+ seenCounts.set(raw, occurrence);
9614
+ return occurrence === 1 ? raw : `${raw} (${occurrence})`;
9615
+ });
9616
+ }
9617
+ function groupColumnsByInstance(baseColumnNames, instanceRows) {
9618
+ const groups = {};
9619
+ for (const baseName of baseColumnNames) {
9620
+ groups[baseName] = {};
9621
+ }
9622
+ if (!instanceRows?.length) return groups;
9623
+ const labels = instanceColumnLabels(instanceRows);
9624
+ instanceRows.forEach((row, i) => {
9625
+ const label = labels[i];
9626
+ for (const baseName of baseColumnNames) {
9627
+ if (Object.prototype.hasOwnProperty.call(row, baseName)) {
9628
+ groups[baseName][label] = row[baseName];
9629
+ }
9630
+ }
9631
+ });
9632
+ return groups;
9633
+ }
9634
+ function buildInstanceTable(groupName, baseNames, groupDisplayName, instanceRows, fieldProvenance) {
9635
+ const columnGroups = groupColumnsByInstance(baseNames, instanceRows);
9636
+ const instanceLabels = instanceColumnLabels(instanceRows);
9637
+ const items = [];
9638
+ for (const [baseName, labelMap] of Object.entries(columnGroups)) {
9639
+ const hasAny = Object.values(labelMap).some((v) => v !== null && v !== void 0 && v !== "");
9640
+ if (!hasAny) continue;
9641
+ const numeric = isNumericField(baseName);
9642
+ const data = {};
9643
+ const formattedData = {};
9644
+ const confidence = {};
9645
+ const provenance = {};
9646
+ for (const [i, row] of instanceRows.entries()) {
9647
+ const label = instanceLabels[i];
9648
+ const value = labelMap[label] ?? null;
9649
+ data[label] = value;
9650
+ formattedData[label] = formatValue(value, numeric);
9651
+ const legacyKey = row.timePeriod ? `${baseName}${row.timePeriod}` : void 0;
9652
+ const prov = legacyKey ? fieldProvenance?.[legacyKey] : void 0;
9653
+ if (prov) {
9654
+ provenance[label] = prov;
9655
+ if (prov.origin === "extracted" && typeof prov.confidence === "number" && !Number.isNaN(prov.confidence)) {
9656
+ confidence[label] = prov.confidence;
9657
+ }
9658
+ }
9659
+ }
9660
+ items.push({
9661
+ displayName: getDisplayName(baseName),
9662
+ timePeriods: instanceLabels,
9663
+ data,
9664
+ formattedData,
9665
+ type: "timeSeries" /* TIME_SERIES */,
9666
+ isNumeric: numeric,
9667
+ ...Object.keys(confidence).length ? { confidence } : {},
9668
+ ...Object.keys(provenance).length ? { provenance } : {}
9669
+ });
9670
+ }
9671
+ const hasData = items.some(
9672
+ (item) => Object.values(item.data).some((v) => v !== null && v !== void 0 && v !== "")
9673
+ );
9674
+ if (!items.length || !hasData) return null;
9675
+ return {
9676
+ name: groupName,
9677
+ displayName: groupDisplayName,
9678
+ type: "timeSeries" /* TIME_SERIES */,
9679
+ items,
9680
+ hasData
9681
+ };
9682
+ }
9683
+ function buildFileFieldTablesFromInstances(instancesByCategory = {}, fieldProvenance, categoryOverrides) {
9684
+ const specs = getBaseFieldSpecs();
9685
+ const fileFields = specs.filter((f) => f.type === "file" && f.ihs_column_names?.length);
9686
+ const grouped = groupFieldsByPattern(fileFields);
9687
+ const tables = {};
9688
+ for (const [groupName, fields] of Object.entries(grouped)) {
9689
+ const instanceRows = instancesByCategory[groupName];
9690
+ if (!instanceRows?.length) continue;
9691
+ const baseNames = /* @__PURE__ */ new Set();
9692
+ for (const field of fields) {
9693
+ for (const col of field.ihs_column_names ?? []) {
9694
+ baseNames.add(col.replace(TIME_PERIOD_REGEX, ""));
9695
+ }
9696
+ }
9697
+ const groupDisplayName = getGroupDisplayNames()[groupName] || fields[0]?.displayName || getDisplayName(groupName);
9698
+ const table = buildInstanceTable(
9699
+ groupName,
9700
+ [...baseNames],
9701
+ groupDisplayName,
9702
+ instanceRows,
9703
+ fieldProvenance
9704
+ );
9705
+ if (table) tables[groupName] = table;
9706
+ }
9707
+ for (const [groupName, spec] of Object.entries(categoryOverrides ?? {})) {
9708
+ if (Object.prototype.hasOwnProperty.call(tables, groupName)) continue;
9709
+ const instanceRows = instancesByCategory[groupName];
9710
+ if (!instanceRows?.length) continue;
9711
+ const table = buildInstanceTable(
9712
+ groupName,
9713
+ spec.baseColumnNames,
9714
+ spec.displayName,
9715
+ instanceRows,
9716
+ fieldProvenance
9717
+ );
9718
+ if (table) tables[groupName] = table;
9719
+ }
9720
+ return tables;
9721
+ }
9600
9722
  var DOC_DISPLAY_NAMES = {
9601
9723
  bankStatements: "Bank Statements",
9602
9724
  financialStatements: "Financial Statements",
@@ -9849,6 +9971,7 @@ var IhsStatus = /* @__PURE__ */ ((IhsStatus2) => {
9849
9971
  IhsStatus2["CreatingApplication"] = "CREATING_APPLICATION";
9850
9972
  IhsStatus2["ApplicationFinalized"] = "APPLICATION_FINALIZED";
9851
9973
  IhsStatus2["LenderEvaluation"] = "LENDER_EVALUATION";
9974
+ IhsStatus2["EditingApplication"] = "EDITING_APPLICATION";
9852
9975
  IhsStatus2["Approved"] = "APPROVED";
9853
9976
  IhsStatus2["LouDelivered"] = "LOU_DELIVERED";
9854
9977
  IhsStatus2["AwaitingDisbursement"] = "AWAITING_DISBURSEMENT";
@@ -9862,6 +9985,7 @@ var IHS_VALID_STATUSES = [
9862
9985
  "CREATING_APPLICATION" /* CreatingApplication */,
9863
9986
  "APPLICATION_FINALIZED" /* ApplicationFinalized */,
9864
9987
  "LENDER_EVALUATION" /* LenderEvaluation */,
9988
+ "EDITING_APPLICATION" /* EditingApplication */,
9865
9989
  "APPROVED" /* Approved */,
9866
9990
  "LOU_DELIVERED" /* LouDelivered */,
9867
9991
  "AWAITING_DISBURSEMENT" /* AwaitingDisbursement */,
@@ -10627,6 +10751,7 @@ export {
10627
10751
  FormFieldValidator,
10628
10752
  FormSpec,
10629
10753
  IHS_FAILURE_STATUSES,
10754
+ IHS_FIELD_ORIGINS,
10630
10755
  IHS_TERMINAL_STATUSES,
10631
10756
  IHS_VALID_STATUSES,
10632
10757
  IhsStatus,
@@ -10639,6 +10764,7 @@ export {
10639
10764
  assertDocumentType,
10640
10765
  buildDocumentRows,
10641
10766
  buildFileFieldTables,
10767
+ buildFileFieldTablesFromInstances,
10642
10768
  categoryFieldsOf,
10643
10769
  categoryForField,
10644
10770
  categorySchemaOf,
@@ -10665,6 +10791,7 @@ export {
10665
10791
  getReuploadableDocTypes,
10666
10792
  getStepDefaultValues,
10667
10793
  getStepSchema,
10794
+ groupColumnsByInstance,
10668
10795
  groupColumnsByTimePeriod,
10669
10796
  groupDetailsByCategory,
10670
10797
  groupFieldsByCategory,
@@ -10673,6 +10800,7 @@ export {
10673
10800
  isDocumentType,
10674
10801
  isFailureIhsStatus,
10675
10802
  isTerminalIhsStatus,
10803
+ isValidIhsFieldOrigin,
10676
10804
  isValidIhsStatus,
10677
10805
  parseFileField,
10678
10806
  processIhsDetails,