import { ICustomer } from '../../types/CustomerTypes'; import { EntityType } from '../../types/CalendarTypes'; import { CustomerStore } from './CustomerStore'; import { BaseEntityService } from '../BaseEntityService'; /** * CustomerService - CRUD operations for customers in IndexedDB * * ARCHITECTURE: * - Extends BaseEntityService for shared CRUD and sync logic * - No serialization needed (ICustomer has no Date fields) * - Provides customer-specific query methods (by phone, search by name) * * INHERITED METHODS (from BaseEntityService): * - get(id), getAll(), save(entity), delete(id) * - markAsSynced(id), markAsError(id), getSyncStatus(id), getBySyncStatus(status) * * CUSTOMER-SPECIFIC METHODS: * - getByPhone(phone) * - searchByName(searchTerm) */ export class CustomerService extends BaseEntityService { readonly storeName = CustomerStore.STORE_NAME; readonly entityType: EntityType = 'Customer'; // No serialization override needed - ICustomer has no Date fields /** * 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([this.storeName], 'readonly'); const store = transaction.objectStore(this.storeName); 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) ); } }