import fs from 'fs/promises'; import path from 'path'; import { v4 as uuidv4 } from 'uuid'; const DATA_DIR = path.join(process.cwd(), 'data'); // Ensure data directory exists const initDataDir = async () => { try { await fs.access(DATA_DIR); } catch { await fs.mkdir(DATA_DIR, { recursive: true }); } }; initDataDir(); export class FileStorageService { private filePath: string; constructor(filename: string) { this.filePath = path.join(DATA_DIR, filename); } private async readFile(): Promise { try { await initDataDir(); const data = await fs.readFile(this.filePath, 'utf-8'); return JSON.parse(data); } catch (error: unknown) { const err = error as { code?: string }; if (err.code === 'ENOENT') { return []; // File doesn't exist yet, return empty array } throw error; } } private async writeFile(data: T[]): Promise { await initDataDir(); await fs.writeFile(this.filePath, JSON.stringify(data, null, 2), 'utf-8'); } async getAll(): Promise { return this.readFile(); } async getById(id: string): Promise { const items = await this.readFile(); return items.find(item => item.id === id) || null; } async create(data: Omit): Promise { const items = await this.readFile(); const newItem = { ...data, id: uuidv4() } as T; items.push(newItem); await this.writeFile(items); return newItem; } async update(id: string, data: Partial): Promise { const items = await this.readFile(); const index = items.findIndex(item => item.id === id); if (index === -1) return null; items[index] = { ...items[index], ...data }; await this.writeFile(items); return items[index]; } async delete(id: string): Promise { const items = await this.readFile(); const filtered = items.filter(item => item.id !== id); if (filtered.length === items.length) return false; await this.writeFile(filtered); return true; } // Helper for filtering by foreign keys (e.g., get parts by projectId) async getByField(field: keyof T, value: T[keyof T]): Promise { const items = await this.readFile(); return items.filter(item => item[field] === value); } }