Merge branch 't3code/expand-research-management-plan'

# 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
This commit is contained in:
2026-03-07 20:39:49 -05:00
38 changed files with 5533 additions and 427 deletions

View File

@@ -14,7 +14,7 @@ import { Input } from '@/components/ui/input';
import { useAuthGuard } from '@/hooks/use-auth-guard';
import { useLinkPrefetch } from '@/hooks/use-link-prefetch';
import {
createResearchJournalEntry,
createResearchArtifact,
queueFilingAnalysis,
queueFilingSync
} from '@/lib/api';
@@ -202,27 +202,39 @@ function FilingsPageContent() {
}
};
const addToJournal = async (filing: Filing) => {
const saveToLibrary = async (filing: Filing) => {
try {
await createResearchJournalEntry({
await createResearchArtifact({
ticker: filing.ticker,
kind: 'filing',
source: 'system',
subtype: 'filing_snapshot',
accessionNumber: filing.accession_number,
entryType: 'filing_note',
title: `${filing.filing_type} filing note`,
title: `${filing.filing_type} filing snapshot`,
summary: filing.analysis?.text ?? filing.analysis?.legacyInsights ?? `Captured filing ${filing.accession_number}.`,
bodyMarkdown: [
`Captured filing note for ${filing.company_name} (${filing.ticker}).`,
`Filed: ${formatFilingDate(filing.filing_date)}`,
`Accession: ${filing.accession_number}`,
'',
filing.analysis?.text ?? filing.analysis?.legacyInsights ?? 'Follow up on this filing from the stream.'
].join('\n')
].join('\n'),
metadata: {
filingType: filing.filing_type,
filingDate: filing.filing_date,
filingUrl: filing.filing_url,
submissionUrl: filing.submission_url ?? null,
primaryDocument: filing.primary_document ?? null
}
});
void queryClient.invalidateQueries({ queryKey: queryKeys.researchWorkspace(filing.ticker) });
void queryClient.invalidateQueries({ queryKey: queryKeys.researchPacket(filing.ticker) });
void queryClient.invalidateQueries({ queryKey: queryKeys.researchJournal(filing.ticker) });
void queryClient.invalidateQueries({ queryKey: queryKeys.companyAnalysis(filing.ticker) });
void queryClient.invalidateQueries({ queryKey: queryKeys.watchlist() });
setActionNotice(`Saved ${filing.accession_number} to the ${filing.ticker} journal.`);
setActionNotice(`Saved ${filing.accession_number} to the ${filing.ticker} research library.`);
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to add filing to journal');
setError(err instanceof Error ? err.message : 'Failed to save filing to library');
}
};
@@ -420,11 +432,11 @@ function FilingsPageContent() {
</Button>
<Button
variant="ghost"
onClick={() => void addToJournal(filing)}
onClick={() => void saveToLibrary(filing)}
className="px-2 py-1 text-xs"
>
<NotebookPen className="size-3" />
Add to journal
Save to library
</Button>
{hasAnalysis ? (
<Link
@@ -498,7 +510,7 @@ function FilingsPageContent() {
</Button>
<Button
variant="ghost"
onClick={() => void addToJournal(filing)}
onClick={() => void saveToLibrary(filing)}
className="px-2 py-1 text-xs"
>
<NotebookPen className="size-3" />