Add company analysis view with financials, price history, filings, and AI reports
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
||||
listWatchlistItems,
|
||||
upsertWatchlistItemRecord
|
||||
} from '@/lib/server/repos/watchlist';
|
||||
import { getPriceHistory, getQuote } from '@/lib/server/prices';
|
||||
import {
|
||||
enqueueTask,
|
||||
getTaskById,
|
||||
@@ -313,6 +314,78 @@ export const app = new Elysia({ prefix: '/api' })
|
||||
|
||||
return Response.json({ insight });
|
||||
})
|
||||
.get('/analysis/company', async ({ query }) => {
|
||||
const { session, response } = await requireAuthenticatedSession();
|
||||
if (response) {
|
||||
return response;
|
||||
}
|
||||
|
||||
const ticker = typeof query.ticker === 'string' ? query.ticker.trim().toUpperCase() : '';
|
||||
if (!ticker) {
|
||||
return jsonError('ticker is required');
|
||||
}
|
||||
|
||||
const [filings, holdings, watchlist, liveQuote, priceHistory] = await Promise.all([
|
||||
listFilingsRecords({ ticker, limit: 40 }),
|
||||
listUserHoldings(session.user.id),
|
||||
listWatchlistItems(session.user.id),
|
||||
getQuote(ticker),
|
||||
getPriceHistory(ticker)
|
||||
]);
|
||||
|
||||
const latestFiling = filings[0] ?? null;
|
||||
const holding = holdings.find((entry) => entry.ticker === ticker) ?? null;
|
||||
const watchlistItem = watchlist.find((entry) => entry.ticker === ticker) ?? null;
|
||||
|
||||
const companyName = latestFiling?.company_name
|
||||
?? watchlistItem?.company_name
|
||||
?? ticker;
|
||||
|
||||
const financials = filings
|
||||
.filter((entry) => entry.metrics)
|
||||
.map((entry) => ({
|
||||
filingDate: entry.filing_date,
|
||||
filingType: entry.filing_type,
|
||||
revenue: entry.metrics?.revenue ?? null,
|
||||
netIncome: entry.metrics?.netIncome ?? null,
|
||||
totalAssets: entry.metrics?.totalAssets ?? null,
|
||||
cash: entry.metrics?.cash ?? null,
|
||||
debt: entry.metrics?.debt ?? null
|
||||
}));
|
||||
|
||||
const aiReports = filings
|
||||
.filter((entry) => entry.analysis?.text || entry.analysis?.legacyInsights)
|
||||
.slice(0, 8)
|
||||
.map((entry) => ({
|
||||
accessionNumber: entry.accession_number,
|
||||
filingDate: entry.filing_date,
|
||||
filingType: entry.filing_type,
|
||||
provider: entry.analysis?.provider ?? 'unknown',
|
||||
model: entry.analysis?.model ?? 'unknown',
|
||||
summary: entry.analysis?.text ?? entry.analysis?.legacyInsights ?? ''
|
||||
}));
|
||||
|
||||
return Response.json({
|
||||
analysis: {
|
||||
company: {
|
||||
ticker,
|
||||
companyName,
|
||||
sector: watchlistItem?.sector ?? null,
|
||||
cik: latestFiling?.cik ?? null
|
||||
},
|
||||
quote: liveQuote,
|
||||
position: holding,
|
||||
priceHistory,
|
||||
financials,
|
||||
filings: filings.slice(0, 20),
|
||||
aiReports
|
||||
}
|
||||
});
|
||||
}, {
|
||||
query: t.Object({
|
||||
ticker: t.String({ minLength: 1 })
|
||||
})
|
||||
})
|
||||
.get('/filings', async ({ query }) => {
|
||||
const { response } = await requireAuthenticatedSession();
|
||||
if (response) {
|
||||
|
||||
Reference in New Issue
Block a user