# Conflicts: # app/analysis/page.tsx # app/watchlist/page.tsx # components/shell/app-shell.tsx # lib/api.ts # lib/query/options.ts # lib/server/api/app.ts # lib/server/db/index.test.ts # lib/server/db/index.ts # lib/server/db/schema.ts # lib/server/repos/research-journal.ts # lib/types.ts
259 lines
6.8 KiB
TypeScript
259 lines
6.8 KiB
TypeScript
import { queryOptions } from '@tanstack/react-query';
|
|
import {
|
|
getCompanyAiReport,
|
|
getCompanyAnalysis,
|
|
getCompanyFinancialStatements,
|
|
getLatestPortfolioInsight,
|
|
getPortfolioSummary,
|
|
searchKnowledge,
|
|
getResearchMemo,
|
|
getResearchPacket,
|
|
getResearchWorkspace,
|
|
getTask,
|
|
getTaskTimeline,
|
|
listFilings,
|
|
listResearchLibrary,
|
|
listHoldings,
|
|
listRecentTasks,
|
|
listResearchJournal,
|
|
listWatchlist
|
|
} from '@/lib/api';
|
|
import { queryKeys } from '@/lib/query/keys';
|
|
import type {
|
|
FinancialCadence,
|
|
FinancialSurfaceKind,
|
|
SearchSource,
|
|
ResearchArtifactKind,
|
|
ResearchArtifactSource
|
|
} from '@/lib/types';
|
|
|
|
export function companyAnalysisQueryOptions(ticker: string) {
|
|
const normalizedTicker = ticker.trim().toUpperCase();
|
|
|
|
return queryOptions({
|
|
queryKey: queryKeys.companyAnalysis(normalizedTicker),
|
|
queryFn: () => getCompanyAnalysis(normalizedTicker),
|
|
staleTime: 120_000
|
|
});
|
|
}
|
|
|
|
export function companyFinancialStatementsQueryOptions(input: {
|
|
ticker: string;
|
|
surfaceKind: FinancialSurfaceKind;
|
|
cadence: FinancialCadence;
|
|
includeDimensions?: boolean;
|
|
includeFacts?: boolean;
|
|
factsCursor?: string | null;
|
|
factsLimit?: number;
|
|
cursor?: string | null;
|
|
limit?: number;
|
|
}) {
|
|
const normalizedTicker = input.ticker.trim().toUpperCase();
|
|
const includeDimensions = input.includeDimensions ?? false;
|
|
const includeFacts = input.includeFacts ?? false;
|
|
const factsCursor = input.factsCursor ?? null;
|
|
const factsLimit = input.factsLimit ?? 500;
|
|
const cursor = input.cursor ?? null;
|
|
const limit = input.limit ?? 40;
|
|
|
|
return queryOptions({
|
|
queryKey: queryKeys.companyFinancialStatements(
|
|
normalizedTicker,
|
|
input.surfaceKind,
|
|
input.cadence,
|
|
includeDimensions,
|
|
includeFacts,
|
|
factsCursor,
|
|
factsLimit,
|
|
cursor,
|
|
limit
|
|
),
|
|
queryFn: () => getCompanyFinancialStatements({
|
|
ticker: normalizedTicker,
|
|
surfaceKind: input.surfaceKind,
|
|
cadence: input.cadence,
|
|
includeDimensions,
|
|
includeFacts,
|
|
factsCursor,
|
|
factsLimit,
|
|
cursor,
|
|
limit
|
|
}),
|
|
staleTime: 60_000
|
|
});
|
|
}
|
|
|
|
export function filingsQueryOptions(input: { ticker?: string; limit?: number } = {}) {
|
|
const normalizedTicker = input.ticker?.trim().toUpperCase() ?? null;
|
|
const limit = input.limit ?? 120;
|
|
|
|
return queryOptions({
|
|
queryKey: queryKeys.filings(normalizedTicker, limit),
|
|
queryFn: () => listFilings({ ticker: normalizedTicker ?? undefined, limit }),
|
|
staleTime: 60_000
|
|
});
|
|
}
|
|
|
|
export function searchQueryOptions(input: {
|
|
query: string;
|
|
ticker?: string | null;
|
|
sources?: SearchSource[];
|
|
limit?: number;
|
|
}) {
|
|
const normalizedQuery = input.query.trim();
|
|
const normalizedTicker = input.ticker?.trim().toUpperCase() ?? null;
|
|
const sources = input.sources && input.sources.length > 0
|
|
? [...new Set(input.sources)]
|
|
: ['documents', 'filings', 'research'] as SearchSource[];
|
|
const limit = input.limit ?? 10;
|
|
|
|
return queryOptions({
|
|
queryKey: queryKeys.search(normalizedQuery, normalizedTicker, sources, limit),
|
|
queryFn: () => searchKnowledge({
|
|
query: normalizedQuery,
|
|
ticker: normalizedTicker ?? undefined,
|
|
sources,
|
|
limit
|
|
}),
|
|
staleTime: 30_000
|
|
});
|
|
}
|
|
|
|
export function aiReportQueryOptions(accessionNumber: string) {
|
|
const normalizedAccession = accessionNumber.trim();
|
|
|
|
return queryOptions({
|
|
queryKey: queryKeys.report(normalizedAccession),
|
|
queryFn: () => getCompanyAiReport(normalizedAccession),
|
|
staleTime: 300_000
|
|
});
|
|
}
|
|
|
|
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(),
|
|
queryFn: () => listWatchlist(),
|
|
staleTime: 30_000
|
|
});
|
|
}
|
|
|
|
export function researchJournalQueryOptions(ticker: string) {
|
|
const normalizedTicker = ticker.trim().toUpperCase();
|
|
|
|
return queryOptions({
|
|
queryKey: queryKeys.researchJournal(normalizedTicker),
|
|
queryFn: () => listResearchJournal(normalizedTicker),
|
|
staleTime: 15_000
|
|
});
|
|
}
|
|
|
|
export function holdingsQueryOptions() {
|
|
return queryOptions({
|
|
queryKey: queryKeys.holdings(),
|
|
queryFn: () => listHoldings(),
|
|
staleTime: 30_000
|
|
});
|
|
}
|
|
|
|
export function portfolioSummaryQueryOptions() {
|
|
return queryOptions({
|
|
queryKey: queryKeys.portfolioSummary(),
|
|
queryFn: () => getPortfolioSummary(),
|
|
staleTime: 30_000
|
|
});
|
|
}
|
|
|
|
export function latestPortfolioInsightQueryOptions() {
|
|
return queryOptions({
|
|
queryKey: queryKeys.latestPortfolioInsight(),
|
|
queryFn: () => getLatestPortfolioInsight(),
|
|
staleTime: 30_000
|
|
});
|
|
}
|
|
|
|
export function taskQueryOptions(taskId: string) {
|
|
return queryOptions({
|
|
queryKey: queryKeys.task(taskId),
|
|
queryFn: () => getTask(taskId),
|
|
staleTime: 5_000
|
|
});
|
|
}
|
|
|
|
export function taskTimelineQueryOptions(taskId: string) {
|
|
return queryOptions({
|
|
queryKey: queryKeys.taskTimeline(taskId),
|
|
queryFn: () => getTaskTimeline(taskId),
|
|
staleTime: 5_000
|
|
});
|
|
}
|
|
|
|
export function recentTasksQueryOptions(limit = 20) {
|
|
return queryOptions({
|
|
queryKey: queryKeys.recentTasks(limit),
|
|
queryFn: () => listRecentTasks({ limit }),
|
|
staleTime: 5_000
|
|
});
|
|
}
|