import { ICustomer } from '../../types/CustomerTypes'; import { CustomerStore } from './CustomerStore'; /** * CustomerService - CRUD operations for customers in IndexedDB * * Handles all customer-related database operations. * Part of modular storage architecture where each entity has its own service. * * Note: No serialization needed - ICustomer has no Date fields. */ export class CustomerService { private db: IDBDatabase; /** * @param db - IDBDatabase instance (injected dependency) */ constructor(db: IDBDatabase) { this.db = db; } /** * Get a single customer by ID * * @param id - Customer ID * @returns ICustomer or null if not found */ async get(id: string): Promise { return new Promise((resolve, reject) => { const transaction = this.db.transaction([CustomerStore.STORE_NAME], 'readonly'); const store = transaction.objectStore(CustomerStore.STORE_NAME); const request = store.get(id); request.onsuccess = () => { resolve(request.result || null); }; request.onerror = () => { reject(new Error(`Failed to get customer ${id}: ${request.error}`)); }; }); } /** * Get all customers * * @returns Array of all customers */ async getAll(): Promise { return new Promise((resolve, reject) => { const transaction = this.db.transaction([CustomerStore.STORE_NAME], 'readonly'); const store = transaction.objectStore(CustomerStore.STORE_NAME); const request = store.getAll(); request.onsuccess = () => { resolve(request.result as ICustomer[]); }; request.onerror = () => { reject(new Error(`Failed to get all customers: ${request.error}`)); }; }); } /** * Save a customer (create or update) * * @param customer - ICustomer to save */ async save(customer: ICustomer): Promise { return new Promise((resolve, reject) => { const transaction = this.db.transaction([CustomerStore.STORE_NAME], 'readwrite'); const store = transaction.objectStore(CustomerStore.STORE_NAME); const request = store.put(customer); request.onsuccess = () => { resolve(); }; request.onerror = () => { reject(new Error(`Failed to save customer ${customer.id}: ${request.error}`)); }; }); } /** * Delete a customer * * @param id - Customer ID to delete */ async delete(id: string): Promise { return new Promise((resolve, reject) => { const transaction = this.db.transaction([CustomerStore.STORE_NAME], 'readwrite'); const store = transaction.objectStore(CustomerStore.STORE_NAME); const request = store.delete(id); request.onsuccess = () => { resolve(); }; request.onerror = () => { reject(new Error(`Failed to delete customer ${id}: ${request.error}`)); }; }); } /** * Get customers by phone number * * @param phone - Phone number * @returns Array of customers with this phone */ async getByPhone(phone: string): Promise { return new Promise((resolve, reject) => { const transaction = this.db.transaction([CustomerStore.STORE_NAME], 'readonly'); const store = transaction.objectStore(CustomerStore.STORE_NAME); const index = store.index('phone'); const request = index.getAll(phone); request.onsuccess = () => { resolve(request.result as ICustomer[]); }; request.onerror = () => { reject(new Error(`Failed to get customers by phone ${phone}: ${request.error}`)); }; }); } /** * Search customers by name (partial match) * * @param searchTerm - Search term (case insensitive) * @returns Array of customers matching search */ async searchByName(searchTerm: string): Promise { const allCustomers = await this.getAll(); const lowerSearch = searchTerm.toLowerCase(); return allCustomers.filter(customer => customer.name.toLowerCase().includes(lowerSearch) ); } }