diff --git a/backend/app/routers/full_status.py b/backend/app/routers/full_status.py index 0bd917b..9c24a50 100644 --- a/backend/app/routers/full_status.py +++ b/backend/app/routers/full_status.py @@ -40,7 +40,10 @@ HEARTBEAT_STALE_SEC = 300 EXPECTED_TOMORROW_PRICE_SLOTS = 90 -def _iso_utc(dt: datetime | None) -> str | None: +def _iso_utc(dt: datetime | str | None) -> str | None: + # JSONB bundle z fn_site_full_status nese timestampy jako stringy — parsovat, + # jinak .tzinfo na str = AttributeError → 500 celého /status/full. + dt = _parse_ts(dt) if dt is None: return None if dt.tzinfo is None: diff --git a/backend/app/routers/plan.py b/backend/app/routers/plan.py index 21ada76..0bc5036 100644 --- a/backend/app/routers/plan.py +++ b/backend/app/routers/plan.py @@ -207,6 +207,7 @@ async def get_plan_compare( raise HTTPException(status_code=404, detail="No comparison plan") active = _bundle_from_current(active_raw) + comparison = _bundle_from_current(compare_raw) diff, slot_diffs = _build_plan_diff(active, comparison) return PlanningCompareResponseModel( active=active, diff --git a/db/routines/R__088_fn_forecast_pv_slots_range_canonical_ab.sql b/db/routines/R__088_fn_forecast_pv_slots_range_canonical_ab.sql index ae5b917..c2379b8 100644 --- a/db/routines/R__088_fn_forecast_pv_slots_range_canonical_ab.sql +++ b/db/routines/R__088_fn_forecast_pv_slots_range_canonical_ab.sql @@ -28,6 +28,9 @@ returns jsonb language sql stable set work_mem = '64MB' +-- PG 18 cachuje plány SQL funkcí → generický plán bez znalosti hodnot parametrů +-- (4.5 s / 607k buffers); s custom planem dle skutečných hodnot 0.4 s / 34k. +set plan_cache_mode = force_custom_plan as $fn$ with tz as ( select coalesce(nullif(trim(s.timezone), ''), 'Europe/Prague') as tz_name