feat(secretaria): modelo de canal (clinica_id) + auto-reply 1:1 com nome legível
- sec_numbers ganha clinica_id (mapa canal→clínica); migrate idempotente. - clinica_id resolvido por CANAL no auto-reply (sec_numbers pela instância que recebeu) e por-REQUISIÇÃO no chat manual (header x-nw-clinica); brain.chat aceita opts.clinicaId e escopa a ponte de agenda (fallback: config global). - /secretaria/numbers CRUD inclui clinica_id. - auto-reply só cria conversa para 1:1 (@s.whatsapp.net) — exclui grupos/ broadcast/newsletter/lid; contact_name legível (Contact → +telefone → jid). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -127,6 +127,7 @@ async function runMigrations(db) {
|
||||
await db.schema.createTable('sec_numbers', (t) => {
|
||||
t.uuid('id').primary().defaultTo(db.raw('gen_random_uuid()'));
|
||||
t.string('instance_id', 100).nullable(); // ID da instância Baileys existente
|
||||
t.string('clinica_id', 100).nullable(); // canal→clínica: workspace dono deste número (satélite)
|
||||
t.string('phone', 30).nullable(); // número do WhatsApp (preenchido após conexão)
|
||||
t.string('label', 100).notNullable(); // apelido (pode vir do nome da instância)
|
||||
t.string('role', 30).notNullable().defaultTo('clinic'); // secretary_virtual | clinic | doctor | specialist | manager | reserve | human_secretary
|
||||
@@ -137,6 +138,10 @@ async function runMigrations(db) {
|
||||
t.timestamps(true, true);
|
||||
});
|
||||
}
|
||||
else if (!(await db.schema.hasColumn('sec_numbers', 'clinica_id'))) {
|
||||
// Tabela pré-existente: adiciona o mapa canal→clínica.
|
||||
await db.schema.alterTable('sec_numbers', (t) => t.string('clinica_id', 100).nullable());
|
||||
}
|
||||
// ── sec_knowledge_chunks (RAG sem pgvector) ───────────────────────────────
|
||||
// Chunks de conhecimento + embedding (JSON em text). Busca por similaridade
|
||||
// roda na aplicação (cosseno), então não exige a extensão pgvector.
|
||||
|
||||
Reference in New Issue
Block a user