-- CL8: instance health monitoring fields + lock helpers alter table public.plesk_instances add column if not exists health_enabled boolean not null default true, add column if not exists health_status text not null default 'unknown', add column if not exists health_last_checked_at timestamptz, add column if not exists health_last_ok_at timestamptz, add column if not exists health_last_error text, add column if not exists health_last_latency_ms integer, add column if not exists health_check_frequency_minutes integer not null default 30, add column if not exists health_next_check_at timestamptz, add column if not exists health_lock_until timestamptz, add column if not exists health_lock_token text; alter table public.plesk_instances drop constraint if exists plesk_instances_health_status_check; alter table public.plesk_instances add constraint plesk_instances_health_status_check check (health_status in ('ok', 'degraded', 'down', 'unknown')); alter table public.plesk_instances drop constraint if exists plesk_instances_health_check_frequency_minutes_check; alter table public.plesk_instances add constraint plesk_instances_health_check_frequency_minutes_check check (health_check_frequency_minutes between 5 and 10080); create index if not exists idx_plesk_instances_health_due on public.plesk_instances (health_enabled, health_next_check_at); create or replace function public.acquire_instance_health_lock( p_instance_id uuid, p_lock_token text, p_ttl_seconds integer default 300, p_force boolean default false ) returns boolean language plpgsql security definer set search_path = public as $$ declare v_acquired boolean := false; begin update public.plesk_instances set health_lock_until = now() + make_interval(secs => p_ttl_seconds), health_lock_token = p_lock_token where id = p_instance_id and health_enabled = true and ( p_force = true or health_next_check_at is null or health_next_check_at <= now() ) and (health_lock_until is null or health_lock_until < now()); get diagnostics v_acquired = row_count; return v_acquired; end; $$; create or replace function public.release_instance_health_lock( p_instance_id uuid, p_lock_token text ) returns void language sql security definer set search_path = public as $$ update public.plesk_instances set health_lock_until = null, health_lock_token = null where id = p_instance_id and health_lock_token = p_lock_token; $$;