From 03711e62800c17598ff894cef6ffd587fb0f2139 Mon Sep 17 00:00:00 2001 From: VPS 4 Builder Date: Sun, 5 Jul 2026 19:48:29 +0200 Subject: [PATCH] =?UTF-8?q?feat(secretaria):=20agente/c=C3=A9rebro=20por?= =?UTF-8?q?=20n=C3=BAmero=20na=20aba=20N=C3=BAmeros?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adiciona o seletor "Agente / Cérebro deste número" no NumbersPanel: cada número de WhatsApp passa a apontar para um agente (sec_numbers.agent_id), tornando a Secretária, os nós do cérebro e a agenda separados POR SESSÃO. Mostra o cérebro vinculado em cada card; tipos SecNumber.agent_id e CalendarSlot.instance_id + param instance_id no calendar. Co-Authored-By: Claude Opus 4.8 --- frontend/views/newwhats/SecretariaView.tsx | 36 ++++++++++++++++--- .../views/newwhats/services/secretariaApi.ts | 5 ++- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/frontend/views/newwhats/SecretariaView.tsx b/frontend/views/newwhats/SecretariaView.tsx index da4d248..c18f2a8 100644 --- a/frontend/views/newwhats/SecretariaView.tsx +++ b/frontend/views/newwhats/SecretariaView.tsx @@ -722,9 +722,10 @@ const ROLE_OPTIONS: { value: NumberRole; label: string }[] = [ interface BaileysInstance { id: string; name: string; status: string } function NumbersPanel({ - numbers, loading, onCreate, onUpdate, onDelete, + numbers, agents, loading, onCreate, onUpdate, onDelete, }: { numbers: SecNumber[] + agents: SecAgent[] loading: boolean onCreate: (d: Partial) => void onUpdate: (id: string, d: Partial) => void @@ -734,7 +735,8 @@ function NumbersPanel({ const [loadingInst, setLoadingInst] = useState(false) const [rolePickerFor, setRolePickerFor] = useState(null) // instance_id const [editingId, setEditingId] = useState(null) // sec_number.id - const [editForm, setEditForm] = useState<{ area: string; priority: number; notes: string }>({ area: '', priority: 10, notes: '' }) + const [editForm, setEditForm] = useState<{ area: string; priority: number; notes: string; agent_id: string | null }>({ area: '', priority: 10, notes: '', agent_id: null }) + const agentNameOf = (id: string | null | undefined) => agents.find((a) => a.id === id)?.name ?? null useEffect(() => { setLoadingInst(true) @@ -825,6 +827,14 @@ function NumbersPanel({ )} {num?.area && · {num.area}} + {num && ( +
+ + + {agentNameOf(num.agent_id) ?? 'Cérebro padrão (1º agente ativo)'} + +
+ )} {/* Actions */} @@ -843,6 +853,8 @@ function NumbersPanel({ {/* Role picker dropdown */} {rolePickerFor === inst.id && ( + <> +
setRolePickerFor(null)} /> + )} @@ -891,7 +904,7 @@ function NumbersPanel({ {/* Editar detalhes (área, prioridade) */} {num && !isEditing && ( -
- {/* Inline edit: área + prioridade */} + {/* Inline edit: agente/cérebro + área + prioridade */} {isEditing && (
+
+

Agente / Cérebro deste número

+ +

Cada número responde com o cérebro (persona, regras, conhecimento, agenda) do agente escolhido aqui.

+

Área / Especialidade

void } = {activeTab === 'numbers' && ( store.createNumber(d)} onUpdate={(id, d) => store.updateNumber(id, d)} diff --git a/frontend/views/newwhats/services/secretariaApi.ts b/frontend/views/newwhats/services/secretariaApi.ts index e537e3d..5a9cb2c 100644 --- a/frontend/views/newwhats/services/secretariaApi.ts +++ b/frontend/views/newwhats/services/secretariaApi.ts @@ -75,6 +75,7 @@ export interface CalendarSlot { date: string time_start: string time_end: string + instance_id?: string | null // número/sessão dona do slot (null = global) attendee_name: string | null attendee_phone: string | null status: 'available' | 'booked' | 'cancelled' @@ -132,6 +133,8 @@ export type NumberRole = export interface SecNumber { id: string instance_id: string + clinica_id?: string | null + agent_id: string | null // agente/cérebro deste número (separação por sessão) label: string role: NumberRole area: string | null @@ -153,7 +156,7 @@ export const secNumberApi = { // ─── Calendar ───────────────────────────────────────────────────────────────── export const secCalApi = { - list: (params?: { from?: string; to?: string; status?: string }) => + list: (params?: { from?: string; to?: string; status?: string; instance_id?: string }) => api.get(`${BASE}/calendar`, { params }).then((r) => r.data), create: (d: Partial) => api.post(`${BASE}/calendar`, d).then((r) => r.data), update: (id: string, d: Partial) => api.put(`${BASE}/calendar/${id}`, d).then((r) => r.data),