237 lines
5.6 KiB
TypeScript
237 lines
5.6 KiB
TypeScript
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<CourtSummary[]>
|
|
getAvailability(query: AvailabilityQuery): Promise<AvailabilityDay>
|
|
getCourtSettings(courtId: string): Promise<CourtSettings>
|
|
updateCourtSettings(input: UpdateCourtSettingsInput): Promise<CourtSettings>
|
|
createBooking(input: CreateBookingInput): Promise<PendingBooking>
|
|
cancelBooking(input: CancelBookingInput): Promise<void>
|
|
getPendingBooking(courtId: string): Promise<PendingBooking | null>
|
|
listMonitorTasks(): Promise<MonitorTask[]>
|
|
getMonitorTaskDetail(taskId: string): Promise<MonitorTaskDetail>
|
|
createMonitorTask(input: CreateMonitorTaskInput): Promise<MonitorTask>
|
|
setMonitorTaskEnabled(taskId: string, enabled: boolean): Promise<MonitorTask>
|
|
setMonitorTaskAutoBooking(taskId: string, enabled: boolean): Promise<MonitorTask>
|
|
deleteMonitorTask(taskId: string): Promise<void>
|
|
takeMonitorAlerts(): Promise<MonitorAlert[]>
|
|
listUnreadMonitorAlerts(): Promise<MonitorAlert[]>
|
|
acknowledgeMonitorAlerts(taskId?: string): Promise<void>
|
|
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
|