Files
hotelsync/src/types/index.ts
HotelSync 63da3d21cc feat: maintenance/blocked date ranges with booking overlap warning
- DB migration 020: add maintenance_from, maintenance_to to rooms
- Room type + RoomPayload: maintenanceFrom, maintenanceTo fields
- Context menu: clicking "На ремонт"/"Закрыт" expands inline date picker
  (С / По + "Без срока" checkbox), confirms with "Применить" button
- Calendar: stripe overlay covers only the maintenance date range
  (full row if no dates set, partial if date range specified)
- Booking creation: if drag-selected dates overlap with maintenance period,
  shows warning dialog with "Отмена" / "Всё равно забронировать"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 14:49:19 +03:00

231 lines
6.3 KiB
TypeScript

// ─── Auth ────────────────────────────────────────────────────────────────────
export type Role = 'super_admin' | 'hotel_manager' | 'housekeeper'
export interface User {
id: string
email: string
name: string
role: Role
hotelId: string | null
hotelName?: string
hotelSlug?: string
avatarUrl?: string
createdAt?: string
updatedAt?: string
}
export interface AuthSession {
user: User
token: string
}
// ─── Hotel ───────────────────────────────────────────────────────────────────
export type HotelPlan = 'starter' | 'pro' | 'enterprise'
export interface Hotel {
id: string
name: string
slug: string
address?: string
phone?: string
timezone: string
currency: string
checkInTime?: string
checkOutTime?: string
logoUrl?: string
plan: HotelPlan
isActive?: boolean
roomCount?: number
activeBookings?: number
createdAt: string
}
// ─── Room ────────────────────────────────────────────────────────────────────
export type RoomStatus = 'available' | 'occupied' | 'maintenance' | 'blocked'
export type HousekeepingStatus = 'clean' | 'dirty' | 'cleaning' | 'inspect'
export type BedType = 'single' | 'double' | 'queen' | 'king' | 'twin'
export type BedItemType = 'single' | 'double' | 'queen' | 'king' | 'twin' | 'sofa' | 'bunk' | 'cot'
export interface BedItem {
type: string
count: number
}
export interface ExtraPlace {
enabled: boolean
count: number // max extra places available
price: number // price per extra place per night
}
export interface ChildPolicy {
enabled: boolean
freeUnderAge: number // children strictly under this age stay free
chargeFromAge: number // children this age and above pay for extra place
}
export interface RoomCategory {
id: string
hotelId: string
name: string
description: string
photos: string[]
color: string
amenities: string[]
}
export interface Room {
id: string
hotelId: string
number: string
name?: string
floor: number
type: string
bedType: BedType
maxGuests: number
baseRate: number
status: RoomStatus
housekeepingStatus: HousekeepingStatus
amenities: string[]
sortOrder: number
allowHourly?: boolean
hourlyRate?: number
description?: string
photos?: string[]
categoryId?: string
beds?: BedItem[]
extraPlace?: ExtraPlace
childPolicy?: ChildPolicy
earlyCheckinFee?: number
lateCheckoutFee?: number
maintenanceFrom?: string | null // ISO date, null = indefinite start
maintenanceTo?: string | null // ISO date, null = indefinite end
}
export interface DocumentTemplate {
id: string
hotelId: string
name: string
type: 'registration' | 'invoice' | 'contract' | 'info'
content: string
forCheckIn: boolean
printOrder: number
}
// ─── Guest ───────────────────────────────────────────────────────────────────
export interface Guest {
id: string
hotelId: string
firstName: string
lastName: string
email: string
phone?: string
nationality?: string
}
// ─── Booking ─────────────────────────────────────────────────────────────────
export type BookingStatus =
| 'inquiry'
| 'confirmed'
| 'checked_in'
| 'checked_out'
| 'cancelled'
| 'no_show'
export type BookingSource =
| 'direct'
| 'booking_com'
| 'airbnb'
| 'expedia'
| 'other'
export interface Booking {
id: string
hotelId: string
roomId: string
guestId: string
guestName: string
guestEmail: string
guestPhone?: string
checkIn: string // ISO date YYYY-MM-DD
checkOut: string // ISO date YYYY-MM-DD
status: BookingStatus
source: BookingSource
channelBookingId?: string
totalAmount: number
paidAmount: number
adults: number
children: number
notes?: string
createdAt: string
}
export interface DraftBooking {
roomId: string
checkIn: string
checkOut: string
}
// ─── Channel ─────────────────────────────────────────────────────────────────
export type ChannelName = 'booking_com' | 'airbnb' | 'expedia' | 'vrbo' | 'yandex_travel' | 'ostrovok' | 'sutochno' | 'onetwotrip'
export type SyncStatus = 'idle' | 'syncing' | 'success' | 'error'
export interface ChannelMapping {
localRoomId: string
channelRoomId: string
channelRoomName: string
}
export interface Channel {
id: string
hotelId: string
name: ChannelName
displayName: string
isEnabled: boolean
lastSyncAt: string | null
lastSyncStatus: SyncStatus
lastSyncError?: string
bookingsImported: number
mappings: ChannelMapping[]
}
// ─── Housekeeping ─────────────────────────────────────────────────────────────
export interface HousekeepingTask {
id: string
hotelId: string
roomId: string
roomNumber: string
assignedToId?: string
assignedToName?: string
priority: 'low' | 'medium' | 'high' | 'urgent'
status: 'pending' | 'in_progress' | 'done'
notes?: string
maintenanceNote?: string
maintenanceSeverity?: 'low' | 'medium' | 'high'
roomBlocked?: boolean
dueDate: string
completedAt?: string
type: 'cleaning' | 'inspection' | 'maintenance'
}
// ─── API Docs ─────────────────────────────────────────────────────────────────
export interface ApiEndpoint {
method: 'GET' | 'POST' | 'PATCH' | 'DELETE' | 'PUT'
path: string
summary: string
description?: string
tags: string[]
auth: boolean
roles?: Role[]
requestBody?: string
response?: string
}