import { readFileSync, writeFileSync, existsSync } from 'fs'; import { randomUUID } from 'crypto'; const STORE_PATH = './market-calls.json'; // MarketCallStore — persists quarterly market thesis entries to market-calls.json. // // A market call captures: // - A written thesis (the reasoning behind the call) // - Tickers to watch // - A snapshot of each ticker's price + signal at the time of the call // - Performance tracking (current vs snapshot price) computed on read // // Format: // { // "calls": [ // { // "id": "uuid", // "title": "Q3 2025 — Rate pivot & tech rotation", // "quarter": "Q3 2025", // "date": "2025-07-01", // "thesis": "The Fed is expected to begin cutting...", // "tickers": ["AAPL", "MSFT", "TLT"], // "snapshot": { // "AAPL": { "price": 195.00, "signal": "✅ Strong Buy", "verdict": "BUY (High Conviction)" } // }, // "createdAt": "2025-07-01T14:22:00.000Z" // } // ] // } export class MarketCallStore { _load() { if (!existsSync(STORE_PATH)) return { calls: [] }; try { return JSON.parse(readFileSync(STORE_PATH, 'utf8')); } catch { return { calls: [] }; } } _save(data) { writeFileSync(STORE_PATH, JSON.stringify(data, null, 2), 'utf8'); } list() { return this._load().calls.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)); } get(id) { return this._load().calls.find((c) => c.id === id) ?? null; } // Create a new call. snapshot is an object keyed by ticker with { price, signal, verdict }. create({ title, quarter, date, thesis, tickers, snapshot }) { 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) { 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; } }