Add Rate Monitor app — Booking.com + direct booking engine competitor rates
Combines Booking.com Playwright scraper (from forecasting), direct booking engine scraper (ported from laptop-archive/guestline-monitor), and Newbook own-hotel rates into one focused tool. Four views: Bookability, Market View (with price index badges + direct rate sub-rows), Direct Rates (per-competitor room breakdown, min-stay flags, hotel config/discovery), Rate Analysis (advance purchase curve, DOW chart, rate timeline, comparison table). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
e05054172f
50 changed files with 11860 additions and 0 deletions
114
frontend/src/types.ts
Normal file
114
frontend/src/types.ts
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
export interface User {
|
||||
email: string
|
||||
name: string
|
||||
is_admin: boolean
|
||||
caps: string[]
|
||||
}
|
||||
|
||||
export function can(user: User | null, cap: string): boolean {
|
||||
if (!user) return false
|
||||
return user.is_admin || user.caps.includes(cap)
|
||||
}
|
||||
|
||||
export interface Hotel {
|
||||
id: number
|
||||
name: string
|
||||
tier: 'own' | 'competitor' | 'market'
|
||||
star_rating: number | null
|
||||
review_score: number | null
|
||||
booking_com_url: string | null
|
||||
booking_com_id: string | null
|
||||
display_order: number
|
||||
notes: string | null
|
||||
is_active: boolean
|
||||
scraped_dates?: number
|
||||
last_scraped?: string | null
|
||||
}
|
||||
|
||||
export interface RateMatrixEntry {
|
||||
hotel_id: number
|
||||
hotel_name: string
|
||||
tier: string
|
||||
rate_date: string
|
||||
rate_gross: number | null
|
||||
availability_status: string
|
||||
rooms_left: number | null
|
||||
scraped_at: string | null
|
||||
}
|
||||
|
||||
export interface ScraperStatus {
|
||||
enabled: boolean
|
||||
paused: boolean
|
||||
pause_until: string | null
|
||||
backend: string
|
||||
daily_time: string
|
||||
last_batch: {
|
||||
batch_id: string
|
||||
started_at: string
|
||||
status: string
|
||||
rates_scraped: number
|
||||
dates_completed: number
|
||||
} | null
|
||||
}
|
||||
|
||||
export interface BookabilityCategory {
|
||||
category_id: string
|
||||
category_name: string
|
||||
room_count: number
|
||||
display_order: number
|
||||
dates: BookabilityDate[]
|
||||
}
|
||||
|
||||
export interface BookabilityDate {
|
||||
date: string
|
||||
gross_rate: number | null
|
||||
tariffs: TariffSummary[]
|
||||
occupancy_pct: number | null
|
||||
available_rooms: number | null
|
||||
is_bookable: boolean
|
||||
}
|
||||
|
||||
export interface TariffSummary {
|
||||
tariff_name: string
|
||||
rate: number | null
|
||||
min_stay: number | null
|
||||
advance_max: number | null
|
||||
is_available: boolean
|
||||
}
|
||||
|
||||
export interface AdvancePurchaseCurvePoint {
|
||||
lead_bucket: string
|
||||
avg_rate: number
|
||||
sample_count: number
|
||||
}
|
||||
|
||||
export interface DowAnalysisPoint {
|
||||
dow: number
|
||||
dow_label: string
|
||||
avg_rate: number
|
||||
date_count: number
|
||||
}
|
||||
|
||||
export interface StrategySummary {
|
||||
advance_discount_pct: number | null
|
||||
weekend_premium_pct: number | null
|
||||
avg_sold_out_rate_pct: number | null
|
||||
strategy_label: string
|
||||
}
|
||||
|
||||
export interface HotelAnalysis {
|
||||
hotel: Hotel
|
||||
date_range: { from: string; to: string }
|
||||
advance_purchase_curve: AdvancePurchaseCurvePoint[]
|
||||
dow_analysis: DowAnalysisPoint[]
|
||||
sold_out_pattern: Array<{ dow: number; dow_label: string; total_dates: number; sold_out_dates: number }>
|
||||
strategy_summary: StrategySummary
|
||||
}
|
||||
|
||||
export interface RateTimelinePoint {
|
||||
scraped_at: string
|
||||
rate_gross: number | null
|
||||
availability_status: string
|
||||
rooms_left: number | null
|
||||
days_out: number
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue