Visao geral

Widget de chat em modo host-controlled

Esta documentacao define o contrato recomendado para integrar o widget white-label da InfraStudio em qualquer aplicacao hospedeira. A ideia central e simples: o chat so existe quando o host permitir. Fora desse contexto, ele deve ser completamente destruido.

Montagem

O host decide quando chamar `mount(...)`.

Contexto

Tenant, usuario, recurso e rota devem refletir o momento atual.

Isolamento

Ao sair do contexto autorizado, destrua o widget imediatamente.

Base

Principios de integracao

Principio 1

O host decide quando o chat pode existir. O widget nao assume autonomia.

Principio 2

Ao sair do contexto autorizado, o host deve chamar `destroy()` imediatamente.

Principio 3

Ao trocar tenant, usuario, agente, recurso ou rota, o host deve invalidar o contexto anterior.

Principio 4

O SDK pode ser carregado uma vez, mas a montagem do chat so acontece por comando explicito.

Principio 5

O objetivo e evitar vazamento de contexto, UI e sessao entre clientes, paginas e recursos.

Referencia

API global

window.InfraChat.mount(config)

Monta o widget. Se ja existir uma instancia do mesmo projeto/agente, o SDK reaproveita a sessao, atualiza contexto/UI e pode reexibir um chat oculto.

window.InfraChat.updateContext(context)

Atualiza o contexto atual sem recarregar o script. Use quando a tela continua autorizada, mas o escopo mudou.

window.InfraChat.hide()

Oculta visualmente o widget sem destruir a instancia. Use apenas quando fizer sentido manter a mesma sessao ainda autorizada.

window.InfraChat.show({ open? })

Reexibe uma instancia previamente ocultada. Pode opcionalmente abrir o painel na volta com `open: true`.

window.InfraChat.destroy()

Desmonta completamente a instancia atual. Remove root, listeners, timers, controllers e estado em memoria.

window.InfraChat.isMounted()

Informa se existe uma instancia ativa do widget naquele momento.

window.InfraChat.getState()

Retorna um snapshot de debug com dados de montagem, loading, contexto e logs de ciclo de vida.

Observabilidade

Logs de ciclo de vida

Esses eventos ajudam a diagnosticar por que o widget montou, atualizou, ocultou, destruiu ou foi bloqueado.

mountedcontext_updatedhiddenshowndestroyedblocked_by_routeblocked_by_policy

Contrato

O que e obrigatorio e o que e opcional

Abaixo esta o contrato mais importante para o `mount`. Nem todo campo do contexto precisa existir sempre. O host deve mandar o que ele realmente sabe, sem inventar identificadores.

Campo

projeto

'infrastudio'

Status

Obrigatorio

Descricao

Slug ou identificador do projeto na InfraStudio. Sem ele o mount nao consegue resolver o contexto base.

Campo

agente

'agente-comercial-principal'

Status

Obrigatorio

Descricao

Slug ou identificador do agente que deve atender esse canal.

Campo

apiBase

'https://infrastudio.pro'

Status

Obrigatorio na pratica

Descricao

URL base onde o SDK vai chamar `/api/chat` e `/api/chat/config`. Se omitido, ele tenta usar o `src` do script como default.

Campo

strictHostControl

true

Status

Recomendado

Descricao

Mantem o widget em modo estritamente controlado pelo host. Para este modelo, o valor esperado e `true`.

Campo

context

{ tenant, user, resource, route, ui }

Status

Recomendado

Descricao

Bloco de contexto de negocio e de tela. Quanto melhor o host informar esse contexto, melhor o isolamento e a personalizacao.

Campo

policy

{ allowed: true, allowedRoutes: ['/imoveis/*'] }

Status

Recomendado

Descricao

Regra de exibicao enviada pelo host. Serve para travar o chat a rotas ou cenarios permitidos.

Campo

open

false

Status

Opcional

Descricao

Se `true`, o widget ja monta aberto.

Campo

hidden

false

Status

Opcional

Descricao

Se `true`, monta oculto visualmente. Em geral, prefira decidir isso no host antes de montar.

