feat(secretaria): follow-up proativo com atraso (Parte B)
Quando o cliente insiste num horário mais tarde, a IA usa confirmar_depois: diz "vou confirmar, aguarde uns minutinhos" e registra um follow-up (sec_agenda_followups, fire_at = now + followup_delay_min, default 15). Um worker no ext-api (a cada 30s) processa os vencidos: consulta /slots perto do horário desejado e manda ao paciente "Oie, consegui! Posso às X?" (assinado pelo agente). Testado em dev: worker processa follow-up vencido, consulta a agenda e envia. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -195,6 +195,29 @@ async function runMigrations(db) {
|
||||
});
|
||||
await db.raw('CREATE INDEX IF NOT EXISTS idx_sec_mem_contact ON sec_contact_memory (agent_id, contact_key)');
|
||||
}
|
||||
// ── sec_agenda_followups — follow-up proativo (Parte B): a IA promete "confirmo
|
||||
// em uns minutos" e um worker envia depois o horário confirmado, com atraso.
|
||||
if (!(await db.schema.hasTable('sec_agenda_followups'))) {
|
||||
await db.schema.createTable('sec_agenda_followups', (t) => {
|
||||
t.uuid('id').primary().defaultTo(db.raw('gen_random_uuid()'));
|
||||
t.string('tenant_id', 80);
|
||||
t.string('instance_id', 100);
|
||||
t.string('chat_id', 300);
|
||||
t.string('jid', 120); // paciente
|
||||
t.string('clinica_id', 100);
|
||||
t.string('agenda_url', 300);
|
||||
t.string('agenda_secret', 200);
|
||||
t.string('dentista_nome', 120);
|
||||
t.date('data');
|
||||
t.string('hora_desejada', 8);
|
||||
t.string('periodo', 10); // manha | tarde
|
||||
t.string('paciente_nome', 120);
|
||||
t.timestamp('fire_at').notNullable();
|
||||
t.string('status', 20).defaultTo('pendente'); // pendente | enviado | falhou
|
||||
t.timestamps(true, true);
|
||||
});
|
||||
await db.raw('CREATE INDEX IF NOT EXISTS idx_followups_fire ON sec_agenda_followups (status, fire_at)');
|
||||
}
|
||||
// ── Seeds: agente padrão + nós + calendário ───────────────────────────────
|
||||
const agentCount = await db('sec_agents').count('id as c').first();
|
||||
if (Number(agentCount?.c ?? 0) === 0) {
|
||||
|
||||
Reference in New Issue
Block a user