Add research workspace and graphing flows

This commit is contained in:
2026-03-07 16:52:35 -05:00
parent db01f207a5
commit 62bacdf104
37 changed files with 5494 additions and 434 deletions

View File

@@ -13,6 +13,18 @@ export const queryKeys = {
) => ['financials-v3', ticker, surfaceKind, cadence, includeDimensions ? 'dims' : 'no-dims', includeFacts ? 'facts' : 'rows', factsCursor ?? '', factsLimit, cursor ?? '', limit] as const,
filings: (ticker: string | null, limit: number) => ['filings', ticker ?? '', limit] as const,
report: (accessionNumber: string) => ['report', accessionNumber] as const,
researchWorkspace: (ticker: string) => ['research', 'workspace', ticker] as const,
researchLibrary: (
ticker: string,
q: string,
kind: string,
tag: string,
source: string,
linkedToMemo: string,
limit: number
) => ['research', 'library', ticker, q, kind, tag, source, linkedToMemo, limit] as const,
researchMemo: (ticker: string) => ['research', 'memo', ticker] as const,
researchPacket: (ticker: string) => ['research', 'packet', ticker] as const,
watchlist: () => ['watchlist'] as const,
researchJournal: (ticker: string) => ['research', 'journal', ticker] as const,
holdings: () => ['portfolio', 'holdings'] as const,

View File

@@ -5,9 +5,13 @@ import {
getCompanyFinancialStatements,
getLatestPortfolioInsight,
getPortfolioSummary,
getResearchMemo,
getResearchPacket,
getResearchWorkspace,
getTask,
getTaskTimeline,
listFilings,
listResearchLibrary,
listHoldings,
listRecentTasks,
listResearchJournal,
@@ -16,7 +20,9 @@ import {
import { queryKeys } from '@/lib/query/keys';
import type {
FinancialCadence,
FinancialSurfaceKind
FinancialSurfaceKind,
ResearchArtifactKind,
ResearchArtifactSource
} from '@/lib/types';
export function companyAnalysisQueryOptions(ticker: string) {
@@ -96,6 +102,68 @@ export function aiReportQueryOptions(accessionNumber: string) {
});
}
export function researchWorkspaceQueryOptions(ticker: string) {
const normalizedTicker = ticker.trim().toUpperCase();
return queryOptions({
queryKey: queryKeys.researchWorkspace(normalizedTicker),
queryFn: () => getResearchWorkspace(normalizedTicker),
staleTime: 15_000
});
}
export function researchLibraryQueryOptions(input: {
ticker: string;
q?: string;
kind?: ResearchArtifactKind;
tag?: string;
source?: ResearchArtifactSource;
linkedToMemo?: boolean;
limit?: number;
}) {
const normalizedTicker = input.ticker.trim().toUpperCase();
const q = input.q?.trim() ?? '';
const kind = input.kind ?? '';
const tag = input.tag?.trim() ?? '';
const source = input.source ?? '';
const linkedToMemo = input.linkedToMemo === undefined ? '' : input.linkedToMemo ? 'true' : 'false';
const limit = input.limit ?? 100;
return queryOptions({
queryKey: queryKeys.researchLibrary(normalizedTicker, q, kind, tag, source, linkedToMemo, limit),
queryFn: () => listResearchLibrary({
ticker: normalizedTicker,
q,
kind: input.kind,
tag,
source: input.source,
linkedToMemo: input.linkedToMemo,
limit
}),
staleTime: 10_000
});
}
export function researchMemoQueryOptions(ticker: string) {
const normalizedTicker = ticker.trim().toUpperCase();
return queryOptions({
queryKey: queryKeys.researchMemo(normalizedTicker),
queryFn: () => getResearchMemo(normalizedTicker),
staleTime: 10_000
});
}
export function researchPacketQueryOptions(ticker: string) {
const normalizedTicker = ticker.trim().toUpperCase();
return queryOptions({
queryKey: queryKeys.researchPacket(normalizedTicker),
queryFn: () => getResearchPacket(normalizedTicker),
staleTime: 10_000
});
}
export function watchlistQueryOptions() {
return queryOptions({
queryKey: queryKeys.watchlist(),