Implementacao

Exemplos principais

Comece pelo minimo valido e avance para o exemplo completo quando quiser contexto, branding e regras de exibicao.

Exemplo minimo valido

Este e o menor exemplo que ainda respeita o modelo host-controlled. Ele cria o widget, mas nao traz contexto rico.

window.InfraChat.mount({
  projeto: 'infrastudio',
  agente: 'agente-comercial-principal',
  apiBase: 'https://infrastudio.pro',
  strictHostControl: true,
});

Exemplo pratico recomendado

Este exemplo cobre rota autorizada, unlock, tenant, usuario, recurso, personalizacao visual e destruicao fora do contexto permitido.

<script src="https://infrastudio.pro/chat.js" data-projeto="infrastudio" data-agente="agente-comercial-principal"></script>
<script>
  const isAllowedRoute = window.location.pathname.startsWith('/imoveis/');
  const hasUnlockedChat = window.__unlockChat === true;

  if (!isAllowedRoute || !hasUnlockedChat) {
    window.InfraChat.destroy();
  } else {
    window.InfraChat.mount({
      projeto: 'infrastudio',
      agente: 'agente-comercial-principal',
      apiBase: 'https://infrastudio.pro',
      strictHostControl: true,
      context: {
        tenant: { id: 'cliente-a', nome: 'Cliente A' },
        user: { id: 'lead-42', tipo: 'lead' },
        resource: { id: 'imovel-99', tipo: 'imovel' },
        route: { path: window.location.pathname },
        ui: {
          title: 'Especialista em imoveis',
          theme: 'dark',
          accent: '#2563eb',
          transparent: true,
        },
      },
      policy: {
        allowed: true,
        allowedRoutes: ['/imoveis/*'],
      },
    });
  }
</script>

Atualizando o contexto

Use isso quando a tela continua autorizada, mas o recurso ou o usuario mudou.

window.InfraChat.updateContext({
  user: { id: 'lead-84', tipo: 'lead' },
  resource: { id: 'imovel-123', tipo: 'imovel' },
  route: { path: window.location.pathname },
});

Ocultando e exibindo novamente

`hide()` some com o widget, mas preserva a sessao em memoria. Para voltar, use `show()` ou monte outra vez com o mesmo projeto e agente.

window.InfraChat.hide();

// Mais tarde, para voltar a exibir o mesmo chat
window.InfraChat.show({ open: true });

Semantica

O que significa cada campo

O host pode adaptar os nomes internos do seu dominio, mas a semantica recomendada e esta: informar quem e o tenant, quem e o usuario, qual e o recurso da tela, em qual rota esta e qual politica permite a existencia do chat.

tenant

Opcional, mas recomendado em multicliente
{ id: 'cliente-a', nome: 'Cliente A' }

Identifica qual cliente, marca, operacao ou tenant e dono daquele contexto. Esse campo e importante quando a mesma InfraStudio atende mais de um cliente.

Use quando o mesmo host ou a mesma conta pode operar mais de um cliente.

Ajuda a evitar vazamento de sessao entre tenants.

Se o seu produto e single-tenant, voce pode omitir.

user

Opcional
{ id: 'user-42', tipo: 'lead' }

Representa a pessoa que esta usando ou vendo o chat naquela sessao.

`user.id` nao e obrigatorio.

Se o host nao conhece a pessoa ainda, pode omitir `user` ou mandar so dados parciais, como `{ tipo: 'lead' }`.

Nao invente IDs. Use apenas identificadores confiaveis do host.

resource

Fortemente recomendado quando a pagina gira em torno de um item
{ id: 'imovel-99', tipo: 'imovel' }

Representa o objeto principal da pagina atual. Ele nao significa necessariamente imovel; significa o recurso de negocio atualmente aberto.

Num portal imobiliario, costuma ser o imovel atual.

Num e-commerce, pode ser o produto.

Numa oficina, pode ser o veiculo.

Num SaaS, pode ser um ticket, projeto, assinatura ou conta.

route

Recomendado
{ path: window.location.pathname }

