WIP main worktree changes before merge

This commit is contained in:
2026-03-13 00:20:22 -04:00
parent 58bf80189d
commit e5141238fb
25 changed files with 940 additions and 208 deletions

View File

@@ -177,7 +177,7 @@ function buildKpiDimensionBreakdown(input: {
continue;
}
const matchedFacts = input.facts.filter((fact) => row.sourceFactIds.includes(fact.id));
const matchedFacts = input.facts.filter((fact) => (row.sourceFactIds ?? []).includes(fact.id));
if (matchedFacts.length === 0) {
continue;
}
@@ -213,9 +213,9 @@ function latestPeriodDate(period: FinancialStatementPeriod) {
function cloneStructuredKpiRow(row: StructuredKpiRow): StructuredKpiRow {
return {
...row,
values: { ...row.values },
sourceConcepts: [...row.sourceConcepts],
sourceFactIds: [...row.sourceFactIds]
values: { ...(row.values ?? {}) },
sourceConcepts: [...(row.sourceConcepts ?? [])],
sourceFactIds: [...(row.sourceFactIds ?? [])]
};
}
@@ -230,7 +230,7 @@ function mergeStructuredKpiRowsByPriority(groups: StructuredKpiRow[][]) {
continue;
}
for (const [periodId, value] of Object.entries(row.values)) {
for (const [periodId, value] of Object.entries(row.values ?? {})) {
const hasExistingValue = Object.prototype.hasOwnProperty.call(existing.values, periodId)
&& existing.values[periodId] !== null;
if (!hasExistingValue) {
@@ -238,9 +238,9 @@ function mergeStructuredKpiRowsByPriority(groups: StructuredKpiRow[][]) {
}
}
existing.sourceConcepts = [...new Set([...existing.sourceConcepts, ...row.sourceConcepts])]
existing.sourceConcepts = [...new Set([...existing.sourceConcepts, ...(row.sourceConcepts ?? [])])]
.sort((left, right) => left.localeCompare(right));
existing.sourceFactIds = [...new Set([...existing.sourceFactIds, ...row.sourceFactIds])]
existing.sourceFactIds = [...new Set([...existing.sourceFactIds, ...(row.sourceFactIds ?? [])])]
.sort((left, right) => left - right);
existing.hasDimensions = existing.hasDimensions || row.hasDimensions;
existing.segment ??= row.segment;
@@ -260,11 +260,16 @@ function mergeStructuredKpiRowsByPriority(groups: StructuredKpiRow[][]) {
function emptyNormalizationMetadata(): NormalizationMetadata {
return {
parserEngine: 'unknown',
regime: 'unknown',
fiscalPack: null,
parserVersion: '0.0.0',
surfaceRowCount: 0,
detailRowCount: 0,
kpiRowCount: 0,
unmappedRowCount: 0,
materialUnmappedRowCount: 0
materialUnmappedRowCount: 0,
warnings: []
};
}
@@ -277,9 +282,22 @@ function buildNormalizationMetadata(
}
return {
parserEngine: latestSnapshot.parser_engine,
regime: latestSnapshot.taxonomy_regime,
fiscalPack: latestSnapshot.fiscal_pack,
parserVersion: latestSnapshot.parser_version,
surfaceRowCount: snapshots.reduce(
(sum, snapshot) => sum + (snapshot.normalization_summary?.surfaceRowCount ?? 0),
0
),
detailRowCount: snapshots.reduce(
(sum, snapshot) => sum + (snapshot.normalization_summary?.detailRowCount ?? 0),
0
),
kpiRowCount: snapshots.reduce(
(sum, snapshot) => sum + (snapshot.normalization_summary?.kpiRowCount ?? 0),
0
),
unmappedRowCount: snapshots.reduce(
(sum, snapshot) => sum + (snapshot.normalization_summary?.unmappedRowCount ?? 0),
0
@@ -287,7 +305,9 @@ function buildNormalizationMetadata(
materialUnmappedRowCount: snapshots.reduce(
(sum, snapshot) => sum + (snapshot.normalization_summary?.materialUnmappedRowCount ?? 0),
0
)
),
warnings: [...new Set(snapshots.flatMap((snapshot) => snapshot.normalization_summary?.warnings ?? []))]
.sort((left, right) => left.localeCompare(right))
};
}
@@ -329,8 +349,12 @@ function aggregateSurfaceRows(input: {
for (const snapshot of input.snapshots) {
const rows = snapshot.surface_rows?.[input.statement] ?? [];
for (const row of rows) {
const sourceConcepts = row.sourceConcepts ?? [];
const sourceRowKeys = row.sourceRowKeys ?? [];
const sourceFactIds = row.sourceFactIds ?? [];
const rowValues = row.values ?? {};
const filteredValues = Object.fromEntries(
Object.entries(row.values).filter(([periodId]) => input.selectedPeriodIds.has(periodId))
Object.entries(rowValues).filter(([periodId]) => input.selectedPeriodIds.has(periodId))
);
const filteredResolvedSourceRowKeys = Object.fromEntries(
Object.entries(row.resolvedSourceRowKeys ?? {}).filter(([periodId]) => input.selectedPeriodIds.has(periodId))
@@ -345,9 +369,9 @@ function aggregateSurfaceRows(input: {
...row,
values: filteredValues,
resolvedSourceRowKeys: filteredResolvedSourceRowKeys,
sourceConcepts: [...row.sourceConcepts],
sourceRowKeys: [...row.sourceRowKeys],
sourceFactIds: [...row.sourceFactIds],
sourceConcepts: [...sourceConcepts],
sourceRowKeys: [...sourceRowKeys],
sourceFactIds: [...sourceFactIds],
warningCodes: row.warningCodes ? [...row.warningCodes] : undefined
});
continue;
@@ -365,9 +389,9 @@ function aggregateSurfaceRows(input: {
}
}
existing.sourceConcepts = [...new Set([...existing.sourceConcepts, ...row.sourceConcepts])].sort((left, right) => left.localeCompare(right));
existing.sourceRowKeys = [...new Set([...existing.sourceRowKeys, ...row.sourceRowKeys])].sort((left, right) => left.localeCompare(right));
existing.sourceFactIds = [...new Set([...existing.sourceFactIds, ...row.sourceFactIds])].sort((left, right) => left - right);
existing.sourceConcepts = [...new Set([...existing.sourceConcepts, ...sourceConcepts])].sort((left, right) => left.localeCompare(right));
existing.sourceRowKeys = [...new Set([...existing.sourceRowKeys, ...sourceRowKeys])].sort((left, right) => left.localeCompare(right));
existing.sourceFactIds = [...new Set([...existing.sourceFactIds, ...sourceFactIds])].sort((left, right) => left - right);
existing.hasDimensions = existing.hasDimensions || row.hasDimensions;
existing.order = Math.min(existing.order, row.order);
existing.detailCount = Math.max(existing.detailCount ?? 0, row.detailCount ?? 0);
@@ -406,8 +430,11 @@ function aggregateDetailRows(input: {
}
for (const row of rows) {
const sourceFactIds = row.sourceFactIds ?? [];
const dimensionsSummary = row.dimensionsSummary ?? [];
const rowValues = row.values ?? {};
const filteredValues = Object.fromEntries(
Object.entries(row.values).filter(([periodId]) => input.selectedPeriodIds.has(periodId))
Object.entries(rowValues).filter(([periodId]) => input.selectedPeriodIds.has(periodId))
);
if (!rowHasValues(filteredValues)) {
continue;
@@ -418,8 +445,8 @@ function aggregateDetailRows(input: {
bucket.set(row.key, {
...row,
values: filteredValues,
sourceFactIds: [...row.sourceFactIds],
dimensionsSummary: [...row.dimensionsSummary]
sourceFactIds: [...sourceFactIds],
dimensionsSummary: [...dimensionsSummary]
});
continue;
}
@@ -430,8 +457,8 @@ function aggregateDetailRows(input: {
}
}
existing.sourceFactIds = [...new Set([...existing.sourceFactIds, ...row.sourceFactIds])].sort((left, right) => left - right);
existing.dimensionsSummary = [...new Set([...existing.dimensionsSummary, ...row.dimensionsSummary])].sort((left, right) => left.localeCompare(right));
existing.sourceFactIds = [...new Set([...existing.sourceFactIds, ...sourceFactIds])].sort((left, right) => left - right);
existing.dimensionsSummary = [...new Set([...existing.dimensionsSummary, ...dimensionsSummary])].sort((left, right) => left.localeCompare(right));
existing.isExtension = existing.isExtension || row.isExtension;
existing.residualFlag = existing.residualFlag || row.residualFlag;
}
@@ -521,8 +548,11 @@ function aggregatePersistedKpiRows(input: {
for (const snapshot of input.snapshots) {
for (const row of snapshot.kpi_rows ?? []) {
const sourceConcepts = row.sourceConcepts ?? [];
const sourceFactIds = row.sourceFactIds ?? [];
const rowValues = row.values ?? {};
const filteredValues = Object.fromEntries(
Object.entries(row.values).filter(([periodId]) => input.selectedPeriodIds.has(periodId))
Object.entries(rowValues).filter(([periodId]) => input.selectedPeriodIds.has(periodId))
);
if (!rowHasValues(filteredValues)) {
continue;
@@ -533,8 +563,8 @@ function aggregatePersistedKpiRows(input: {
rowMap.set(row.key, {
...row,
values: filteredValues,
sourceConcepts: [...row.sourceConcepts],
sourceFactIds: [...row.sourceFactIds]
sourceConcepts: [...sourceConcepts],
sourceFactIds: [...sourceFactIds]
});
continue;
}
@@ -543,8 +573,8 @@ function aggregatePersistedKpiRows(input: {
...existing.values,
...filteredValues
};
existing.sourceConcepts = [...new Set([...existing.sourceConcepts, ...row.sourceConcepts])].sort((left, right) => left.localeCompare(right));
existing.sourceFactIds = [...new Set([...existing.sourceFactIds, ...row.sourceFactIds])].sort((left, right) => left - right);
existing.sourceConcepts = [...new Set([...existing.sourceConcepts, ...sourceConcepts])].sort((left, right) => left.localeCompare(right));
existing.sourceFactIds = [...new Set([...existing.sourceFactIds, ...sourceFactIds])].sort((left, right) => left - right);
existing.hasDimensions = existing.hasDimensions || row.hasDimensions;
}
}