107 lines
3.8 KiB
SQL
107 lines
3.8 KiB
SQL
ALTER TABLE agent_bots ADD COLUMN IF NOT EXISTS captain_assistant_id BIGINT;
|
|
|
|
-- This data repair and its unique indexes must see a stable snapshot. These
|
|
-- locks block concurrent writes while allowing reads, so run this migration
|
|
-- in a maintenance window sized for the deduplication.
|
|
LOCK TABLE agent_bots, agent_bot_inboxes, captain_inboxes, conversations,
|
|
agent_bot_presence_events, bot_rules, bot_trigger_configs
|
|
IN SHARE ROW EXCLUSIVE MODE;
|
|
|
|
UPDATE agent_bots
|
|
SET captain_assistant_id = (config ->> 'assistant_id')::BIGINT
|
|
WHERE bot_type = 'captain'
|
|
AND captain_assistant_id IS NULL
|
|
AND config ->> 'assistant_id' ~ '^[0-9]+$';
|
|
|
|
UPDATE conversations conversation
|
|
SET assignee_agent_bot_id = canonical.keep_id
|
|
FROM (
|
|
SELECT account_id, captain_assistant_id, MIN(id) AS keep_id,
|
|
ARRAY_AGG(id) AS duplicate_ids
|
|
FROM agent_bots
|
|
WHERE captain_assistant_id IS NOT NULL
|
|
GROUP BY account_id, captain_assistant_id
|
|
HAVING COUNT(*) > 1
|
|
) canonical
|
|
WHERE conversation.assignee_agent_bot_id = ANY(canonical.duplicate_ids)
|
|
AND conversation.assignee_agent_bot_id <> canonical.keep_id;
|
|
|
|
UPDATE agent_bot_inboxes binding
|
|
SET agent_bot_id = canonical.keep_id
|
|
FROM (
|
|
SELECT account_id, captain_assistant_id, MIN(id) AS keep_id,
|
|
ARRAY_AGG(id) AS duplicate_ids
|
|
FROM agent_bots
|
|
WHERE captain_assistant_id IS NOT NULL
|
|
GROUP BY account_id, captain_assistant_id
|
|
HAVING COUNT(*) > 1
|
|
) canonical
|
|
WHERE binding.agent_bot_id = ANY(canonical.duplicate_ids)
|
|
AND binding.agent_bot_id <> canonical.keep_id;
|
|
|
|
UPDATE agent_bot_presence_events event
|
|
SET agent_bot_id = canonical.keep_id
|
|
FROM (
|
|
SELECT account_id, captain_assistant_id, MIN(id) AS keep_id,
|
|
ARRAY_AGG(id) AS duplicate_ids
|
|
FROM agent_bots
|
|
WHERE captain_assistant_id IS NOT NULL
|
|
GROUP BY account_id, captain_assistant_id
|
|
HAVING COUNT(*) > 1
|
|
) canonical
|
|
WHERE event.agent_bot_id = ANY(canonical.duplicate_ids)
|
|
AND event.agent_bot_id <> canonical.keep_id;
|
|
|
|
UPDATE bot_rules rule
|
|
SET agent_bot_id = canonical.keep_id
|
|
FROM (
|
|
SELECT account_id, captain_assistant_id, MIN(id) AS keep_id,
|
|
ARRAY_AGG(id) AS duplicate_ids
|
|
FROM agent_bots
|
|
WHERE captain_assistant_id IS NOT NULL
|
|
GROUP BY account_id, captain_assistant_id
|
|
HAVING COUNT(*) > 1
|
|
) canonical
|
|
WHERE rule.agent_bot_id = ANY(canonical.duplicate_ids)
|
|
AND rule.agent_bot_id <> canonical.keep_id;
|
|
|
|
UPDATE bot_trigger_configs config
|
|
SET agent_bot_id = canonical.keep_id
|
|
FROM (
|
|
SELECT account_id, captain_assistant_id, MIN(id) AS keep_id,
|
|
ARRAY_AGG(id) AS duplicate_ids
|
|
FROM agent_bots
|
|
WHERE captain_assistant_id IS NOT NULL
|
|
GROUP BY account_id, captain_assistant_id
|
|
HAVING COUNT(*) > 1
|
|
) canonical
|
|
WHERE config.agent_bot_id = ANY(canonical.duplicate_ids)
|
|
AND config.agent_bot_id <> canonical.keep_id;
|
|
|
|
DELETE FROM agent_bot_inboxes duplicate
|
|
USING agent_bot_inboxes canonical
|
|
WHERE duplicate.id > canonical.id
|
|
AND duplicate.agent_bot_id = canonical.agent_bot_id
|
|
AND duplicate.inbox_id = canonical.inbox_id;
|
|
|
|
DELETE FROM agent_bots duplicate
|
|
USING agent_bots canonical
|
|
WHERE duplicate.id > canonical.id
|
|
AND duplicate.account_id IS NOT DISTINCT FROM canonical.account_id
|
|
AND duplicate.captain_assistant_id = canonical.captain_assistant_id
|
|
AND duplicate.captain_assistant_id IS NOT NULL;
|
|
|
|
DELETE FROM captain_inboxes duplicate
|
|
USING captain_inboxes canonical
|
|
WHERE duplicate.id > canonical.id
|
|
AND duplicate.inbox_id = canonical.inbox_id
|
|
AND duplicate.deleted_at IS NULL
|
|
AND canonical.deleted_at IS NULL;
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_bots_captain_assistant
|
|
ON agent_bots(account_id, captain_assistant_id);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_bot_inboxes_bot_inbox
|
|
ON agent_bot_inboxes(agent_bot_id, inbox_id);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_captain_inboxes_active_inbox
|
|
ON captain_inboxes(inbox_id) WHERE deleted_at IS NULL;
|