955 lines
22 KiB
TypeScript
955 lines
22 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 TickerAutomationSource =
|
|
| "analysis"
|
|
| "financials"
|
|
| "search"
|
|
| "graphing"
|
|
| "research";
|
|
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 TaskStageContext = {
|
|
progress?: {
|
|
current: number;
|
|
total: number;
|
|
unit: string;
|
|
} | null;
|
|
counters?: Record<string, number>;
|
|
subject?: {
|
|
ticker?: string;
|
|
accessionNumber?: string;
|
|
label?: string;
|
|
} | null;
|
|
};
|
|
|
|
export type TaskNotificationStat = {
|
|
label: string;
|
|
value: string;
|
|
};
|
|
|
|
export type TaskNotificationAction = {
|
|
id:
|
|
| "open_details"
|
|
| "open_filings"
|
|
| "open_analysis"
|
|
| "open_analysis_report"
|
|
| "open_search"
|
|
| "open_portfolio";
|
|
label: string;
|
|
href: string | null;
|
|
primary?: boolean;
|
|
};
|
|
|
|
export type TaskNotificationView = {
|
|
title: string;
|
|
statusLine: string;
|
|
detailLine: string | null;
|
|
tone: "info" | "success" | "error";
|
|
progress: {
|
|
current: number;
|
|
total: number;
|
|
unit: string;
|
|
percent: number | null;
|
|
} | null;
|
|
stats: TaskNotificationStat[];
|
|
actions: TaskNotificationAction[];
|
|
};
|
|
|
|
export type TaskNotificationEntry = {
|
|
id: string;
|
|
kind: "single" | "filing_sync_batch";
|
|
status: TaskStatus;
|
|
title: string;
|
|
statusLine: string;
|
|
detailLine: string | null;
|
|
progress: TaskNotificationView["progress"];
|
|
stats: TaskNotificationStat[];
|
|
updatedAt: string;
|
|
primaryTaskId: string;
|
|
taskIds: string[];
|
|
actions: TaskNotificationAction[];
|
|
notificationReadAt: string | null;
|
|
notificationSilencedAt: string | null;
|
|
meta?: {
|
|
tickerCount: number;
|
|
runningCount: number;
|
|
queuedCount: number;
|
|
failureCount: number;
|
|
};
|
|
};
|
|
|
|
export type Task = {
|
|
id: string;
|
|
user_id: string;
|
|
task_type: TaskType;
|
|
status: TaskStatus;
|
|
stage: TaskStage;
|
|
stage_detail: string | null;
|
|
stage_context: TaskStageContext | 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;
|
|
notification: TaskNotificationView;
|
|
};
|
|
|
|
export type TaskStageEvent = {
|
|
id: number;
|
|
task_id: string;
|
|
user_id: string;
|
|
stage: TaskStage;
|
|
stage_detail: string | null;
|
|
stage_context: TaskStageContext | 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"
|
|
| "disclosure"
|
|
| "equity"
|
|
| "comprehensive_income";
|
|
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"
|
|
| "equity_statement"
|
|
| "disclosures"
|
|
| "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[];
|
|
};
|
|
|
|
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;
|
|
type StandardizedStatementRow = StandardizedFinancialRow;
|
|
export type SurfaceFinancialRow = StandardizedFinancialRow & {
|
|
statement?: Extract<
|
|
FinancialStatementKind,
|
|
"income" | "balance" | "cash_flow" | "equity" | "disclosure"
|
|
>;
|
|
detailCount?: number;
|
|
resolutionMethod?:
|
|
| "direct"
|
|
| "surface_bridge"
|
|
| "formula_derived"
|
|
| "not_meaningful";
|
|
confidence?: "high" | "medium" | "low";
|
|
warningCodes?: string[];
|
|
};
|
|
|
|
export type DetailFinancialRow = {
|
|
key: string;
|
|
parentSurfaceKey: string;
|
|
label: string;
|
|
conceptKey: string;
|
|
qname: string;
|
|
namespaceUri: string;
|
|
localName: string;
|
|
unit: string | null;
|
|
values: Record<string, number | null>;
|
|
sourceFactIds: number[];
|
|
isExtension: boolean;
|
|
dimensionsSummary: string[];
|
|
residualFlag: boolean;
|
|
};
|
|
|
|
export type SurfaceDetailMap = Record<string, DetailFinancialRow[]>;
|
|
|
|
export type NormalizationSummary = {
|
|
surfaceRowCount: number;
|
|
detailRowCount: number;
|
|
kpiRowCount: number;
|
|
unmappedRowCount: number;
|
|
materialUnmappedRowCount: number;
|
|
residualPrimaryCount: number;
|
|
residualDisclosureCount: number;
|
|
unsupportedConceptCount: number;
|
|
issuerOverlayMatchCount: number;
|
|
warnings: string[];
|
|
};
|
|
|
|
export type NormalizationMetadata = {
|
|
parserEngine: string;
|
|
regime: "us-gaap" | "ifrs-full" | "unknown";
|
|
fiscalPack: string | null;
|
|
parserVersion: string;
|
|
surfaceRowCount: number;
|
|
detailRowCount: number;
|
|
kpiRowCount: number;
|
|
unmappedRowCount: number;
|
|
materialUnmappedRowCount: number;
|
|
residualPrimaryCount: number;
|
|
residualDisclosureCount: number;
|
|
unsupportedConceptCount: number;
|
|
issuerOverlayMatchCount: number;
|
|
warnings: string[];
|
|
};
|
|
|
|
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;
|
|
};
|
|
|
|
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: SurfaceFinancialRow[];
|
|
} | null;
|
|
statementDetails: SurfaceDetailMap | 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;
|
|
};
|
|
normalization: NormalizationMetadata;
|
|
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 CompanyProfile = {
|
|
description: string | null;
|
|
exchange: string | null;
|
|
industry: string | null;
|
|
country: string | null;
|
|
website: string | null;
|
|
fiscalYearEnd: string | null;
|
|
employeeCount: number | null;
|
|
source: "sec_derived" | "unavailable";
|
|
};
|
|
|
|
export type CompanyValuationSnapshot = {
|
|
sharesOutstanding: number | null;
|
|
marketCap: number | null;
|
|
enterpriseValue: number | null;
|
|
trailingPe: number | null;
|
|
evToRevenue: number | null;
|
|
evToEbitda: number | null;
|
|
source: "derived" | "partial" | "unavailable";
|
|
};
|
|
|
|
export type CompanyBullBear = {
|
|
source: "ai_synthesized" | "memo_fallback" | "unavailable";
|
|
bull: string[];
|
|
bear: string[];
|
|
updatedAt: string | null;
|
|
};
|
|
|
|
export type RecentDevelopmentKind =
|
|
| "8-K"
|
|
| "10-K"
|
|
| "10-Q"
|
|
| "press_release"
|
|
| "news";
|
|
|
|
export type RecentDevelopmentItem = {
|
|
id: string;
|
|
kind: RecentDevelopmentKind;
|
|
title: string;
|
|
url: string | null;
|
|
source: string;
|
|
publishedAt: string;
|
|
summary: string | null;
|
|
accessionNumber: string | null;
|
|
};
|
|
|
|
export type RecentDevelopmentsWeeklySnapshot = {
|
|
summary: string;
|
|
highlights: string[];
|
|
itemCount: number;
|
|
startDate: string;
|
|
endDate: string;
|
|
updatedAt: string;
|
|
source: "ai_synthesized" | "heuristic";
|
|
};
|
|
|
|
export type RecentDevelopments = {
|
|
status: "ready" | "partial" | "unavailable";
|
|
items: RecentDevelopmentItem[];
|
|
weeklySnapshot: RecentDevelopmentsWeeklySnapshot | null;
|
|
};
|
|
|
|
export type PriceData<T> = {
|
|
value: T;
|
|
stale: boolean;
|
|
};
|
|
|
|
export type CompanyAnalysis = {
|
|
company: {
|
|
ticker: string;
|
|
companyName: string;
|
|
sector: string | null;
|
|
category: string | null;
|
|
tags: string[];
|
|
cik: string | null;
|
|
};
|
|
quote: PriceData<number | null>;
|
|
position: Holding | null;
|
|
priceHistory: PriceData<Array<{ date: string; close: number }> | null>;
|
|
benchmarkHistory: PriceData<Array<{ date: string; close: number }> | null>;
|
|
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;
|
|
};
|
|
companyProfile: CompanyProfile;
|
|
valuationSnapshot: CompanyValuationSnapshot;
|
|
bullBear: CompanyBullBear;
|
|
recentDevelopments: RecentDevelopments;
|
|
};
|
|
|
|
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;
|
|
};
|
|
|
|
// Chart Types
|
|
export type ChartType = "line" | "combination";
|
|
export type TimeRange = "1W" | "1M" | "3M" | "1Y" | "3Y" | "5Y" | "10Y" | "20Y";
|
|
|
|
// Chart Data Formats
|
|
export type PriceDataPoint = {
|
|
date: string;
|
|
price: number;
|
|
};
|
|
|
|
export type OHLCVDataPoint = {
|
|
date: string;
|
|
open: number;
|
|
high: number;
|
|
low: number;
|
|
close: number;
|
|
volume: number;
|
|
};
|
|
|
|
export type ChartDataPoint = PriceDataPoint | OHLCVDataPoint;
|
|
|
|
export type DataSeries<T extends ChartDataPoint = ChartDataPoint> = {
|
|
id: string;
|
|
label: string;
|
|
data: T[];
|
|
color?: string;
|
|
type?: "line" | "area" | "bar";
|
|
visible?: boolean;
|
|
};
|
|
|
|
// Chart Configuration
|
|
export type ChartZoomState = {
|
|
startIndex: number;
|
|
endIndex: number;
|
|
isZoomed: boolean;
|
|
};
|
|
|
|
export type ChartColorPalette = {
|
|
primary: string;
|
|
secondary: string;
|
|
positive: string;
|
|
negative: string;
|
|
grid: string;
|
|
text: string;
|
|
muted: string;
|
|
tooltipBg: string;
|
|
tooltipBorder: string;
|
|
volume: string;
|
|
};
|
|
|
|
export type InteractivePriceChartProps = {
|
|
// Data
|
|
data: ChartDataPoint[];
|
|
dataSeries?: DataSeries[];
|
|
|
|
// Configuration
|
|
defaultChartType?: ChartType;
|
|
defaultTimeRange?: TimeRange;
|
|
showVolume?: boolean;
|
|
showToolbar?: boolean;
|
|
height?: number;
|
|
|
|
// Customization
|
|
colors?: Partial<ChartColorPalette>;
|
|
formatters?: {
|
|
price?: (value: number) => string;
|
|
date?: (value: string) => string;
|
|
volume?: (value: number) => string;
|
|
};
|
|
|
|
// Event handlers
|
|
onChartTypeChange?: (type: ChartType) => void;
|
|
onTimeRangeChange?: (range: TimeRange) => void;
|
|
onDataPointHover?: (point: ChartDataPoint | null) => void;
|
|
onZoomChange?: (state: ChartZoomState) => void;
|
|
|
|
// State
|
|
loading?: boolean;
|
|
error?: string | null;
|
|
|
|
// Accessibility
|
|
ariaLabel?: string;
|
|
description?: string;
|
|
};
|