import { IBooking, EntityType, IEventBus, BookingStatus } from '../../types/CalendarTypes'; import { BookingStore } from './BookingStore'; import { BaseEntityService } from '../../storage/BaseEntityService'; import { IndexedDBContext } from '../../storage/IndexedDBContext'; /** * BookingService - CRUD operations for bookings in IndexedDB */ export class BookingService extends BaseEntityService { readonly storeName = BookingStore.STORE_NAME; readonly entityType: EntityType = 'Booking'; constructor(context: IndexedDBContext, eventBus: IEventBus) { super(context, eventBus); } protected serialize(booking: IBooking): unknown { return { ...booking, createdAt: booking.createdAt.toISOString() }; } protected deserialize(data: unknown): IBooking { const raw = data as Record; return { ...raw, createdAt: new Date(raw.createdAt as string) } as IBooking; } /** * Get bookings for a customer */ async getByCustomer(customerId: 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('customerId'); const request = index.getAll(customerId); request.onsuccess = () => { const data = request.result as unknown[]; const bookings = data.map(item => this.deserialize(item)); resolve(bookings); }; request.onerror = () => { reject(new Error(`Failed to get bookings for customer ${customerId}: ${request.error}`)); }; }); } /** * Get bookings by status */ async getByStatus(status: BookingStatus): Promise { return new Promise((resolve, reject) => { const transaction = this.db.transaction([this.storeName], 'readonly'); const store = transaction.objectStore(this.storeName); const index = store.index('status'); const request = index.getAll(status); request.onsuccess = () => { const data = request.result as unknown[]; const bookings = data.map(item => this.deserialize(item)); resolve(bookings); }; request.onerror = () => { reject(new Error(`Failed to get bookings with status ${status}: ${request.error}`)); }; }); } }