feat(financials): add compact surface UI and graphing states
This commit is contained in:
@@ -4,7 +4,7 @@ import type {
|
||||
CompanyFinancialStatementsResponse,
|
||||
FinancialStatementPeriod,
|
||||
RatioRow,
|
||||
StandardizedFinancialRow
|
||||
SurfaceFinancialRow
|
||||
} from '@/lib/types';
|
||||
|
||||
function createPeriod(input: {
|
||||
@@ -26,7 +26,7 @@ function createPeriod(input: {
|
||||
} satisfies FinancialStatementPeriod;
|
||||
}
|
||||
|
||||
function createStatementRow(key: string, values: Record<string, number | null>, unit: StandardizedFinancialRow['unit'] = 'currency') {
|
||||
function createStatementRow(key: string, values: Record<string, number | null>, unit: SurfaceFinancialRow['unit'] = 'currency') {
|
||||
return {
|
||||
key,
|
||||
label: key,
|
||||
@@ -39,8 +39,9 @@ function createStatementRow(key: string, values: Record<string, number | null>,
|
||||
sourceFactIds: [1],
|
||||
formulaKey: null,
|
||||
hasDimensions: false,
|
||||
resolvedSourceRowKeys: Object.fromEntries(Object.keys(values).map((periodId) => [periodId, key]))
|
||||
} satisfies StandardizedFinancialRow;
|
||||
resolvedSourceRowKeys: Object.fromEntries(Object.keys(values).map((periodId) => [periodId, key])),
|
||||
statement: 'income'
|
||||
} satisfies SurfaceFinancialRow;
|
||||
}
|
||||
|
||||
function createRatioRow(key: string, values: Record<string, number | null>, unit: RatioRow['unit'] = 'percent') {
|
||||
@@ -54,8 +55,9 @@ function createFinancials(input: {
|
||||
ticker: string;
|
||||
companyName: string;
|
||||
periods: FinancialStatementPeriod[];
|
||||
statementRows?: StandardizedFinancialRow[];
|
||||
statementRows?: SurfaceFinancialRow[];
|
||||
ratioRows?: RatioRow[];
|
||||
fiscalPack?: string | null;
|
||||
}) {
|
||||
return {
|
||||
company: {
|
||||
@@ -72,6 +74,7 @@ function createFinancials(input: {
|
||||
faithful: [],
|
||||
standardized: input.statementRows ?? []
|
||||
},
|
||||
statementDetails: null,
|
||||
ratioRows: input.ratioRows ?? [],
|
||||
kpiRows: null,
|
||||
trendSeries: [],
|
||||
@@ -100,6 +103,13 @@ function createFinancials(input: {
|
||||
taxonomy: null,
|
||||
validation: null
|
||||
},
|
||||
normalization: {
|
||||
regime: 'unknown',
|
||||
fiscalPack: input.fiscalPack ?? null,
|
||||
parserVersion: '0.0.0',
|
||||
unmappedRowCount: 0,
|
||||
materialUnmappedRowCount: 0
|
||||
},
|
||||
dimensionBreakdown: null
|
||||
} satisfies CompanyFinancialStatementsResponse;
|
||||
}
|
||||
@@ -194,6 +204,37 @@ describe('graphing series', () => {
|
||||
expect(data.hasAnyData).toBe(false);
|
||||
});
|
||||
|
||||
it('marks not meaningful standardized rows separately from missing metric data', () => {
|
||||
const data = buildGraphingComparisonData({
|
||||
surface: 'income_statement',
|
||||
metric: 'gross_profit',
|
||||
results: [
|
||||
{
|
||||
ticker: 'JPM',
|
||||
financials: createFinancials({
|
||||
ticker: 'JPM',
|
||||
companyName: 'JPMorgan Chase & Co.',
|
||||
fiscalPack: 'bank_lender',
|
||||
periods: [createPeriod({ id: 'jpm-fy', filingId: 1, filingDate: '2026-02-13', periodEnd: '2025-12-31', filingType: '10-K' })],
|
||||
statementRows: [{
|
||||
...createStatementRow('gross_profit', { 'jpm-fy': null }),
|
||||
resolutionMethod: 'not_meaningful'
|
||||
}]
|
||||
})
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
expect(data.latestRows[0]).toMatchObject({
|
||||
ticker: 'JPM',
|
||||
fiscalPack: 'bank_lender',
|
||||
status: 'not_meaningful',
|
||||
errorMessage: 'Not meaningful for this pack.'
|
||||
});
|
||||
expect(data.hasAnyData).toBe(false);
|
||||
expect(data.hasPartialData).toBe(true);
|
||||
});
|
||||
|
||||
it('derives latest and prior values for the summary table', () => {
|
||||
const data = buildGraphingComparisonData({
|
||||
surface: 'income_statement',
|
||||
@@ -216,6 +257,7 @@ describe('graphing series', () => {
|
||||
|
||||
expect(data.latestRows[0]).toMatchObject({
|
||||
ticker: 'AMD',
|
||||
fiscalPack: null,
|
||||
latestValue: 70,
|
||||
priorValue: 50,
|
||||
changeValue: 20,
|
||||
|
||||
Reference in New Issue
Block a user