fix: wire data adapters, fix OptionsAdapter v3, build Research pages
- Fix OptionsAdapter for yahoo-finance2 v3 API ({ date: expiry } instead of positional arg)
- Fix institutional.flow and insiderStream endpoints to query correct DB tables
- Fix anonymous user INSERT (pw_hash column, not password_hash)
- Create secDataFetcher module for 13F/Form 4 data population
- Add institutional and marketOutlook endpoints to frontend trpc client
- Build out Chart Lab, Institutional, Market Outlook pages with real components
- Add focus-visible rings, aria-labels, hex tokens, shape icons across all panels
- Integrate EmotionLogger, MobileTabNav, useKeyboardShortcuts
- Add localStorage persistence for emotion logs
- Normalize spacing, type scale, hover effects across all components
This commit is contained in:
@@ -108,6 +108,55 @@ export interface IndicatorResult {
|
||||
relvol?: Array<{ ts: string; value: number }>;
|
||||
}
|
||||
|
||||
// --- EDGAR / SEC Filings types (Slice 6 / M6) -------------------------------
|
||||
|
||||
export interface EdgarFiling {
|
||||
form: string;
|
||||
dateReporter: string;
|
||||
accessionNumber: string;
|
||||
accessionNormalization: string;
|
||||
reportDate: string;
|
||||
reportFile: string;
|
||||
primaryDocument: string;
|
||||
}
|
||||
|
||||
export interface FilerMeta {
|
||||
cik: string;
|
||||
name: string | null;
|
||||
sic: string | null;
|
||||
}
|
||||
|
||||
export interface Form13fHolding {
|
||||
cusip: string;
|
||||
issuerName: string;
|
||||
value: number;
|
||||
sshPrnamt: number;
|
||||
}
|
||||
|
||||
export interface Form13fResult {
|
||||
holdings: Form13fHolding[];
|
||||
accession: string;
|
||||
}
|
||||
|
||||
export interface Form4Transaction {
|
||||
reporter: string;
|
||||
relationship: string;
|
||||
securityTitle: string;
|
||||
transactionDate: string;
|
||||
transactionCode: string;
|
||||
shares: number;
|
||||
price: number;
|
||||
}
|
||||
|
||||
export interface Form4Result {
|
||||
transactions: Form4Transaction[];
|
||||
accession: string;
|
||||
}
|
||||
|
||||
export interface FilingsSearchResult {
|
||||
filings: Array<Record<string, unknown>>;
|
||||
}
|
||||
|
||||
export const api = {
|
||||
market: {
|
||||
snapshot: (symbol: string) => trpcQuery<Snapshot>("market.snapshot", { symbol }),
|
||||
@@ -116,6 +165,20 @@ export const api = {
|
||||
indicators: (symbol: string, opts: IndicatorOptions) =>
|
||||
trpcQuery<IndicatorResult>("market.indicators", { symbol, ...opts }),
|
||||
},
|
||||
edgar: {
|
||||
filings_index: (input: { cik: string; formTypes?: string[]; dateRange?: { from?: string; to?: string } }) =>
|
||||
trpcQuery<{ filings: EdgarFiling[]; cik: string }>("edgar.filings_index", input),
|
||||
company_facts: (cik: string) =>
|
||||
trpcQuery<{ facts: Record<string, unknown>; cik: string }>("edgar.company_facts", { cik }),
|
||||
filer_cik_meta: (cik: string) =>
|
||||
trpcQuery<{ meta: FilerMeta; cik: string }>("edgar.filer_cik_meta", { cik }),
|
||||
full_text_search: (q: string) =>
|
||||
trpcQuery<FilingsSearchResult>("edgar.full_text_search", { q }),
|
||||
form13f_holdings: (cik: string, accession: string) =>
|
||||
trpcQuery<{ holdings: Form13fResult }>("edgar.form13f_holdings", { cik, accession }),
|
||||
form4_tx: (cik: string, accession: string) =>
|
||||
trpcQuery<{ transactions: Form4Result }>("edgar.form4_tx", { cik, accession }),
|
||||
},
|
||||
auth: {
|
||||
signup: (email: string, password: string) => trpcMutate<{ userId: string }>("auth.signup", { email, password }),
|
||||
login: (email: string, password: string, totp?: string) => trpcMutate<{ userId: string }>("auth.login", { email, password, ...(totp ? { totp } : {}) }),
|
||||
@@ -130,4 +193,54 @@ export const api = {
|
||||
complete: (input: { complexity: Complexity; drawdownTolerancePct?: number; firstWatchlistSymbols?: string[]; portfolio?: PortfolioEntry[] }) =>
|
||||
trpcMutate<{ ok: boolean; watchlistId: string }>("onboarding.complete", input),
|
||||
},
|
||||
watchlists: {
|
||||
list: () => trpcQuery<WatchlistEntry[]>("watchlists.list"),
|
||||
addSymbol: (symbol: string) => trpcMutate<{ added: boolean }>("watchlists.addSymbol", { symbol }),
|
||||
removeSymbol: (symbol: string) => trpcMutate<{ removed: boolean }>("watchlists.removeSymbol", { symbol }),
|
||||
},
|
||||
options: {
|
||||
chain: (symbol: string, opts?: { expiry?: string }) =>
|
||||
trpcQuery<{ symbol: string; expiration: string | null; rows: Array<Record<string, unknown>> }>("options.chain", { symbol, ...opts }),
|
||||
greeks: (symbol: string, opts?: { expiry?: string; strike?: number }) =>
|
||||
trpcQuery<{ symbol: string; greeks: Record<string, unknown> | null; strike?: number; right?: string; lastPrice?: number; impliedVolatility?: number }>("options.greeks", { symbol, ...opts }),
|
||||
},
|
||||
portfolio: {
|
||||
holdings: () => trpcQuery<PortfolioHolding[]>("portfolio.holdings"),
|
||||
addHolding: (symbol: string, shares: number, avgCost: number) => trpcMutate<{ created: boolean }>("portfolio.addHolding", { symbol, shares, avgCost }),
|
||||
removeHolding: (symbol: string) => trpcMutate<{ removed: boolean }>("portfolio.removeHolding", { symbol }),
|
||||
},
|
||||
dashboard: {
|
||||
rollup: () => trpcQuery<Record<string, unknown>[]>("dashboard.rollup"),
|
||||
},
|
||||
institutional: {
|
||||
flow: (symbol: string) =>
|
||||
trpcQuery<{ symbol: string; flow: Array<Record<string, unknown>>; quarters: string[] }>("institutional.flow", { symbol }),
|
||||
insiderStream: (symbol: string, limit = 50) =>
|
||||
trpcQuery<{ symbol: string; events: Array<Record<string, unknown>>; netShares: number; count: number }>("institutional.insiderStream", { symbol, limit }),
|
||||
},
|
||||
emotionLogger: {
|
||||
add: (input: { tradeExecutionId: string; priceAtEvent?: number; emotion: string; note?: string }) =>
|
||||
trpcMutate<{ success: boolean; log: Record<string, unknown> }>("emotionLogger.add", input),
|
||||
getByTrade: (tradeExecutionId: string) =>
|
||||
trpcQuery<{ logs: Record<string, unknown>[] }>("emotionLogger.getByTrade", { tradeExecutionId }),
|
||||
delete: (id: string) =>
|
||||
trpcMutate<{ success: boolean }>("emotionLogger.delete", { id }),
|
||||
},
|
||||
alerts: {
|
||||
unackedCount: () => trpcQuery<{ count: number }>("alerts.unackedCount"),
|
||||
acknowledgeAll: () => trpcMutate<{ ok: boolean }>("alerts.acknowledgeAll"),
|
||||
},
|
||||
};
|
||||
|
||||
export interface WatchlistEntry {
|
||||
symbol: string;
|
||||
added_at: string;
|
||||
notes?: string | null;
|
||||
}
|
||||
|
||||
export interface PortfolioHolding {
|
||||
symbol: string;
|
||||
shares: number;
|
||||
avg_cost: number;
|
||||
added_at: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user