- 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>
231 lines
6.3 KiB
TypeScript
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
|
|
}
|