40 lines
1.3 KiB
TypeScript
40 lines
1.3 KiB
TypeScript
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
import type { PortfolioData, PortfolioHolding } from '../types';
|
|
|
|
export class PortfolioRepository {
|
|
private static readonly PORTFOLIO_PATH = './portfolio.json';
|
|
|
|
exists(): boolean {
|
|
return existsSync(PortfolioRepository.PORTFOLIO_PATH);
|
|
}
|
|
|
|
read(): PortfolioData {
|
|
if (!this.exists()) return { holdings: [] };
|
|
return JSON.parse(readFileSync(PortfolioRepository.PORTFOLIO_PATH, 'utf8')) as PortfolioData;
|
|
}
|
|
|
|
write(data: PortfolioData): void {
|
|
writeFileSync(PortfolioRepository.PORTFOLIO_PATH, JSON.stringify(data, null, 2), 'utf8');
|
|
}
|
|
|
|
upsert(entry: PortfolioHolding): PortfolioHolding {
|
|
const data = this.read();
|
|
const normalized = entry.ticker.toUpperCase().trim();
|
|
const idx = data.holdings.findIndex((h) => h.ticker.toUpperCase() === normalized);
|
|
const record: PortfolioHolding = { ...entry, ticker: normalized };
|
|
if (idx >= 0) data.holdings[idx] = record;
|
|
else data.holdings.push(record);
|
|
this.write(data);
|
|
return record;
|
|
}
|
|
|
|
remove(ticker: string): boolean {
|
|
const data = this.read();
|
|
const before = data.holdings.length;
|
|
data.holdings = data.holdings.filter((h) => h.ticker.toUpperCase() !== ticker.toUpperCase());
|
|
if (data.holdings.length === before) return false;
|
|
this.write(data);
|
|
return true;
|
|
}
|
|
}
|