fix(newwhats): papel do número no /wa-inbox p/ usuário sem conta no motor
Os papéis (sec_numbers) são resolvidos no motor pela conta (x-nw-email). Um
usuário que só existe no scoreodonto (ex.: recepcionista) não tem conta no motor,
então buscar os papéis com o e-mail DELE retorna "conta não encontrada" → todos os
números liberados apareciam como "Sem papel definido". Agora o papel de cada sessão
liberada é buscado com o e-mail do DONO da sessão (cache por e-mail). Verificado:
recep passa a ver o número como role=clinic ("Clínica / Recepção · Rui Cesar").
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+21
-10
@@ -301,29 +301,39 @@ export function createAccountsRoute(pool) {
|
||||
};
|
||||
|
||||
try {
|
||||
// Papéis: sec_numbers são globais no motor — um fetch, indexado por instance_id.
|
||||
const numbers = await motorGet('/secretaria/numbers', email);
|
||||
const roleOf = new Map(numbers.map((n) => [n.instance_id, n]));
|
||||
const meta = (instanceId, fallbackName) => {
|
||||
const n = roleOf.get(instanceId) || {};
|
||||
// Papéis (sec_numbers) são resolvidos no motor pela CONTA (x-nw-email). Um
|
||||
// usuário sem conta no motor (ex.: recepcionista que só existe no scoreodonto)
|
||||
// não tem números próprios — então o papel de cada número LIBERADO precisa ser
|
||||
// buscado com o e-mail do DONO da sessão, não do usuário logado. Cache por e-mail.
|
||||
const numbersCache = new Map();
|
||||
const numbersFor = async (asEmail) => {
|
||||
if (!numbersCache.has(asEmail)) {
|
||||
const nums = await motorGet('/secretaria/numbers', asEmail);
|
||||
numbersCache.set(asEmail, new Map(nums.map((n) => [n.instance_id, n])));
|
||||
}
|
||||
return numbersCache.get(asEmail);
|
||||
};
|
||||
const metaFrom = (roleMap, instanceId, fallbackName) => {
|
||||
const n = roleMap.get(instanceId) || {};
|
||||
return { role: n.role || null, label: n.label || fallbackName || null, area: n.area || null, notes: n.notes || null };
|
||||
};
|
||||
|
||||
const out = [];
|
||||
const seen = new Set();
|
||||
const push = (s, extra) => {
|
||||
const pushWith = (s, roleMap, extra) => {
|
||||
if (!s || seen.has(s.id)) return;
|
||||
seen.add(s.id);
|
||||
out.push({
|
||||
instanceId: s.id, phone: s.phone || null, name: s.name || null,
|
||||
status: s.status || null, avatar: s.avatar || null,
|
||||
...meta(s.id, s.name), ...extra,
|
||||
...metaFrom(roleMap, s.id, s.name), ...extra,
|
||||
});
|
||||
};
|
||||
|
||||
// 1) Sessões PRÓPRIAS (conta do próprio usuário no motor).
|
||||
// 1) Sessões PRÓPRIAS (conta do próprio usuário no motor) — papel da própria conta.
|
||||
const ownRoles = await numbersFor(email);
|
||||
for (const s of await motorGet('/sessions', email)) {
|
||||
push(s, { clinicaId: null, ownerEmail: email, ownerNome: null, own: true, canInbox: true });
|
||||
pushWith(s, ownRoles, { clinicaId: null, ownerEmail: email, ownerNome: null, own: true, canInbox: true });
|
||||
}
|
||||
|
||||
// 2) Sessões LIBERADAS por outros donos (can_inbox por sessão).
|
||||
@@ -343,8 +353,9 @@ export function createAccountsRoute(pool) {
|
||||
const { rows } = await pool.query('SELECT nome FROM usuarios WHERE id = $1', [owner.ownerId]);
|
||||
ownerNome = rows[0]?.nome || null;
|
||||
} catch { /* opcional */ }
|
||||
const ownerRoles = await numbersFor(owner.email); // papéis dos números vêm da conta do DONO
|
||||
for (const s of await motorGet('/sessions', owner.email)) {
|
||||
if (allowed.has(s.id)) push(s, { clinicaId, ownerEmail: owner.email, ownerNome, own: false, canInbox: true });
|
||||
if (allowed.has(s.id)) pushWith(s, ownerRoles, { clinicaId, ownerEmail: owner.email, ownerNome, own: false, canInbox: true });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user