omnichannel-deploy/database/migrations/017_configurable_triage_flow.sql

146 lines
6.2 KiB
MySQL
Raw Normal View History

-- ============================================================
-- Migration 017: Fluxo configuravel de triagem do Agente Virtual Sothis
-- Tabelas:
-- bot_triage_flows
-- bot_triage_audiences
-- bot_triage_intents
-- whatsapp_chat_atribuicoes
-- ============================================================
CREATE TABLE IF NOT EXISTS bot_triage_flows (
id SERIAL PRIMARY KEY,
name VARCHAR(160) NOT NULL UNIQUE,
active BOOLEAN NOT NULL DEFAULT TRUE,
greeting_message TEXT NOT NULL,
audience_question TEXT NOT NULL,
intent_question_template TEXT NOT NULL,
fallback_message TEXT NOT NULL,
fallback_area_id INTEGER REFERENCES areas(id) ON DELETE SET NULL,
max_attempts INTEGER NOT NULL DEFAULT 2,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS bot_triage_audiences (
id SERIAL PRIMARY KEY,
flow_id INTEGER NOT NULL REFERENCES bot_triage_flows(id) ON DELETE CASCADE,
label VARCHAR(160) NOT NULL,
keywords TEXT,
sort_order INTEGER NOT NULL DEFAULT 1,
active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS bot_triage_intents (
id SERIAL PRIMARY KEY,
audience_id INTEGER NOT NULL REFERENCES bot_triage_audiences(id) ON DELETE CASCADE,
label VARCHAR(160) NOT NULL,
area_id INTEGER NOT NULL REFERENCES areas(id) ON DELETE CASCADE,
keywords TEXT,
sort_order INTEGER NOT NULL DEFAULT 1,
active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
ALTER TABLE whatsapp_chat_atribuicoes
ADD COLUMN IF NOT EXISTS triage_flow_id INTEGER REFERENCES bot_triage_flows(id) ON DELETE SET NULL,
ADD COLUMN IF NOT EXISTS triage_audience_id INTEGER REFERENCES bot_triage_audiences(id) ON DELETE SET NULL,
ADD COLUMN IF NOT EXISTS triage_step VARCHAR(40);
CREATE INDEX IF NOT EXISTS idx_bot_triage_flows_active
ON bot_triage_flows (active);
CREATE INDEX IF NOT EXISTS idx_bot_triage_audiences_flow
ON bot_triage_audiences (flow_id, active, sort_order);
CREATE INDEX IF NOT EXISTS idx_bot_triage_intents_audience
ON bot_triage_intents (audience_id, active, sort_order);
CREATE INDEX IF NOT EXISTS idx_whatsapp_atribuicoes_triage_flow
ON whatsapp_chat_atribuicoes (triage_flow_id, triage_audience_id, triage_step);
INSERT INTO areas (nome, descricao) VALUES
('Documentos RH', 'Documentos para ex-colaboradores, informe de rendimentos e comprovantes'),
('Rescisao', 'Rescisao, FGTS, verbas rescisorias e encerramento de contrato')
ON CONFLICT (nome) DO UPDATE SET
descricao = EXCLUDED.descricao,
ativo = TRUE,
updated_at = NOW();
INSERT INTO bot_triage_flows (
name,
active,
greeting_message,
audience_question,
intent_question_template,
fallback_message,
fallback_area_id,
max_attempts,
updated_at
)
SELECT
'RH CAOA - Atendimento Sothis',
TRUE,
'Ola! Sou o Agente Virtual Sothis. Vou te direcionar para o atendimento correto de RH.',
'Digite o numero da opcao que melhor descreve voce:',
'Perfeito. Agora digite o numero do assunto que voce precisa:',
'Nao consegui identificar com seguranca. Vou encaminhar seu atendimento para o suporte de RH.',
a.id,
2,
CURRENT_TIMESTAMP
FROM areas a
WHERE a.nome = 'Suporte'
ON CONFLICT (name) DO UPDATE SET
active = TRUE,
greeting_message = EXCLUDED.greeting_message,
audience_question = EXCLUDED.audience_question,
intent_question_template = EXCLUDED.intent_question_template,
fallback_message = EXCLUDED.fallback_message,
fallback_area_id = EXCLUDED.fallback_area_id,
max_attempts = EXCLUDED.max_attempts,
updated_at = CURRENT_TIMESTAMP;
WITH flow AS (
SELECT id FROM bot_triage_flows WHERE name = 'RH CAOA - Atendimento Sothis'
)
INSERT INTO bot_triage_audiences (flow_id, label, keywords, sort_order, active, updated_at)
SELECT flow.id, seed.label, seed.keywords, seed.sort_order, TRUE, CURRENT_TIMESTAMP
FROM flow
JOIN (
VALUES
('Sou colaborador ativo', 'colaborador, funcionario, matricula, holerite, ferias, ponto, beneficios', 1),
('Sou ex-colaborador', 'ex colaborador, ex-colaborador, rescisao, fgts, informe de rendimentos, desligamento', 2),
('Sou candidato a uma vaga', 'candidato, vaga, curriculo, processo seletivo, entrevista, candidatura', 3)
) AS seed(label, keywords, sort_order) ON TRUE
ON CONFLICT DO NOTHING;
WITH audiences AS (
SELECT bta.id, bta.label
FROM bot_triage_audiences bta
INNER JOIN bot_triage_flows btf ON btf.id = bta.flow_id
WHERE btf.name = 'RH CAOA - Atendimento Sothis'
),
seed AS (
SELECT * FROM (
VALUES
('Sou colaborador ativo', 'Beneficios', 'beneficios, vale refeicao, vale transporte, convenio, plano de saude', 'Benefícios', 1),
('Sou colaborador ativo', 'Holerite', 'holerite, folha, salario, pagamento, desconto', 'Holerite', 2),
('Sou colaborador ativo', 'Ferias', 'ferias, abono, descanso, saldo de ferias', 'Férias', 3),
('Sou colaborador ativo', 'Ponto', 'ponto, espelho de ponto, banco de horas, jornada, batida', 'Ponto', 4),
('Sou ex-colaborador', 'Documentos', 'documento, documentos, comprovante, informe de rendimentos', 'Documentos RH', 1),
('Sou ex-colaborador', 'FGTS e rescisao', 'fgts, rescisao, verbas rescisorias, desligamento', 'Rescisao', 2),
('Sou ex-colaborador', 'Informe de rendimentos', 'informe, rendimentos, imposto de renda, ir', 'Documentos RH', 3),
('Sou candidato a uma vaga', 'Status da vaga', 'status, vaga, retorno, resultado', 'Recrutamento', 1),
('Sou candidato a uma vaga', 'Reagendar entrevista', 'reagendar, entrevista, agenda, horario', 'Recrutamento', 2),
('Sou candidato a uma vaga', 'Nova candidatura', 'nova candidatura, curriculo, candidatar, oportunidade', 'Recrutamento', 3)
) AS rows(audience_label, label, keywords, area_nome, sort_order)
)
INSERT INTO bot_triage_intents (audience_id, label, area_id, keywords, sort_order, active, updated_at)
SELECT audiences.id, seed.label, areas.id, seed.keywords, seed.sort_order, TRUE, CURRENT_TIMESTAMP
FROM seed
INNER JOIN audiences ON audiences.label = seed.audience_label
INNER JOIN areas ON areas.nome = seed.area_nome
ON CONFLICT DO NOTHING;