Add 'last changed' tooltip to bookability date headers

Separate verified_at (last checked) from valid_from (last rate change)
in the matrix response. Column headers show when rates were last checked;
hovering shows both "Checked: X" and "Changed: Y" so users can distinguish
a manual refresh that verified unchanged rates from one that found new prices.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-10 08:44:29 +00:00
parent 418e0d2fcc
commit ed0a027448
2 changed files with 30 additions and 14 deletions

View file

@ -52,14 +52,16 @@ class DateRateInfo(BaseModel):
tariffs: List[TariffInfo]
tariff_count: int
occupancy: Optional[OccupancyInfo] = None
valid_from: Optional[str] = None
valid_from: Optional[str] = None # when rates last CHANGED
verified_at: Optional[str] = None # when rates last CHECKED
class RateMatrixResponse(BaseModel):
categories: List[CategoryInfo]
dates: List[str]
matrix: Dict[str, Dict[str, DateRateInfo]]
date_last_updated: Dict[str, Optional[str]] = {}
date_last_updated: Dict[str, Optional[str]] = {} # max verified_at per date
date_last_changed: Dict[str, Optional[str]] = {} # max valid_from per date
# ============================================
@ -346,26 +348,31 @@ async def get_rate_matrix(
tariffs=tariffs_list,
tariff_count=tariffs_data.get('tariff_count', len(tariffs_list)),
occupancy=existing_occ,
valid_from=lv
valid_from=vf,
verified_at=lv
)
# 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]] = {}
# Per-date header timestamps
date_last_updated: Dict[str, Optional[str]] = {} # last CHECKED (verified_at)
date_last_changed: Dict[str, Optional[str]] = {} # last CHANGED (valid_from)
for date_str in dates:
latest = None
latest_checked = None
latest_changed = None
for cat in categories:
vf = matrix.get(cat.category_id, {}).get(date_str, DateRateInfo(tariffs=[], tariff_count=0)).valid_from
if vf and (latest is None or vf > latest):
latest = vf
date_last_updated[date_str] = latest
entry = matrix.get(cat.category_id, {}).get(date_str, DateRateInfo(tariffs=[], tariff_count=0))
if entry.verified_at and (latest_checked is None or entry.verified_at > latest_checked):
latest_checked = entry.verified_at
if entry.valid_from and (latest_changed is None or entry.valid_from > latest_changed):
latest_changed = entry.valid_from
date_last_updated[date_str] = latest_checked
date_last_changed[date_str] = latest_changed
return RateMatrixResponse(
categories=categories,
dates=dates,
matrix=matrix,
date_last_updated=date_last_updated
date_last_updated=date_last_updated,
date_last_changed=date_last_changed
)