Files
market_screener/server/repositories/MarketCallRepository.ts
T
2026-06-06 22:55:43 -04:00

87 lines
2.2 KiB
TypeScript

import { randomUUID } from 'crypto';
import type { Db } from '../db/index';
import type { MarketCall, CreateCallInput } from '../types';
interface CallRow {
id: string;
title: string;
quarter: string;
date: string;
thesis: string;
tickers: string; // JSON
snapshot: string; // JSON
created_at: string;
}
export class MarketCallRepository {
constructor(private readonly db: Db) {}
list(): (MarketCall & { createdAt: string })[] {
const rows = this.db
.prepare('SELECT * FROM market_calls ORDER BY created_at DESC')
.all() as CallRow[];
return rows.map(MarketCallRepository.toCall);
}
get(id: string): (MarketCall & { createdAt: string }) | null {
const row = this.db.prepare('SELECT * FROM market_calls WHERE id = ?').get(id) as
| CallRow
| undefined;
return row ? MarketCallRepository.toCall(row) : null;
}
create({
title,
quarter,
date,
thesis,
tickers,
snapshot,
}: CreateCallInput): MarketCall & { createdAt: string } {
const call = {
id: randomUUID(),
title,
quarter,
date: date ?? new Date().toISOString().slice(0, 10),
thesis,
tickers: tickers ?? [],
snapshot: snapshot ?? {},
createdAt: new Date().toISOString(),
};
this.db
.prepare(
`INSERT INTO market_calls (id, title, quarter, date, thesis, tickers, snapshot, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
)
.run(
call.id,
call.title,
call.quarter,
call.date,
call.thesis,
JSON.stringify(call.tickers),
JSON.stringify(call.snapshot),
call.createdAt,
);
return call as MarketCall & { createdAt: string };
}
delete(id: string): boolean {
const result = this.db.prepare('DELETE FROM market_calls WHERE id = ?').run(id);
return result.changes > 0;
}
private static toCall(row: CallRow): MarketCall & { createdAt: string } {
return {
id: row.id,
title: row.title,
quarter: row.quarter,
date: row.date,
thesis: row.thesis,
tickers: JSON.parse(row.tickers),
snapshot: JSON.parse(row.snapshot),
createdAt: row.created_at,
} as MarketCall & { createdAt: string };
}
}