636 lines
15 KiB
TypeScript
636 lines
15 KiB
TypeScript
export type User = {
|
|
id: string;
|
|
email: string;
|
|
name: string | null;
|
|
image: string | null;
|
|
};
|
|
|
|
export type CoverageStatus = 'backlog' | 'active' | 'watch' | 'archive';
|
|
export type CoveragePriority = 'low' | 'medium' | 'high';
|
|
export type ResearchJournalEntryType = 'note' | 'filing_note' | 'status_change';
|
|
export type NumberScaleUnit = 'thousands' | 'millions' | 'billions';
|
|
export type ResearchArtifactKind = 'filing' | 'ai_report' | 'note' | 'upload' | 'memo_snapshot' | 'status_change';
|
|
export type ResearchArtifactSource = 'system' | 'user';
|
|
export type ResearchVisibilityScope = 'private' | 'organization';
|
|
export type ResearchMemoRating = 'strong_buy' | 'buy' | 'hold' | 'sell';
|
|
export type ResearchMemoConviction = 'low' | 'medium' | 'high';
|
|
export type ResearchMemoSection =
|
|
| 'thesis'
|
|
| 'variant_view'
|
|
| 'catalysts'
|
|
| 'risks'
|
|
| 'disconfirming_evidence'
|
|
| 'next_actions';
|
|
|
|
export type WatchlistItem = {
|
|
id: number;
|
|
user_id: string;
|
|
ticker: string;
|
|
company_name: string;
|
|
sector: string | null;
|
|
category: string | null;
|
|
tags: string[];
|
|
created_at: string;
|
|
status: CoverageStatus;
|
|
priority: CoveragePriority;
|
|
updated_at: string;
|
|
last_reviewed_at: string | null;
|
|
latest_filing_date: string | null;
|
|
};
|
|
|
|
export type Holding = {
|
|
id: number;
|
|
user_id: string;
|
|
ticker: string;
|
|
company_name: string | null;
|
|
shares: string;
|
|
avg_cost: string;
|
|
current_price: string | null;
|
|
market_value: string;
|
|
gain_loss: string;
|
|
gain_loss_pct: string;
|
|
last_price_at: string | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
};
|
|
|
|
export type PortfolioSummary = {
|
|
positions: number;
|
|
total_value: string;
|
|
total_gain_loss: string;
|
|
total_cost_basis: string;
|
|
avg_return_pct: string;
|
|
};
|
|
|
|
export type FilingExtraction = {
|
|
summary: string;
|
|
keyPoints: string[];
|
|
redFlags: string[];
|
|
followUpQuestions: string[];
|
|
portfolioSignals: string[];
|
|
segmentSpecificData: string[];
|
|
geographicRevenueBreakdown: string[];
|
|
companySpecificData: string[];
|
|
secApiCrossChecks: string[];
|
|
confidence: number;
|
|
};
|
|
|
|
export type FilingExtractionMeta = {
|
|
provider: string;
|
|
model: string;
|
|
source: 'primary_document' | 'metadata_fallback';
|
|
generatedAt: string;
|
|
};
|
|
|
|
export type Filing = {
|
|
id: number;
|
|
ticker: string;
|
|
filing_type: '10-K' | '10-Q' | '8-K';
|
|
filing_date: string;
|
|
accession_number: string;
|
|
cik: string;
|
|
company_name: string;
|
|
filing_url: string | null;
|
|
submission_url?: string | null;
|
|
primary_document?: string | null;
|
|
metrics: {
|
|
revenue: number | null;
|
|
netIncome: number | null;
|
|
totalAssets: number | null;
|
|
cash: number | null;
|
|
debt: number | null;
|
|
} | null;
|
|
analysis: {
|
|
provider?: string;
|
|
model?: string;
|
|
text?: string;
|
|
legacyInsights?: string;
|
|
companyMetrics?: string[];
|
|
extraction?: FilingExtraction;
|
|
extractionMeta?: FilingExtractionMeta;
|
|
} | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
};
|
|
|
|
export type TaskStatus = 'queued' | 'running' | 'completed' | 'failed';
|
|
export type TaskType =
|
|
| 'sync_filings'
|
|
| 'refresh_prices'
|
|
| 'analyze_filing'
|
|
| 'portfolio_insights'
|
|
| 'index_search';
|
|
export type TaskStage =
|
|
| 'queued'
|
|
| 'running'
|
|
| 'completed'
|
|
| 'failed'
|
|
| 'sync.fetch_filings'
|
|
| 'sync.discover_assets'
|
|
| 'sync.extract_taxonomy'
|
|
| 'sync.normalize_taxonomy'
|
|
| 'sync.derive_metrics'
|
|
| 'sync.validate_pdf_metrics'
|
|
| 'sync.persist_taxonomy'
|
|
| 'sync.fetch_metrics'
|
|
| 'sync.persist_filings'
|
|
| 'sync.hydrate_statements'
|
|
| 'refresh.load_holdings'
|
|
| 'refresh.fetch_quotes'
|
|
| 'refresh.persist_prices'
|
|
| 'analyze.load_filing'
|
|
| 'analyze.fetch_document'
|
|
| 'analyze.extract'
|
|
| 'analyze.generate_report'
|
|
| 'analyze.persist_report'
|
|
| 'search.collect_sources'
|
|
| 'search.fetch_documents'
|
|
| 'search.chunk'
|
|
| 'search.embed'
|
|
| 'search.persist'
|
|
| 'insights.load_holdings'
|
|
| 'insights.generate'
|
|
| 'insights.persist';
|
|
|
|
export type Task = {
|
|
id: string;
|
|
user_id: string;
|
|
task_type: TaskType;
|
|
status: TaskStatus;
|
|
stage: TaskStage;
|
|
stage_detail: string | null;
|
|
resource_key: string | null;
|
|
notification_read_at: string | null;
|
|
notification_silenced_at: string | null;
|
|
priority: number;
|
|
payload: Record<string, unknown>;
|
|
result: Record<string, unknown> | null;
|
|
error: string | null;
|
|
attempts: number;
|
|
max_attempts: number;
|
|
workflow_run_id?: string | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
finished_at: string | null;
|
|
};
|
|
|
|
export type TaskStageEvent = {
|
|
id: number;
|
|
task_id: string;
|
|
user_id: string;
|
|
stage: TaskStage;
|
|
stage_detail: string | null;
|
|
status: TaskStatus;
|
|
created_at: string;
|
|
};
|
|
|
|
export type TaskTimeline = {
|
|
task: Task;
|
|
events: TaskStageEvent[];
|
|
};
|
|
|
|
export type PortfolioInsight = {
|
|
id: number;
|
|
user_id: string;
|
|
provider: string;
|
|
model: string;
|
|
content: string;
|
|
created_at: string;
|
|
};
|
|
|
|
export type ResearchJournalEntry = {
|
|
id: number;
|
|
user_id: string;
|
|
ticker: string;
|
|
accession_number: string | null;
|
|
entry_type: ResearchJournalEntryType;
|
|
title: string | null;
|
|
body_markdown: string;
|
|
metadata: Record<string, unknown> | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
};
|
|
|
|
export type SearchSource = 'documents' | 'filings' | 'research';
|
|
export type SearchResult = {
|
|
chunkId: number;
|
|
documentId: number;
|
|
source: SearchSource;
|
|
sourceKind: 'filing_document' | 'filing_brief' | 'research_note';
|
|
sourceRef: string;
|
|
title: string | null;
|
|
ticker: string | null;
|
|
accessionNumber: string | null;
|
|
filingDate: string | null;
|
|
citationLabel: string;
|
|
headingPath: string | null;
|
|
chunkText: string;
|
|
snippet: string;
|
|
score: number;
|
|
vectorRank: number | null;
|
|
lexicalRank: number | null;
|
|
href: string;
|
|
};
|
|
|
|
export type SearchCitation = {
|
|
index: number;
|
|
label: string;
|
|
chunkId: number;
|
|
href: string;
|
|
};
|
|
|
|
export type SearchAnswerResponse = {
|
|
answer: string;
|
|
citations: SearchCitation[];
|
|
results: SearchResult[];
|
|
};
|
|
|
|
export type ResearchArtifact = {
|
|
id: number;
|
|
user_id: string;
|
|
organization_id: string | null;
|
|
ticker: string;
|
|
accession_number: string | null;
|
|
kind: ResearchArtifactKind;
|
|
source: ResearchArtifactSource;
|
|
subtype: string | null;
|
|
title: string | null;
|
|
summary: string | null;
|
|
body_markdown: string | null;
|
|
search_text: string | null;
|
|
visibility_scope: ResearchVisibilityScope;
|
|
tags: string[];
|
|
metadata: Record<string, unknown> | null;
|
|
file_name: string | null;
|
|
mime_type: string | null;
|
|
file_size_bytes: number | null;
|
|
storage_path: string | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
linked_to_memo: boolean;
|
|
};
|
|
|
|
export type ResearchMemo = {
|
|
id: number;
|
|
user_id: string;
|
|
organization_id: string | null;
|
|
ticker: string;
|
|
rating: ResearchMemoRating | null;
|
|
conviction: ResearchMemoConviction | null;
|
|
time_horizon_months: number | null;
|
|
packet_title: string | null;
|
|
packet_subtitle: string | null;
|
|
thesis_markdown: string;
|
|
variant_view_markdown: string;
|
|
catalysts_markdown: string;
|
|
risks_markdown: string;
|
|
disconfirming_evidence_markdown: string;
|
|
next_actions_markdown: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
};
|
|
|
|
export type ResearchMemoEvidenceLink = {
|
|
id: number;
|
|
memo_id: number;
|
|
artifact_id: number;
|
|
section: ResearchMemoSection;
|
|
annotation: string | null;
|
|
sort_order: number;
|
|
created_at: string;
|
|
artifact: ResearchArtifact;
|
|
};
|
|
|
|
export type ResearchPacketSection = {
|
|
section: ResearchMemoSection;
|
|
title: string;
|
|
body_markdown: string;
|
|
evidence: ResearchMemoEvidenceLink[];
|
|
};
|
|
|
|
export type ResearchPacket = {
|
|
ticker: string;
|
|
companyName: string | null;
|
|
generated_at: string;
|
|
memo: ResearchMemo | null;
|
|
sections: ResearchPacketSection[];
|
|
};
|
|
|
|
export type ResearchLibraryResponse = {
|
|
artifacts: ResearchArtifact[];
|
|
availableTags: string[];
|
|
};
|
|
|
|
export type ResearchWorkspace = {
|
|
ticker: string;
|
|
companyName: string | null;
|
|
coverage: WatchlistItem | null;
|
|
latestFilingDate: string | null;
|
|
memo: ResearchMemo | null;
|
|
library: ResearchArtifact[];
|
|
packet: ResearchPacket;
|
|
availableTags: string[];
|
|
};
|
|
|
|
export type CompanyFinancialPoint = {
|
|
filingDate: string;
|
|
filingType: Filing['filing_type'];
|
|
revenue: number | null;
|
|
netIncome: number | null;
|
|
totalAssets: number | null;
|
|
cash: number | null;
|
|
debt: number | null;
|
|
};
|
|
|
|
export type FinancialStatementKind = 'income' | 'balance' | 'cash_flow' | 'equity' | 'comprehensive_income';
|
|
export type FinancialHistoryWindow = '10y' | 'all';
|
|
export type FinancialCadence = 'annual' | 'quarterly' | 'ltm';
|
|
export type FinancialDisplayMode = 'faithful' | 'standardized';
|
|
export type FinancialSurfaceKind =
|
|
| 'income_statement'
|
|
| 'balance_sheet'
|
|
| 'cash_flow_statement'
|
|
| 'ratios'
|
|
| 'segments_kpis'
|
|
| 'adjusted'
|
|
| 'custom_metrics';
|
|
export type FinancialUnit = 'currency' | 'count' | 'shares' | 'percent' | 'ratio';
|
|
export type FinancialCategory = string;
|
|
|
|
export type FinancialStatementPeriod = {
|
|
id: string;
|
|
filingId: number;
|
|
accessionNumber: string;
|
|
filingDate: string;
|
|
periodStart: string | null;
|
|
periodEnd: string | null;
|
|
filingType: Extract<Filing['filing_type'], '10-K' | '10-Q'>;
|
|
periodLabel: string;
|
|
};
|
|
|
|
export type TaxonomyDimensionMember = {
|
|
axis: string;
|
|
member: string;
|
|
};
|
|
|
|
export type TaxonomyStatementRow = {
|
|
key: string;
|
|
label: string;
|
|
conceptKey: string;
|
|
qname: string;
|
|
namespaceUri: string;
|
|
localName: string;
|
|
isExtension: boolean;
|
|
statement: FinancialStatementKind;
|
|
roleUri: string | null;
|
|
order: number;
|
|
depth: number;
|
|
parentKey: string | null;
|
|
values: Record<string, number | null>;
|
|
units: Record<string, string | null>;
|
|
hasDimensions: boolean;
|
|
sourceFactIds: number[];
|
|
};
|
|
|
|
export type FinancialStatementSurfaceKind = FinancialDisplayMode;
|
|
|
|
export type DerivedFinancialRow = {
|
|
key: string;
|
|
label: string;
|
|
category: FinancialCategory;
|
|
templateSection?: FinancialCategory;
|
|
order: number;
|
|
unit: FinancialUnit;
|
|
values: Record<string, number | null>;
|
|
sourceConcepts: string[];
|
|
sourceRowKeys: string[];
|
|
sourceFactIds: number[];
|
|
formulaKey: string | null;
|
|
hasDimensions: boolean;
|
|
resolvedSourceRowKeys: Record<string, string | null>;
|
|
};
|
|
|
|
export type StandardizedFinancialRow = DerivedFinancialRow;
|
|
export type StandardizedStatementRow = StandardizedFinancialRow;
|
|
|
|
export type RatioRow = DerivedFinancialRow & {
|
|
denominatorKey: string | null;
|
|
};
|
|
|
|
export type StructuredKpiRow = {
|
|
key: string;
|
|
label: string;
|
|
category: FinancialCategory;
|
|
unit: FinancialUnit;
|
|
order: number;
|
|
segment: string | null;
|
|
axis: string | null;
|
|
member: string | null;
|
|
values: Record<string, number | null>;
|
|
sourceConcepts: string[];
|
|
sourceFactIds: number[];
|
|
provenanceType: 'taxonomy' | 'structured_note';
|
|
hasDimensions: boolean;
|
|
};
|
|
|
|
export type TaxonomyFactRow = {
|
|
id: number;
|
|
snapshotId: number;
|
|
filingId: number;
|
|
filingDate: string;
|
|
statement: FinancialStatementKind | null;
|
|
roleUri: string | null;
|
|
conceptKey: string;
|
|
qname: string;
|
|
namespaceUri: string;
|
|
localName: string;
|
|
value: number;
|
|
contextId: string;
|
|
unit: string | null;
|
|
decimals: string | null;
|
|
periodStart: string | null;
|
|
periodEnd: string | null;
|
|
periodInstant: string | null;
|
|
dimensions: TaxonomyDimensionMember[];
|
|
isDimensionless: boolean;
|
|
sourceFile: string | null;
|
|
};
|
|
|
|
export type MetricValidationCheck = {
|
|
metricKey: keyof NonNullable<Filing['metrics']>;
|
|
taxonomyValue: number | null;
|
|
llmValue: number | null;
|
|
absoluteDiff: number | null;
|
|
relativeDiff: number | null;
|
|
status: 'not_run' | 'matched' | 'mismatch' | 'error';
|
|
evidencePages: number[];
|
|
pdfUrl: string | null;
|
|
provider: string | null;
|
|
model: string | null;
|
|
error: string | null;
|
|
};
|
|
|
|
export type MetricValidationResult = {
|
|
status: 'not_run' | 'matched' | 'mismatch' | 'error';
|
|
checks: MetricValidationCheck[];
|
|
validatedAt: string | null;
|
|
};
|
|
|
|
export type FilingFaithfulStatementRow = {
|
|
key: string;
|
|
label: string;
|
|
concept: string | null;
|
|
order: number;
|
|
depth: number;
|
|
isSubtotal: boolean;
|
|
values: Record<string, number | null>;
|
|
hasDimensions: boolean;
|
|
};
|
|
|
|
export type DimensionBreakdownRow = {
|
|
rowKey: string;
|
|
concept: string | null;
|
|
sourceRowKey: string | null;
|
|
sourceLabel: string | null;
|
|
periodId: string;
|
|
axis: string;
|
|
member: string;
|
|
value: number | null;
|
|
unit: string | null;
|
|
provenanceType?: 'taxonomy' | 'structured_note';
|
|
};
|
|
|
|
export type TrendSeries = {
|
|
key: string;
|
|
label: string;
|
|
category: FinancialCategory;
|
|
unit: FinancialUnit;
|
|
values: Record<string, number | null>;
|
|
};
|
|
|
|
export type CompanyFinancialStatementsResponse = {
|
|
company: {
|
|
ticker: string;
|
|
companyName: string;
|
|
cik: string | null;
|
|
};
|
|
surfaceKind: FinancialSurfaceKind;
|
|
cadence: FinancialCadence;
|
|
displayModes: FinancialDisplayMode[];
|
|
defaultDisplayMode: FinancialDisplayMode;
|
|
periods: FinancialStatementPeriod[];
|
|
statementRows: {
|
|
faithful: TaxonomyStatementRow[];
|
|
standardized: StandardizedFinancialRow[];
|
|
} | null;
|
|
ratioRows: RatioRow[] | null;
|
|
kpiRows: StructuredKpiRow[] | null;
|
|
trendSeries: TrendSeries[];
|
|
categories: Array<{
|
|
key: FinancialCategory;
|
|
label: string;
|
|
count: number;
|
|
}>;
|
|
availability: {
|
|
adjusted: boolean;
|
|
customMetrics: boolean;
|
|
};
|
|
nextCursor: string | null;
|
|
facts: {
|
|
rows: TaxonomyFactRow[];
|
|
nextCursor: string | null;
|
|
} | null;
|
|
coverage: {
|
|
filings: number;
|
|
rows: number;
|
|
dimensions: number;
|
|
facts: number;
|
|
};
|
|
dataSourceStatus: {
|
|
enabled: boolean;
|
|
hydratedFilings: number;
|
|
partialFilings: number;
|
|
failedFilings: number;
|
|
pendingFilings: number;
|
|
queuedSync: boolean;
|
|
};
|
|
metrics: {
|
|
taxonomy: Filing['metrics'];
|
|
validation: MetricValidationResult | null;
|
|
};
|
|
dimensionBreakdown: Record<string, DimensionBreakdownRow[]> | null;
|
|
};
|
|
|
|
export type CompanyAiReport = {
|
|
accessionNumber: string;
|
|
filingDate: string;
|
|
filingType: Filing['filing_type'];
|
|
provider: string;
|
|
model: string;
|
|
summary: string;
|
|
};
|
|
|
|
export type CompanyAiReportDetail = CompanyAiReport & {
|
|
ticker: string;
|
|
companyName: string;
|
|
filingUrl: string | null;
|
|
submissionUrl: string | null;
|
|
primaryDocument: string | null;
|
|
};
|
|
|
|
export type CompanyAnalysis = {
|
|
company: {
|
|
ticker: string;
|
|
companyName: string;
|
|
sector: string | null;
|
|
category: string | null;
|
|
tags: string[];
|
|
cik: string | null;
|
|
};
|
|
quote: number;
|
|
position: Holding | null;
|
|
priceHistory: Array<{ date: string; close: number }>;
|
|
financials: CompanyFinancialPoint[];
|
|
filings: Filing[];
|
|
aiReports: CompanyAiReport[];
|
|
coverage: WatchlistItem | null;
|
|
journalPreview: ResearchJournalEntry[];
|
|
recentAiReports: CompanyAiReport[];
|
|
latestFilingSummary: {
|
|
accessionNumber: string;
|
|
filingDate: string;
|
|
filingType: Filing['filing_type'];
|
|
filingUrl: string | null;
|
|
submissionUrl: string | null;
|
|
summary: string | null;
|
|
hasAnalysis: boolean;
|
|
} | null;
|
|
keyMetrics: {
|
|
referenceDate: string | null;
|
|
revenue: number | null;
|
|
netIncome: number | null;
|
|
totalAssets: number | null;
|
|
cash: number | null;
|
|
debt: number | null;
|
|
netMargin: number | null;
|
|
};
|
|
};
|
|
|
|
export type NavGroup = 'overview' | 'research' | 'portfolio';
|
|
export type NavMatchMode = 'exact' | 'prefix';
|
|
|
|
export type NavItem = {
|
|
id: string;
|
|
href: string;
|
|
label: string;
|
|
group: NavGroup;
|
|
matchMode: NavMatchMode;
|
|
preserveTicker?: boolean;
|
|
mobilePrimary?: boolean;
|
|
};
|
|
|
|
export type ActiveContext = {
|
|
pathname: string;
|
|
activeTicker: string | null;
|
|
};
|