Wire up direct-rates column; remove dormant pause-on-block flow

Direct-rates sub-row in Market View was dead: the frontend filters
competitors on direct_hotel_id but /matrix and /hotels never returned it.
Add direct_hotel_id to both queries (+ HotelResponse), and only render the
"Direct" sub-row when a hotel actually has a non-null direct rate (was
rendering all-dashes on an empty {} object).

Remove the pause-on-block flow entirely — dormant since rotate-on-block
replaced it (nothing set booking_scraper_paused=true after set_scraper_paused
was dropped): is_scraper_paused, /config/unpause, the /scrape paused guard,
ScraperStatusResponse.paused/pause_until, and the frontend Paused badge +
Unpause button. Trim now-unused datetime import.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-06 06:01:56 +00:00
parent 1dc8c0a945
commit 74ae94671b
5 changed files with 15 additions and 103 deletions

View file

@ -32,8 +32,6 @@ interface ScrapeJob {
interface ScraperStatus {
enabled: boolean
paused: boolean
pause_until: string | null
backend: string
location_configured: boolean
location_name: string | null
@ -274,14 +272,6 @@ const StatusPanel: React.FC<{ status: ScraperStatus | undefined, isLoading: bool
{status.enabled ? 'Enabled' : 'Disabled'}
</span>
</div>
{status.paused && (
<div style={styles.statusItem}>
<span style={styles.statusLabel}>Status</span>
<span style={badgeStyle('warning')}>
Paused{status.pause_until ? ` until ${formatDateTime(status.pause_until)}` : ''}
</span>
</div>
)}
<div style={styles.statusItem}>
<span style={styles.statusLabel}>Location</span>
<span style={{ fontSize: '13px', color: status.location_configured ? 'var(--text-dark)' : 'var(--text-mid)' }}>
@ -379,11 +369,6 @@ const SettingsTab: React.FC = () => {
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['scraper-status'] }),
})
const unpauseMutation = useMutation({
mutationFn: async () => (await api.post('/competitors/config/unpause')).data,
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['scraper-status'] }),
})
const scrapeMutation = useMutation({
mutationFn: async () => {
return (await api.post('/competitors/scrape', {
@ -486,14 +471,6 @@ const SettingsTab: React.FC = () => {
>
{status?.enabled ? 'Disable Scraper' : 'Enable Scraper'}
</button>
{status?.paused && (
<button
onClick={() => unpauseMutation.mutate()}
style={buttonStyle('primary')}
>
Unpause Scraper
</button>
)}
</div>
</div>
@ -1419,8 +1396,9 @@ const RateMatrixTab: React.FC = () => {
)
})}
</tr>
{/* Direct rates sub-row */}
{showDirect && hotel.tier === 'competitor' && (directRatesMap?.[hotel.id] != null) && (
{/* Direct rates sub-row — only when this hotel actually has direct rates */}
{showDirect && hotel.tier === 'competitor' &&
Object.values(directRatesMap?.[hotel.id] || {}).some(v => v != null) && (
<tr style={{ background: '#fafbfc' }}>
<td style={{ ...styles.matrixTd, ...styles.stickyCol, paddingLeft: 28, fontSize: 11, color: 'var(--text-mid)', fontStyle: 'italic' }}>
Direct

View file

@ -536,7 +536,6 @@ function SystemTab({ config, isLoading }: { config: SystemConfig | undefined; is
const displayKeys = [
'booking_scraper_enabled',
'booking_scraper_paused',
'booking_scraper_backend',
'booking_scraper_daily_time',
'booking_proxy_enabled',

View file

@ -38,8 +38,6 @@ export interface RateMatrixEntry {
export interface ScraperStatus {
enabled: boolean
paused: boolean
pause_until: string | null
backend: string
daily_time: string
last_batch: {