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:
@@ -208,6 +208,30 @@ export async function runMigrations(db: Knex): Promise<void> {
|
||||
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