Implement fiscal-style research MVP flows
Some checks failed
PR Checks / typecheck-and-build (push) Has been cancelled

This commit is contained in:
2026-03-07 09:51:18 -05:00
parent f69e5b671b
commit 52136271d3
26 changed files with 2719 additions and 243 deletions

View File

@@ -27,6 +27,9 @@ type TaxonomyAssetType =
type TaxonomyParseStatus = 'ready' | 'partial' | 'failed';
type TaxonomyMetricValidationStatus = 'not_run' | 'matched' | 'mismatch' | 'error';
type CoverageStatus = 'backlog' | 'active' | 'watch' | 'archive';
type CoveragePriority = 'low' | 'medium' | 'high';
type ResearchJournalEntryType = 'note' | 'filing_note' | 'status_change';
type FilingAnalysis = {
provider?: string;
@@ -269,16 +272,22 @@ export const watchlistItem = sqliteTable('watchlist_item', {
sector: text('sector'),
category: text('category'),
tags: text('tags', { mode: 'json' }).$type<string[]>(),
created_at: text('created_at').notNull()
status: text('status').$type<CoverageStatus>().notNull().default('backlog'),
priority: text('priority').$type<CoveragePriority>().notNull().default('medium'),
created_at: text('created_at').notNull(),
updated_at: text('updated_at').notNull(),
last_reviewed_at: text('last_reviewed_at')
}, (table) => ({
watchlistUserTickerUnique: uniqueIndex('watchlist_user_ticker_uidx').on(table.user_id, table.ticker),
watchlistUserCreatedIndex: index('watchlist_user_created_idx').on(table.user_id, table.created_at)
watchlistUserCreatedIndex: index('watchlist_user_created_idx').on(table.user_id, table.created_at),
watchlistUserUpdatedIndex: index('watchlist_user_updated_idx').on(table.user_id, table.updated_at)
}));
export const holding = sqliteTable('holding', {
id: integer('id').primaryKey({ autoIncrement: true }),
user_id: text('user_id').notNull().references(() => user.id, { onDelete: 'cascade' }),
ticker: text('ticker').notNull(),
company_name: text('company_name'),
shares: numeric('shares').notNull(),
avg_cost: numeric('avg_cost').notNull(),
current_price: numeric('current_price'),
@@ -520,6 +529,22 @@ export const portfolioInsight = sqliteTable('portfolio_insight', {
insightUserCreatedIndex: index('insight_user_created_idx').on(table.user_id, table.created_at)
}));
export const researchJournalEntry = sqliteTable('research_journal_entry', {
id: integer('id').primaryKey({ autoIncrement: true }),
user_id: text('user_id').notNull().references(() => user.id, { onDelete: 'cascade' }),
ticker: text('ticker').notNull(),
accession_number: text('accession_number'),
entry_type: text('entry_type').$type<ResearchJournalEntryType>().notNull(),
title: text('title'),
body_markdown: text('body_markdown').notNull(),
metadata: text('metadata', { mode: 'json' }).$type<Record<string, unknown> | null>(),
created_at: text('created_at').notNull(),
updated_at: text('updated_at').notNull()
}, (table) => ({
researchJournalTickerIndex: index('research_journal_ticker_idx').on(table.user_id, table.ticker, table.created_at),
researchJournalAccessionIndex: index('research_journal_accession_idx').on(table.user_id, table.accession_number)
}));
export const authSchema = {
user,
session,
@@ -543,7 +568,8 @@ export const appSchema = {
filingLink,
taskRun,
taskStageEvent,
portfolioInsight
portfolioInsight,
researchJournalEntry
};
export const schema = {