fix prices reloading
Some checks failed
CI and deploy / migration-check (push) Failing after 9s
CI and deploy / deploy (push) Has been skipped

This commit is contained in:
Dusan Vojacek
2026-04-27 18:42:06 +02:00
parent e4d4fee24d
commit 5b94f8baec
3 changed files with 28 additions and 6 deletions

View File

@@ -0,0 +1,8 @@
-- ============================================================
-- Site market config: urychlení lookupu platné konfigurace
-- (vw_site_effective_price, fn_effective_*_price)
-- ============================================================
create index if not exists idx_site_market_config_site_valid_from
on ems.site_market_config (site_id, valid_from desc);

View File

@@ -6,6 +6,11 @@ returns jsonb
language sql
stable
as $fn$
with bounds as (
select
((p_day::timestamp) at time zone 'Europe/Prague') as day_start_utc,
(((p_day + 1)::timestamp) at time zone 'Europe/Prague') as day_end_utc
)
select coalesce(
jsonb_agg(u.j order by u.interval_start),
'[]'::jsonb
@@ -17,8 +22,10 @@ as $fn$
from (
select v.*
from ems.vw_site_effective_price v
cross join bounds b
where v.site_id = p_site_id
and (v.interval_start at time zone 'Europe/Prague')::date = p_day
and v.interval_start >= b.day_start_utc
and v.interval_start < b.day_end_utc
order by v.interval_start
) t
) u;

View File

@@ -3,9 +3,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import {
getCurrentPlan,
getSitePrices,
getForecastPvSlotsRangeCorrected,
type SiteEffectivePriceRowDto,
} from '../api/backend'
import { getJson } from '../api/postgrest'
import {
@@ -22,6 +20,7 @@ import type {
HeatPumpLatestRow,
ModeLogRecentRow,
SiteStatusRow,
SiteEffectivePriceRow,
Telemetry15m7dRow,
} from '../types/ems'
import type { PlanningIntervalDto } from '../types/plan'
@@ -197,7 +196,7 @@ export function useDashboardData(siteId: number | null) {
auditHourly,
modeLog,
hpArr,
...priceLists
priceRows,
] = await Promise.all([
getCurrentPlan(siteId).catch((e: unknown) => {
if (axios.isAxiosError(e) && e.response?.status === 404) {
@@ -221,7 +220,15 @@ export function useDashboardData(siteId: number | null) {
limit: '200',
}),
getJson<HeatPumpLatestRow[]>('/vw_latest_heat_pump', { site_id: `eq.${siteId}` }),
...[...dates].map((d) => getSitePrices(siteId, d)),
// Ceny bereme v jednom range dotazu přes PostgREST view (místo N× /api/v1/sites/{id}/prices?date=...).
// Okno: [windowStart, windowStart + TOTAL_SLOTS) pro mapování na sloty.
getJson<SiteEffectivePriceRow[]>('/vw_site_effective_price', {
site_id: `eq.${siteId}`,
interval_start: `gte.${new Date(windowStart).toISOString()}`,
interval_end: `lt.${new Date(windowStart + TOTAL_SLOTS * SLOT_MS).toISOString()}`,
order: 'interval_start.asc',
limit: String(TOTAL_SLOTS + 32),
}),
])
const status = Array.isArray(statusArr) && statusArr[0] ? statusArr[0]! : null
@@ -235,7 +242,7 @@ export function useDashboardData(siteId: number | null) {
}
const priceBySlot = new Map<string, { buy: number | null; sell: number | null }>()
const flatPrices: SiteEffectivePriceRowDto[] = priceLists.flat() as SiteEffectivePriceRowDto[]
const flatPrices: SiteEffectivePriceRow[] = Array.isArray(priceRows) ? priceRows : []
for (const r of flatPrices) {
const k = slotTimeKey(new Date(r.interval_start).getTime())
priceBySlot.set(k, {