Mapa de atividades do Construtor
Cada item do book de aprendizado aponta para uma destas âncoras (docId). Manutenção: app/docs/AI_CONSTRUTOR.md.
intent-info
Pedido de informação
Perguntas do tipo «gere a URL», «quais variáveis», «explique». Devolver só reply (e plan se ajudar).
intent: "info" surveyJson: null settingsPatch: null surveyMeta: null createSurvey: false changes: []
O Studio não autosava e não mostra recibo «O que mudei».
intent-mutate
Pedido de alteração
Só quando o humano pediu mudar o form ou settings. Devolver JSON completo e/ou settingsPatch com diff real. Título ecoado (igual ao atual) não é mudança.
surveyjson-form
Form (surveyJson)
Páginas, perguntas, visibleIf / enableIf / requiredIf, tipos SurveyJS. Merge no JSON atual. Nomes em snake_case. Não inventar triggers[]. title, description, html e choices[].text são string em português — não mapa { "pt": "…" } / { "default", "pt" } a menos que o humano peça tradução. survey.locale: "pt" no root pode ficar.
Runtime: Form Library 2.5.39 (paridade com comentário por opção do Creator). choices[].showCommentArea, isCommentRequired e commentPlaceholder no item são válidos. O valor gravado passa a { value, comment } (CSV: nome_value + nome_comment). visibleIf {radio} = '1' continua comparando o value.
Pergunta type: "html": a propriedade html é uma string JSON (ou mapa locale { "default": "…" }). Proibido array de linhas, objeto {iframe:…} ou markdown. Iframe de mapa usa srcdoc='…' (aspas simples); JS/CSS internos com aspas duplas. Não reescrever um srcdoc já válido. Não inventar Leaflet no JSON — colar o template da biblioteca. O pin grava em perguntas type: "text" cujos name batem com data-lat-name / data-lng-name / data-addr-name. Calculada (expression) não recebe o pin. survey.setValue funciona com visible: false; o fallback via DOM exige o input no layout.
{
"type": "html",
"name": "mapa_coordenadas",
"html": "<iframe title=\"…\" allow=\"geolocation\" data-lat-name=\"latitude_g6\" data-lng-name=\"longitude_g6\" data-addr-name=\"endereco_g6\" srcdoc='<!DOCTYPE html>…'></iframe>"
}
{ "type": "text", "name": "latitude_g6", "title": "Latitude" }
{ "type": "text", "name": "longitude_g6", "title": "Longitude" }
{ "type": "text", "name": "endereco_g6", "title": "Endereço" }
Expressão não é JavaScript. Token completo em { }: {q} notempty, {matrix[0].col} notempty, countInArray({m}, 'col') > 0 (dois argumentos). Proibido {q}.length, coluna ano, e not(expr) — a inversa é !(expr) ou countInArray({m}, 'col') = 0. XOR: radiogroup + choices[].visibleIf. Expressão inválida ou not(…) esconde todas as opções.
settings-filters
Filtros
settingsPatch.filters[] com expression, code, label. O Studio projeta triggers type=complete. O Construtor não edita surveyJson.triggers[].
settings-quotas
Cotas
settingsPatch.quotas[]. Nunca trigger complete para cota. Arrays substituem a lista (incluir itens que devem permanecer).
settings-automations
Automações
settingsPatch.automations[] When/Then (webhook, redirect, email, ai…). Webhook HTTPS. Arrays substituem a lista.
settings-messages
Encerramento
settingsPatch.messages.{filtered|overlimit|completed} = texto (mode: custom) ou redirect (mode: redirect, URL absoluta). Não usar path relativo. Não escrever o redirect só no reply.
create-survey
Pesquisa nova
createSurvey=true somente se o humano pediu pesquisa nova ou o form atual está vazio (0 perguntas). Se já há perguntas e o pedido é alterar, createSurvey=false e merge no JSON atual.
prefill-url
URL de prefill
Formato: https://r.gmrpesquisa.com.br/{publicName}?nome=VALOR_REAL (host público, nunca survey.gmrpesquisa.com.br/{slug} — isso devolve {"error":"not_found"}).
Query com {token} no redirect de encerramento é preenchida no complete com a resposta (data, senão customs). Host público: https://r.gmrpesquisa.com.br/{slug}?campo={campo}. Nunca survey.gmrpesquisa.com.br/{slug} ({"error":"not_found"}). Link colado no browser sem passar pelo complete não substitui as chaves.
public-name
Slug / base da URL
O contexto do turno já traz publicName. Nunca peça «a URL de entrada» se o slug estiver preenchido. Monte a URL pública (PUBLIC_BASE_URL, hoje https://r.gmrpesquisa.com.br/{publicName}). Proibido survey.gmrpesquisa.com.br/{slug}.
plan-then-verify
Planejar, executar, conferir
- Efeitos do pedido
- Onde mora (schema vs settings vs API que você não chama)
- Ordem das alterações
- Lista de tarefas no
plan[]— no mesmo JSON que já traz o patch. Não esperar um segundo «pode executar». - Conferir se o pedido foi feito (não só JSON válido)
- Se travar de verdade (dado ausente no contexto):
fulfillment.ok=false,blocker, orientação manual — sem patch. Revisão de cliente não é travamento.
skipversion
Autosave vs Salvar
O Construtor pode gravar draft com skipVersion: true quando houve mutate + diff. Isso não entra no ledger de aprendizado. Instrução aceita = botão Salvar (note: studio_json), que gera versão e alimenta classificador → book.