export type CourtStatus = 'online' | 'maintenance' | 'login-required' export interface CourtSummary { id: string name: string shortName: string district?: string address?: string distanceKm?: number surface?: string indoor?: boolean accent: string status: CourtStatus } export type SlotStatus = 'available' | 'limited' | 'booked' | 'blocked' export interface BookingContact { name?: string phone?: string } export interface EnrollmentActivity { id: string title: string startTime: string endTime: string feeCents: number enrolledCount: number capacity: number participantNames: string[] enrollmentDeadline?: string } export interface BookingSlot { id: string courtLabel: string startTime: string endTime: string priceCents: number status: SlotStatus unavailableLabel?: string bookedBy?: BookingContact[] enrollment?: EnrollmentActivity providerReference?: { classroomUid: string beginDatetime: string endDatetime: string } sourceLabel?: string } export interface AvailabilityDay { courtId: string date: string updatedAt: string slots: BookingSlot[] } export interface AvailabilityQuery { courtId: string date: string } export interface CourtSettings { courtId: string visitorId?: string visitorIdConfigured: boolean } export interface UpdateCourtSettingsInput { courtId: string visitorId?: string } export interface CreateBookingInput { courtId: string date: string slotId?: string slotIds?: string[] expectedPriceCents: number expectedStartTime?: string expectedEndTime?: string } export interface CancelBookingInput { courtId: string orderId: string } export interface PendingBooking { courtId: string orderId: string venueAppointmentIds: string[] amountCents: number courtLabel: string startTime: string endTime: string expiresAt?: string status: | 'submitting-uncertain' | 'pending-payment' | 'release-uncertain' | 'release-confirmed' } export interface MonitorTask { id: string courtId: string targetDate?: string startTime: string endTime: string enabled: boolean createdAt: string lastCheckedAt?: string lastError?: string availableCount: number stats: MonitorTaskStats autoBooking: MonitorAutoBookingState } export type MonitorAutoBookingStatus = | 'disabled' | 'armed' | 'attempting' | 'pending-payment' | 'blocked' | 'stopped' export interface MonitorAutoBookingState { enabled: boolean status: MonitorAutoBookingStatus attemptCount: number lastAttemptAt?: string lastError?: string orderId?: string bookedAt?: string bookedDate?: string bookedSlotLabel?: string } export interface MonitorTaskStats { totalChecks: number successfulChecks: number partialFailureChecks: number failedChecks: number alertsSent: number availableObservations: number lastAlertAt?: string } export interface MonitorDailyStats { date: string checks: number failedChecks: number alerts: number availableObservations: number maxAvailable: number } export interface MonitorTaskLog { id: string occurredAt: string type: 'check' | 'alert' | 'error' | 'lifecycle' | 'booking' level: 'info' | 'warning' | 'success' message: string availableCount?: number checkedDateCount?: number failedDates?: string[] } export interface MonitorTaskDetail { task: MonitorTask dailyStats: MonitorDailyStats[] logs: MonitorTaskLog[] } export interface CreateMonitorTaskInput { courtId: string targetDate?: string startTime: string endTime: string autoBookingEnabled?: boolean } export interface MonitorAlert { taskId: string courtId: string targetDate: string startTime: string endTime: string slotLabels: string[] occurredAt: string } export interface TennisBookApi { listCourts(): Promise getAvailability(query: AvailabilityQuery): Promise getCourtSettings(courtId: string): Promise updateCourtSettings(input: UpdateCourtSettingsInput): Promise createBooking(input: CreateBookingInput): Promise cancelBooking(input: CancelBookingInput): Promise getPendingBooking(courtId: string): Promise listMonitorTasks(): Promise getMonitorTaskDetail(taskId: string): Promise createMonitorTask(input: CreateMonitorTaskInput): Promise setMonitorTaskEnabled(taskId: string, enabled: boolean): Promise setMonitorTaskAutoBooking(taskId: string, enabled: boolean): Promise deleteMonitorTask(taskId: string): Promise takeMonitorAlerts(): Promise listUnreadMonitorAlerts(): Promise acknowledgeMonitorAlerts(taskId?: string): Promise onMonitorAlert(listener: () => void): () => void onShowMonitorTask(listener: (taskId: string) => void): () => void } export const IPC_CHANNELS = { listCourts: 'courts:list', getAvailability: 'courts:availability', getCourtSettings: 'court-settings:get', updateCourtSettings: 'court-settings:update', createBooking: 'bookings:create', cancelBooking: 'bookings:cancel', getPendingBooking: 'bookings:pending', listMonitorTasks: 'monitors:list', getMonitorTaskDetail: 'monitors:detail', createMonitorTask: 'monitors:create', setMonitorTaskEnabled: 'monitors:set-enabled', setMonitorTaskAutoBooking: 'monitors:set-auto-booking', deleteMonitorTask: 'monitors:delete', takeMonitorAlerts: 'monitors:take-alerts', listUnreadMonitorAlerts: 'monitors:list-unread-alerts', acknowledgeMonitorAlerts: 'monitors:acknowledge-alerts', monitorAlert: 'monitors:alert', showMonitorTask: 'monitors:show-task' } as const