Ctrl K
ComunidadGuías…

migrations/040_one_hold_vocabulary.sql

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
CREATE OR REPLACE FUNCTION hold_vocabulary_json(document text) RETURNS jsonb
LANGUAGE plpgsql IMMUTABLE AS $$
BEGIN
  RETURN document::jsonb;
EXCEPTION WHEN others THEN
  RETURN NULL;
END
$$;

WITH offered AS (
  SELECT task_event_id, task_run_id, created_at, hold_vocabulary_json(body) AS record
  FROM task_event
  WHERE name = 'approval.choices_offered'
),
offered_hold AS (
  SELECT offered.record -> 'choices' AS choices, hold.task_event_id AS hold_event_id
  FROM offered
  JOIN LATERAL (
    SELECT hold_event.task_event_id, hold_vocabulary_json(hold_event.body) AS record
    FROM task_event hold_event
    WHERE hold_event.task_run_id = offered.task_run_id
      AND hold_event.name IN ('approval.pending_call', 'approval.hold_opened')
      AND (hold_event.created_at, hold_event.task_event_id) < (offered.created_at, offered.task_event_id)
    ORDER BY hold_event.created_at DESC, hold_event.task_event_id DESC
    LIMIT 1
  ) hold ON true
  WHERE offered.record ? 'choices'
    AND btrim(coalesce(hold.record ->> 'toolName', '')) = btrim(coalesce(offered.record ->> 'toolName', ''))
    AND coalesce(hold.record -> 'toolInput', '{}'::jsonb) = coalesce(offered.record -> 'toolInput', '{}'::jsonb)
)
UPDATE task_event
SET body = (hold_vocabulary_json(task_event.body) || jsonb_build_object('choices', offered_hold.choices))::text
FROM offered_hold
WHERE task_event.task_event_id = offered_hold.hold_event_id;

DELETE FROM task_event WHERE name = 'approval.choices_offered';

UPDATE task_event
SET name = 'approval.hold_opened'
WHERE name = 'approval.held_call'
  AND EXISTS (
    SELECT 1
    FROM task_run
    WHERE task_run.task_run_id = task_event.task_run_id
      AND task_run.status = 'waiting_approval'
  )
  AND NOT EXISTS (
    SELECT 1
    FROM task_event other_hold
    WHERE other_hold.task_run_id = task_event.task_run_id
      AND other_hold.name IN ('approval.pending_call', 'approval.hold_opened')
  );

DELETE FROM task_event WHERE name = 'approval.held_call';

UPDATE task_event SET name = 'approval.hold_opened' WHERE name = 'approval.pending_call';
UPDATE task_event SET name = 'approval.hold_spent' WHERE name = 'approval.executed';

UPDATE task_event
SET body = (
  (hold_vocabulary_json(body) - 'approvalToken')
  || jsonb_build_object('holdID', coalesce(
    nullif(hold_vocabulary_json(body) ->> 'holdID', ''),
    nullif(hold_vocabulary_json(body) ->> 'approvalToken', ''),
    task_event_id
  ))
)::text
WHERE name = 'approval.hold_opened'
  AND hold_vocabulary_json(body) IS NOT NULL
  AND (
    hold_vocabulary_json(body) ? 'approvalToken'
    OR coalesce(hold_vocabulary_json(body) ->> 'holdID', '') = ''
  );

UPDATE task_event
SET body = (
  (hold_vocabulary_json(body) - 'approvalToken')
  || jsonb_build_object('holdID', coalesce(
    nullif(hold_vocabulary_json(body) ->> 'holdID', ''),
    hold_vocabulary_json(body) ->> 'approvalToken',
    ''
  ))
)::text
WHERE name IN ('approval.decided', 'approval.hold_spent')
  AND hold_vocabulary_json(body) ? 'approvalToken';

