70 lines
1.8 KiB
TypeScript
70 lines
1.8 KiB
TypeScript
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
import { randomUUID } from 'crypto';
|
|
import type { MarketCall, CreateCallInput, StoreData } from '../types';
|
|
|
|
export class MarketCallRepository {
|
|
private static readonly DEFAULT_PATH = './market-calls.json';
|
|
|
|
private readonly storePath: string;
|
|
|
|
constructor(storePath?: string) {
|
|
this.storePath = storePath ?? MarketCallRepository.DEFAULT_PATH;
|
|
}
|
|
|
|
private load(): StoreData {
|
|
if (!existsSync(this.storePath)) return { calls: [] };
|
|
try {
|
|
return JSON.parse(readFileSync(this.storePath, 'utf8')) as StoreData;
|
|
} catch {
|
|
return { calls: [] };
|
|
}
|
|
}
|
|
|
|
private save(data: StoreData): void {
|
|
writeFileSync(this.storePath, JSON.stringify(data, null, 2), 'utf8');
|
|
}
|
|
|
|
list(): (MarketCall & { createdAt: string })[] {
|
|
return this.load().calls.sort(
|
|
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
|
|
);
|
|
}
|
|
|
|
get(id: string): (MarketCall & { createdAt: string }) | null {
|
|
return this.load().calls.find((c) => c.id === id) ?? null;
|
|
}
|
|
|
|
create({
|
|
title,
|
|
quarter,
|
|
date,
|
|
thesis,
|
|
tickers,
|
|
snapshot,
|
|
}: CreateCallInput): MarketCall & { createdAt: string } {
|
|
const data = this.load();
|
|
const call = {
|
|
id: randomUUID(),
|
|
title,
|
|
quarter,
|
|
date: date ?? new Date().toISOString().slice(0, 10),
|
|
thesis,
|
|
tickers,
|
|
snapshot: snapshot ?? {},
|
|
createdAt: new Date().toISOString(),
|
|
};
|
|
data.calls.push(call);
|
|
this.save(data);
|
|
return call;
|
|
}
|
|
|
|
delete(id: string): boolean {
|
|
const data = this.load();
|
|
const before = data.calls.length;
|
|
data.calls = data.calls.filter((c) => c.id !== id);
|
|
if (data.calls.length === before) return false;
|
|
this.save(data);
|
|
return true;
|
|
}
|
|
}
|