feat: add call center queues
- packages/database: Agent, AgentSession, AgentStateEvent, AgentPauseEvent, PauseReason, Queue, QueueMember (agente.md secao 53) - apps/api/src/queues: CRUD de filas gerando queues.conf pelo mesmo padrao do dialplan (arquivo compartilhado + module reload app_queue.so), mas SEM membros estaticos no arquivo — membership eh 100% dinamica via AMI (evita duas fontes de verdade conflitantes) - apps/api/src/pause-reasons: CRUD de motivos de pausa - apps/api/src/agents: CRUD administrativo de agentes (1:1 com User) - apps/api/src/agent-console: maquina de estados do agente (LOGGED_IN/AVAILABLE/PAUSED), 'tela do agente' via login/available/pause/unpause/logout, cada transicao aciona AMI QueueAdd/QueuePause/QueueRemove de verdade e registra agent_state_events/agent_pause_events com inicio/fim - apps/api/src/monitoring: GET /api/monitoring/queues (chamadas aguardando, agentes logados/pausados/disponiveis via AMI QueueStatus ao vivo) — metricas historicas (TME/TMA/SLA) ficam para a Fase 7 Testado ponta a ponta contra o Asterisk real: fila criada aparece via 'queue show'; agente loga, fica disponivel (QueueAdd confirmado, membro dinamico visivel), pausa com motivo (confirmado 'paused:Almoco' ao vivo), despausa, desloga (QueueRemove confirmado, fila volta a 'No Members'). Disposicoes de chamada e Callback adiados para a Fase 6 (dependem de haver chamadas de campanha reais para classificar).
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "QueueStrategy" AS ENUM ('ringall', 'leastrecent', 'fewestcalls', 'random', 'rrmemory', 'rrordered', 'linear', 'wrandom');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "AgentState" AS ENUM ('OFFLINE', 'LOGGED_IN', 'AVAILABLE', 'RINGING', 'IN_CALL', 'WRAP_UP', 'PAUSED');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "queues" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"number" TEXT NOT NULL,
|
||||
"strategy" "QueueStrategy" NOT NULL DEFAULT 'ringall',
|
||||
"timeout" INTEGER NOT NULL DEFAULT 15,
|
||||
"retry" INTEGER NOT NULL DEFAULT 5,
|
||||
"wrap_up_time" INTEGER NOT NULL DEFAULT 0,
|
||||
"max_len" INTEGER NOT NULL DEFAULT 0,
|
||||
"music_on_hold" TEXT NOT NULL DEFAULT 'default',
|
||||
"announce" TEXT,
|
||||
"service_level" INTEGER NOT NULL DEFAULT 60,
|
||||
"auto_fill" BOOLEAN NOT NULL DEFAULT true,
|
||||
"ring_in_use" BOOLEAN NOT NULL DEFAULT true,
|
||||
"weight" INTEGER NOT NULL DEFAULT 0,
|
||||
"enabled" BOOLEAN NOT NULL DEFAULT true,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "queues_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "queue_members" (
|
||||
"id" TEXT NOT NULL,
|
||||
"queue_id" TEXT NOT NULL,
|
||||
"agent_id" TEXT NOT NULL,
|
||||
"penalty" INTEGER NOT NULL DEFAULT 0,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "queue_members_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "pause_reasons" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"code" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"max_duration_seconds" INTEGER,
|
||||
"paid" BOOLEAN NOT NULL DEFAULT false,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "pause_reasons_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "agents" (
|
||||
"id" TEXT NOT NULL,
|
||||
"code" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"current_extension" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "agents_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "agent_sessions" (
|
||||
"id" TEXT NOT NULL,
|
||||
"agent_id" TEXT NOT NULL,
|
||||
"extension" TEXT NOT NULL,
|
||||
"started_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"ended_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "agent_sessions_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "agent_state_events" (
|
||||
"id" TEXT NOT NULL,
|
||||
"agent_id" TEXT NOT NULL,
|
||||
"state" "AgentState" NOT NULL,
|
||||
"started_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"ended_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "agent_state_events_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "agent_pause_events" (
|
||||
"id" TEXT NOT NULL,
|
||||
"agent_id" TEXT NOT NULL,
|
||||
"pause_reason_id" TEXT NOT NULL,
|
||||
"started_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"ended_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "agent_pause_events_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "queues_name_key" ON "queues"("name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "queues_number_key" ON "queues"("number");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "queue_members_queue_id_agent_id_key" ON "queue_members"("queue_id", "agent_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "pause_reasons_code_key" ON "pause_reasons"("code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "agents_code_key" ON "agents"("code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "agents_user_id_key" ON "agents"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "agent_sessions_agent_id_idx" ON "agent_sessions"("agent_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "agent_state_events_agent_id_ended_at_idx" ON "agent_state_events"("agent_id", "ended_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "agent_pause_events_agent_id_ended_at_idx" ON "agent_pause_events"("agent_id", "ended_at");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "queue_members" ADD CONSTRAINT "queue_members_queue_id_fkey" FOREIGN KEY ("queue_id") REFERENCES "queues"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "queue_members" ADD CONSTRAINT "queue_members_agent_id_fkey" FOREIGN KEY ("agent_id") REFERENCES "agents"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "agents" ADD CONSTRAINT "agents_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "agent_sessions" ADD CONSTRAINT "agent_sessions_agent_id_fkey" FOREIGN KEY ("agent_id") REFERENCES "agents"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "agent_state_events" ADD CONSTRAINT "agent_state_events_agent_id_fkey" FOREIGN KEY ("agent_id") REFERENCES "agents"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "agent_pause_events" ADD CONSTRAINT "agent_pause_events_agent_id_fkey" FOREIGN KEY ("agent_id") REFERENCES "agents"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "agent_pause_events" ADD CONSTRAINT "agent_pause_events_pause_reason_id_fkey" FOREIGN KEY ("pause_reason_id") REFERENCES "pause_reasons"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
Reference in New Issue
Block a user