Fix bookability column timestamps showing stale 'last changed' dates

Switch date_last_updated from valid_from (rate change time) to
last_verified_at (last check time). All dates verified in the same daily
run now show a consistent timestamp rather than varying by when rates
last changed. Also commit per-date instead of batching 10 days — prevents
a single API error from rolling back up to 9 preceding committed dates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-10 08:41:58 +00:00
parent 218589afbe
commit d72f14ae49
3 changed files with 22 additions and 4 deletions

View file

@ -242,7 +242,7 @@ async def get_rate_matrix(
# Fetch rates with tariffs_data (get latest version per category/date) # Fetch rates with tariffs_data (get latest version per category/date)
rates_query = """ rates_query = """
SELECT DISTINCT ON (category_id, rate_date) SELECT DISTINCT ON (category_id, rate_date)
category_id, rate_date, rate_gross, rate_net, tariffs_data, valid_from category_id, rate_date, rate_gross, rate_net, tariffs_data, valid_from, last_verified_at
FROM newbook_current_rates FROM newbook_current_rates
WHERE rate_date >= :from_date AND rate_date <= :to_date WHERE rate_date >= :from_date AND rate_date <= :to_date
""" """
@ -338,6 +338,7 @@ async def get_rate_matrix(
# Preserve existing occupancy data # Preserve existing occupancy data
existing_occ = matrix[cat_id][rate_date].occupancy existing_occ = matrix[cat_id][rate_date].occupancy
vf = row.valid_from.isoformat() if row.valid_from else None vf = row.valid_from.isoformat() if row.valid_from else None
lv = row.last_verified_at.isoformat() if row.last_verified_at else vf
matrix[cat_id][rate_date] = DateRateInfo( matrix[cat_id][rate_date] = DateRateInfo(
rate_gross=float(row.rate_gross) if row.rate_gross else None, rate_gross=float(row.rate_gross) if row.rate_gross else None,
@ -345,10 +346,12 @@ async def get_rate_matrix(
tariffs=tariffs_list, tariffs=tariffs_list,
tariff_count=tariffs_data.get('tariff_count', len(tariffs_list)), tariff_count=tariffs_data.get('tariff_count', len(tariffs_list)),
occupancy=existing_occ, occupancy=existing_occ,
valid_from=vf valid_from=lv
) )
# Per-date latest update time (max valid_from across all categories for each date) # Per-date latest check time (max last_verified_at across all categories for each date)
# Use last_verified_at so the header reflects when data was last CHECKED, not when rates last changed.
# This makes all dates verified in the same daily run show a consistent timestamp.
date_last_updated: Dict[str, Optional[str]] = {} date_last_updated: Dict[str, Optional[str]] = {}
for date_str in dates: for date_str in dates:
latest = None latest = None

View file

@ -26,7 +26,7 @@ from database import SyncSessionLocal
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
COMMIT_BATCH_SIZE = 10 # Commit to DB every N days COMMIT_BATCH_SIZE = 1 # Commit after every date — prevents rollback from wiping sibling days on API error
def rates_changed(old_rate: Optional[Dict], new_rate: Dict) -> bool: def rates_changed(old_rate: Optional[Dict], new_rate: Dict) -> bool:

View file

@ -361,3 +361,18 @@ tr:hover td { background: #f8fafc; }
padding: 16px; padding: 16px;
} }
} }
/* Sidebar scrollbar */
.nav-scroll::-webkit-scrollbar,
.sidebar::-webkit-scrollbar,
.sidebar-nav::-webkit-scrollbar { width: 4px; }
.nav-scroll::-webkit-scrollbar-track,
.sidebar::-webkit-scrollbar-track,
.sidebar-nav::-webkit-scrollbar-track { background: transparent; }
.nav-scroll::-webkit-scrollbar-thumb,
.sidebar::-webkit-scrollbar-thumb,
.sidebar-nav::-webkit-scrollbar-thumb { background: rgba(201,168,76,0.35); border-radius: 2px; }
.nav-scroll::-webkit-scrollbar-thumb:hover,
.sidebar::-webkit-scrollbar-thumb:hover,
.sidebar-nav::-webkit-scrollbar-thumb:hover { background: rgba(201,168,76,0.65); }
.nav-scroll, .sidebar, .sidebar-nav { scrollbar-width: thin; scrollbar-color: rgba(201,168,76,0.35) transparent; }