Od uživatele po 42883 incidentu (R__018 comment na staré signatuře shodil 2 deploye): odkaz přes signaturu se rozbije při každé změně parametrů. R__018 převeden na bez-parametrovou formu, pravidlo v CLAUDE.md Konvencích. Zbylých 51 parametrizovaných comment on / 6 dropů v repu funguje (míří na aktuální signatury) — normalizovat při dotyku. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
110 lines
3.3 KiB
PL/PgSQL
110 lines
3.3 KiB
PL/PgSQL
-- Cache delta profilu PV (těžká agregace forecast_accuracy) — refresh po fn_fill_forecast_accuracy.
|
|
-- Prefix R__018: musí běžet před R__022 (volá fn_refresh_site_pv_delta_profile_cache).
|
|
|
|
drop function if exists ems.fn_refresh_site_pv_delta_profile_cache;
|
|
|
|
create or replace function ems.fn_refresh_site_pv_delta_profile_cache(
|
|
p_site_id int,
|
|
p_force boolean default false
|
|
)
|
|
returns void
|
|
language plpgsql
|
|
as $fn$
|
|
declare
|
|
v_profile jsonb;
|
|
begin
|
|
-- VÝKON: agregace 120 dní nad forecast_accuracy trvá ~44 s/site na prod —
|
|
-- po 15 min ji přepočítávat dusilo celou DB (timeouty API). Profil má 14d
|
|
-- poločas, denní granularitu — čerstvost 6 h bohatě stačí.
|
|
if not p_force and exists (
|
|
select 1 from ems.site_pv_forecast_calibration c
|
|
where c.site_id = p_site_id
|
|
and c.delta_profile_cached_at > now() - interval '6 hours'
|
|
) then
|
|
return;
|
|
end if;
|
|
|
|
v_profile := ems.fn_pv_forecast_delta_profile(
|
|
p_site_id,
|
|
now() - interval '120 days',
|
|
now()
|
|
);
|
|
|
|
update ems.site_pv_forecast_calibration c
|
|
set
|
|
delta_profile_cache = v_profile,
|
|
delta_profile_cached_at = now(),
|
|
updated_at = now()
|
|
where c.site_id = p_site_id;
|
|
|
|
if not found then
|
|
insert into ems.site_pv_forecast_calibration (
|
|
site_id,
|
|
delta_learn_min_ts,
|
|
delta_profile_cache,
|
|
delta_profile_cached_at
|
|
)
|
|
values (
|
|
p_site_id,
|
|
timestamptz '2026-04-11T22:00:00Z',
|
|
v_profile,
|
|
now()
|
|
);
|
|
end if;
|
|
end;
|
|
$fn$;
|
|
|
|
comment on function ems.fn_refresh_site_pv_delta_profile_cache is
|
|
'Přepočte a uloží delta_profile_cache pro site (volá fn_pv_forecast_delta_profile).';
|
|
|
|
create or replace function ems.fn_pv_forecast_delta_profile_cached(
|
|
p_site_id int,
|
|
p_data_from timestamptz default (now() - interval '120 days'),
|
|
p_data_to timestamptz default now(),
|
|
p_half_life_days numeric default 14,
|
|
p_threshold_w int default 150,
|
|
p_top_n_days int default 3,
|
|
p_non_top_day_factor numeric default 0.02,
|
|
p_day_weight_gamma numeric default 1.0,
|
|
p_max_age interval default interval '30 minutes'
|
|
)
|
|
returns jsonb
|
|
language plpgsql
|
|
stable
|
|
as $fn$
|
|
declare
|
|
v_cached jsonb;
|
|
v_cached_at timestamptz;
|
|
begin
|
|
select c.delta_profile_cache, c.delta_profile_cached_at
|
|
into v_cached, v_cached_at
|
|
from ems.site_pv_forecast_calibration c
|
|
where c.site_id = p_site_id;
|
|
|
|
-- ČTENÁŘ NIKDY NEPOČÍTÁ (přepočet = 44 s/site na prod!). Vrací cache bez
|
|
-- ohledu na stáří (přepočet řídí výhradně fn_refresh_… — throttle 6 h
|
|
-- z fill_forecast_accuracy ticku + denní catch-up). p_max_age ponechán
|
|
-- v signatuře kvůli kompatibilitě volajících, ignoruje se.
|
|
if v_cached is not null
|
|
and p_data_from >= (now() - interval '121 days')
|
|
and p_data_to <= now() + interval '5 minutes' then
|
|
return v_cached;
|
|
end if;
|
|
|
|
-- jen first-run (cache NULL) nebo nestandardní analytické okno:
|
|
return ems.fn_pv_forecast_delta_profile(
|
|
p_site_id,
|
|
p_data_from,
|
|
p_data_to,
|
|
p_half_life_days,
|
|
p_threshold_w,
|
|
p_top_n_days,
|
|
p_non_top_day_factor,
|
|
p_day_weight_gamma
|
|
);
|
|
end;
|
|
$fn$;
|
|
|
|
comment on function ems.fn_pv_forecast_delta_profile_cached is
|
|
'Delta profil VŽDY z cache (stáří řídí refresh job, ne čtenář — přepočet 44 s/site); inline přepočet jen first-run / nestandardní okno.';
|