-- Auto-expire beacons 12 hours after the most recent vouch create or replace function update_beacon_expires_at(p_beacon_id uuid) returns void language plpgsql security definer as $$ declare last_vouch_at timestamptz; begin select max(created_at) into last_vouch_at from beacon_votes where beacon_id = p_beacon_id and vote_type = 'vouch'; update posts set expires_at = case when last_vouch_at is null then null else last_vouch_at + interval '12 hours' end where id = p_beacon_id and is_beacon = true; end; $$; create or replace function handle_beacon_vote_ttl() returns trigger language plpgsql security definer as $$ declare target_beacon_id uuid; begin target_beacon_id := coalesce(new.beacon_id, old.beacon_id); if target_beacon_id is not null then perform update_beacon_expires_at(target_beacon_id); end if; return null; end; $$; drop trigger if exists beacon_vote_ttl_trigger on beacon_votes; create trigger beacon_vote_ttl_trigger after insert or update or delete on beacon_votes for each row execute function handle_beacon_vote_ttl(); -- Backfill existing beacons with vouches update posts p set expires_at = v.last_vouch_at + interval '12 hours' from ( select beacon_id, max(created_at) as last_vouch_at from beacon_votes where vote_type = 'vouch' group by beacon_id ) v where p.id = v.beacon_id and p.is_beacon = true;