UPDATE task_event
SET body = jsonb_set(
  hold_vocabulary_json(body),
  '{decision}',
  to_jsonb(CASE hold_vocabulary_json(body) ->> 'decision'
    WHEN 'cancel' THEN 'reject'
    ELSE 'approve'
  END)
)::text
WHERE name = 'approval.decided'
  AND hold_vocabulary_json(body) ->> 'decision' IN ('confirm', 'confirm_task', 'cancel');

UPDATE task_event
SET body = (
  (hold_vocabulary_json(body) - 'presentedToken' - 'awaitingHeldCallIDs')
  || jsonb_build_object('presentedHoldID', coalesce(hold_vocabulary_json(body) -> 'presentedToken', to_jsonb(''::text)))
)::text
WHERE name = 'approval.unheld_call_carried_out'
  AND (
    hold_vocabulary_json(body) ? 'presentedToken'
    OR hold_vocabulary_json(body) ? 'awaitingHeldCallIDs'
  );

DO $$
DECLARE
  legacy record;
  paired_hold_id text;
BEGIN
  FOR legacy IN
    SELECT task_event_id, task_run_id, name, created_at, hold_vocabulary_json(body) AS record
    FROM task_event
    WHERE name IN ('approval.decided', 'approval.hold_spent')
      AND hold_vocabulary_json(body) IS NOT NULL
      AND coalesce(hold_vocabulary_json(body) ->> 'holdID', '') = ''
    ORDER BY created_at, task_event_id
  LOOP
    paired_hold_id := NULL;
    IF legacy.name = 'approval.decided' THEN
      SELECT hold.record ->> 'holdID' INTO paired_hold_id
      FROM (
        SELECT task_event_id, created_at, hold_vocabulary_json(body) AS record
        FROM task_event
        WHERE name = 'approval.hold_opened'
          AND task_run_id = legacy.task_run_id
          AND (created_at, task_event_id) < (legacy.created_at, legacy.task_event_id)
      ) hold
      WHERE NOT EXISTS (
        SELECT 1
        FROM task_event earlier
        WHERE earlier.name = 'approval.decided'
          AND earlier.task_run_id = legacy.task_run_id
          AND (earlier.created_at, earlier.task_event_id) < (legacy.created_at, legacy.task_event_id)
          AND hold_vocabulary_json(earlier.body) ->> 'holdID' = hold.record ->> 'holdID'
      )
      ORDER BY hold.created_at DESC, hold.task_event_id DESC
      LIMIT 1;
    ELSE
      SELECT hold.record ->> 'holdID' INTO paired_hold_id
      FROM (
        SELECT task_event_id, created_at, hold_vocabulary_json(body) AS record
        FROM task_event
        WHERE name = 'approval.hold_opened'
          AND task_run_id = legacy.task_run_id
          AND (created_at, task_event_id) < (legacy.created_at, legacy.task_event_id)
      ) hold
      WHERE btrim(coalesce(hold.record ->> 'toolName', '')) = btrim(coalesce(legacy.record ->> 'toolName', ''))
        AND EXISTS (
          SELECT 1
          FROM task_event approval
          WHERE approval.name = 'approval.decided'
            AND approval.task_run_id = legacy.task_run_id
            AND hold_vocabulary_json(approval.body) ->> 'holdID' = hold.record ->> 'holdID'
            AND hold_vocabulary_json(approval.body) ->> 'decision' = 'approve'
        )
        AND NOT EXISTS (
          SELECT 1
          FROM task_event spent
          WHERE spent.name = 'approval.hold_spent'
            AND spent.task_run_id = legacy.task_run_id
            AND hold_vocabulary_json(spent.body) ->> 'holdID' = hold.record ->> 'holdID'
        )
      ORDER BY hold.created_at DESC, hold.task_event_id DESC
      LIMIT 1;
    END IF;
    IF paired_hold_id IS NOT NULL THEN
      UPDATE task_event
      SET body = (hold_vocabulary_json(body) || jsonb_build_object('holdID', paired_hold_id))::text
      WHERE task_event_id = legacy.task_event_id;
    END IF;
  END LOOP;
END
$$;

DROP FUNCTION hold_vocabulary_json(text);