Informa em qual rota ou pagina o host esta. E a base mais comum para politica de exibicao e destruicao do widget.

O mais comum e mandar pelo menos `path`.

Se quiser, voce pode incluir metadados extras, como `name`, `section` ou `template`.

Esse campo ajuda o host a demonstrar explicitamente que o contexto de tela mudou.

ui

Opcional
{ title: 'Atendimento premium', theme: 'dark', accent: '#2563eb' }

Personaliza a identidade visual daquele contexto atual.

Pode variar por cliente, agente, campanha, imovel ou rota.

Use para refletir branding, titulo do atendimento e cor principal.

Nao substitui o isolamento de contexto; e apenas a camada visual.

policy

Recomendado
{ allowed: true, allowedRoutes: ['/imoveis/*'] }

Define a permissao de existencia do chat naquele momento.

Se `allowed` for `false`, o widget deve ser bloqueado.

Se `allowedRoutes` existir e a rota nao bater, o widget deve ser bloqueado.

Quando bloqueado, o lifecycle log esperado e `blocked_by_policy` ou `blocked_by_route`.

Sobre `resource`

`resource` nao significa necessariamente "imovel". Ele significa "o recurso principal da pagina atual". Se o cliente for imobiliaria, costuma ser um imovel. Se for e-commerce, pode ser um produto. Se for oficina, pode ser um veiculo. Se for SaaS, pode ser uma assinatura, ticket ou projeto.

O mais importante e que, ao trocar esse recurso, o host atualize ou destrua o chat. Esse e um dos pontos mais sensiveis para evitar vazamento de contexto entre uma tela e outra.

Sobre `user.id`

`user.id` nao e obrigatorio. Se o host conhece a identidade da pessoa, ele deve enviar. Se ainda nao conhece, pode omitir `user` inteiro ou mandar apenas dados parciais, como `tipo`, `origem` ou `segmento`.

Nao invente IDs apenas para preencher o campo. Use somente identificadores reais e confiaveis do sistema hospedeiro.

Operacao

Quando usar `updateContext` e quando destruir

Situacao

Entrou numa pagina autorizada pela politica do host

Acao

Chamar `mount(...)` com o contexto atual.

Situacao

Mudou o recurso, mas continua dentro de uma pagina ainda autorizada

Acao

Atualizar com `updateContext(...)` ou, se quiser isolamento maximo, `destroy()` seguido de `mount(...)` limpo.

Situacao

Mudou de tenant, agente ou perfil de usuario

Acao

Preferir `destroy()` e `mount(...)` de novo para evitar heranca indevida.

Situacao

Saiu da pagina autorizada

Acao

Chamar `destroy()` imediatamente.

Situacao

Quer apenas ocultar temporariamente o mesmo chat ainda autorizado

Acao

Usar `hide()`.

Situacao

O chat foi ocultado e precisa voltar sem perder a sessao

Acao

Usar `show({ open: true })` ou chamar `mount(...)` novamente com o mesmo projeto/agente.

Adaptacao

Exemplos por dominio

O formato do contexto e sempre o mesmo, mas o significado de `resource` muda de acordo com o negocio do cliente.

Imobiliaria

O recurso principal costuma ser o imovel.

context: {
  tenant: { id: 'imobiliaria-sol' },
  user: { id: 'lead-42', tipo: 'lead' },
  resource: { id: 'imovel-99', tipo: 'imovel' },
  route: { path: '/imoveis/apartamento-centro' },
}

E-commerce

O recurso principal costuma ser o produto em exibicao.

context: {
  tenant: { id: 'loja-x' },
  user: { id: 'cliente-77', tipo: 'comprador' },
  resource: { id: 'sku-123', tipo: 'produto' },
  route: { path: '/produtos/camiseta-premium' },
}

Servico

O recurso principal pode ser um veiculo, atendimento ou ordem de servico.

context: {
  tenant: { id: 'oficina-y' },
  user: { id: 'cliente-19', tipo: 'condutor' },
  resource: { id: 'placa-abc1d23', tipo: 'veiculo' },
  route: { path: '/servicos/freio' },
}