<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Documentação Técnica App + API REST - Parte 2]]></title><description><![CDATA[<h1><img src="http://insoft-docker1:4567/assets/plugins/nodebb-plugin-emoji/emoji/android/1f517.png?v=8k80dgruung" class="not-responsive emoji emoji-android emoji--link" title=":link:" alt="🔗" /> 6. INTEGRAÇÕES EXTERNAS</h1>
<h2>6.1 Dispositivo QFace (Digicon/Suprema)</h2>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Item</th>
<th>Detalhe</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Protocolo</strong></td>
<td>TCP/IP proprietário (SDK C/C++)</td>
</tr>
<tr>
<td><strong>DLL</strong></td>
<td><code>QFM_SDK_DLL.dll</code> (32-bit e 64-bit)</td>
</tr>
<tr>
<td><strong>IP padrão</strong></td>
<td><code>172.16.110.6</code></td>
</tr>
<tr>
<td><strong>Porta padrão</strong></td>
<td><code>12120</code></td>
</tr>
<tr>
<td><strong>Modo</strong></td>
<td>Binário (asciiMode = false)</td>
</tr>
<tr>
<td><strong>Configuração</strong></td>
<td><code>config/application.json</code> → <code>deviceIp</code>, <code>devicePort</code>, <code>asciiMode</code></td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>Funções da DLL utilizadas:</strong></p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Função C</th>
<th>Wrapper TypeScript</th>
<th>Descrição</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>QF_InitSocket</code></td>
<td><code>initSocket()</code></td>
<td>Conecta ao dispositivo</td>
</tr>
<tr>
<td><code>QF_CloseSocket</code></td>
<td><code>closeSocket()</code></td>
<td>Desconecta</td>
</tr>
<tr>
<td><code>QF_DeleteAll</code></td>
<td><code>deleteAllTemplates()</code></td>
<td>Remove todos os templates do device</td>
</tr>
<tr>
<td><code>QF_EnrollImage</code></td>
<td><code>enrollImage(userID, imageBuffer)</code></td>
<td>Envia imagem e gera template</td>
</tr>
<tr>
<td><code>QF_ReadTemplate</code></td>
<td><code>readTemplate(userID)</code></td>
<td>Lê template gerado</td>
</tr>
<tr>
<td><code>QF_ScanTemplate</code></td>
<td><code>scanTemplate()</code></td>
<td>Captura template via câmera do device</td>
</tr>
<tr>
<td><code>QF_GetFirmwareVersion</code></td>
<td><code>getDeviceInfo()</code></td>
<td>Lê versão de firmware</td>
</tr>
<tr>
<td><code>QF_GetSysParameter</code></td>
<td><code>getDeviceInfo()</code></td>
<td>Lê número de série e build</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>Pontos de atenção:</strong></p>
<ul>
<li>A DLL <strong>não é thread-safe</strong> → usar sempre o mutex</li>
<li>O dispositivo precisa estar na mesma rede local (IP acessível)</li>
<li>Firewall do Windows pode bloquear a porta 12120</li>
</ul>
<hr />
<h2>6.2 API Externa (Webhook de saída)</h2>
<p dir="auto"><strong>Descrição simplificada (Suporte):</strong></p>
<blockquote>
<p dir="auto">O sistema pode enviar automaticamente os templates gerados para um sistema externo (ERP, controle de acesso, etc.) via HTTP.</p>
</blockquote>
<p dir="auto"><strong>Descrição técnica:</strong></p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Item</th>
<th>Detalhe</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Configuração</strong></td>
<td><code>externalApiEnabled</code>, <code>externalApiUrl</code>, <code>externalApiUser</code>, <code>externalApiPassword</code></td>
</tr>
<tr>
<td><strong>Formato de payload</strong></td>
<td>Configurável via <code>payloadTemplate</code> (suporta variáveis: <code>{{biometric_data}}</code>, <code>{{user_id}}</code>, <code>{{timestamp}}</code>)</td>
</tr>
<tr>
<td><strong>Endpoints customizados</strong></td>
<td><code>apiEndpoints</code> (JSON com lista de endpoints)</td>
</tr>
<tr>
<td><strong>Backup</strong></td>
<td>Registros mantidos por <code>backupRegistersDays</code> dias (padrão: 7)</td>
</tr>
</tbody>
</table>
<hr />
<h2>6.3 Windows Service Manager (NSSM)</h2>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Item</th>
<th>Detalhe</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Ferramenta</strong></td>
<td>NSSM v2.24 (Non-Sucking Service Manager)</td>
</tr>
<tr>
<td><strong>Localização</strong></td>
<td><code>nssm/win32/</code> e <code>nssm/win64/</code></td>
</tr>
<tr>
<td><strong>Uso</strong></td>
<td>Registra <code>insoft-qface-win-api.exe</code> como serviço do Windows</td>
</tr>
<tr>
<td><strong>Nome do serviço</strong></td>
<td><code>insoft-qface-win-api</code> (padrão)</td>
</tr>
<tr>
<td><strong>Variáveis de ambiente</strong></td>
<td><code>CONFIG_PATH</code>, <code>QFACE_DLL_PATH</code>, <code>SHARED_I18N_PATH</code> configuradas no serviço</td>
</tr>
</tbody>
</table>
<hr />
<h1><img src="http://insoft-docker1:4567/assets/plugins/nodebb-plugin-emoji/emoji/android/1f6a8.png?v=8k80dgruung" class="not-responsive emoji emoji-android emoji--rotating_light" title=":rotating_light:" alt="🚨" /> 7. TRATAMENTO DE ERROS E EXCEÇÕES</h1>
<h2>Sistema de Logs</h2>
<h3>Aplicativo Electron (<code>insoft-qface-app</code>)</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Aspecto</th>
<th>Detalhe</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Biblioteca</strong></td>
<td><code>electron-log</code></td>
</tr>
<tr>
<td><strong>Arquivo de log</strong></td>
<td><code>&lt;cwd&gt;/logs/AppLog.log</code></td>
</tr>
<tr>
<td><strong>Níveis</strong></td>
<td><code>info</code>, <code>warn</code>, <code>error</code>, <code>debug</code></td>
</tr>
<tr>
<td><strong>Acesso</strong></td>
<td>Dashboard → aba Logs → "Ver Logs"</td>
</tr>
</tbody>
</table>
<h3>API Windows (<code>insoft-qface-win-api</code>)</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Aspecto</th>
<th>Detalhe</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Arquivo de log</strong></td>
<td><code>&lt;exeDir&gt;/logs/AppLog.log</code></td>
</tr>
<tr>
<td><strong>Log de serviço</strong></td>
<td><code>&lt;exeDir&gt;/logs/service.log</code></td>
</tr>
<tr>
<td><strong>Log de erros</strong></td>
<td><code>&lt;exeDir&gt;/logs/error.log</code></td>
</tr>
<tr>
<td><strong>HTTP Requests</strong></td>
<td>Morgan (<code>combined</code> format) no console</td>
</tr>
</tbody>
</table>
<h2>Proteção contra crashes</h2>
<p dir="auto">O sistema possui handlers globais para evitar que erros inesperados derrubem o aplicativo:</p>
<pre><code class="language-typescript">// No Electron (main.ts) e na API (start.ts / server/index.ts)
process.on('uncaughtException', (error) =&gt; {
  logger.error('Uncaught Exception:', error);
  // NÃO encerra o processo — mantém o app rodando
});

process.on('unhandledRejection', (reason) =&gt; {
  logger.error('Unhandled Rejection:', reason);
  // NÃO encerra o processo
});
</code></pre>
<h2>Códigos de mensagem de erro</h2>
<p dir="auto">Todos os erros retornados pela API usam o sistema de mensagens codificadas (<code>repp.message.X</code>). A tabela completa está em <a href="shared/i18n/en-US.json">shared/i18n/en-US.json</a> e <a href="shared/i18n/pt-BR.json">shared/i18n/pt-BR.json</a>.</p>
<p dir="auto"><strong>Erros mais comuns em produção:</strong></p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Código</th>
<th>Constante</th>
<th>Mensagem (PT-BR)</th>
<th>Causa</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>repp.message.24</code></td>
<td><code>FAILED_CONNECT_DEVICE</code></td>
<td>Falha ao conectar no dispositivo</td>
<td>IP/porta errado ou dispositivo offline</td>
</tr>
<tr>
<td><code>repp.message.55</code></td>
<td><code>API_WINDOWS_SERVICE_NOT_INSTALLED</code></td>
<td>Serviço Windows não instalado</td>
<td>API não foi instalada como serviço</td>
</tr>
<tr>
<td><code>repp.message.31</code></td>
<td><code>CAPTURE_TIMEOUT</code></td>
<td>Timeout na captura</td>
<td>Usuário não posicionou rosto a tempo</td>
</tr>
<tr>
<td><code>repp.message.27</code></td>
<td><code>INVALID_IMAGE</code></td>
<td>Imagem inválida</td>
<td>Imagem não contém face detectável</td>
</tr>
<tr>
<td><code>repp.message.43</code></td>
<td><code>TEMPLATE_SCAN_FAILED</code></td>
<td>Falha na captura do template</td>
<td>Câmera do QFace com problema</td>
</tr>
</tbody>
</table>
<hr />
<h1>🧪 8. CENÁRIOS COMUNS DE SUPORTE</h1>
<h2><img src="http://insoft-docker1:4567/assets/plugins/nodebb-plugin-emoji/emoji/android/2757.png?v=8k80dgruung" class="not-responsive emoji emoji-android emoji--exclamation" title=":exclamation:" alt="❗" /> Problema 1: "API não está rodando" / Dashboard mostra serviço parado</h2>
<p dir="auto"><strong>Sintoma:</strong> Status da API aparece como "Parado" ou "Não instalado" na tela do Dashboard.</p>
<p dir="auto"><strong>Possíveis causas:</strong></p>
<ul>
<li>O serviço <code>insoft-qface-win-api</code> não está instalado</li>
<li>O serviço foi interrompido manualmente</li>
<li>Alguma atualização removeu o serviço</li>
</ul>
<p dir="auto"><strong>Como investigar:</strong></p>
<ol>
<li>Abrir o <strong>Gerenciador de Serviços</strong> do Windows (<code>services.msc</code>)</li>
<li>Procurar por <code>Insoft QFace Win API</code></li>
<li>Verificar logs: <code>&lt;pasta_instalação&gt;\logs\service.log</code></li>
</ol>
<p dir="auto"><strong>Como resolver:</strong></p>
<ul>
<li>Se o serviço não existe: usar o botão <strong>"Instalar Serviço"</strong> no Dashboard</li>
<li>Se o serviço existe mas está parado: clicar em <strong>"Iniciar"</strong> no Dashboard ou no <code>services.msc</code></li>
<li>Se há erro: verificar <code>error.log</code> para detalhes</li>
</ul>
<hr />
<h2><img src="http://insoft-docker1:4567/assets/plugins/nodebb-plugin-emoji/emoji/android/2757.png?v=8k80dgruung" class="not-responsive emoji emoji-android emoji--exclamation" title=":exclamation:" alt="❗" /> Problema 2: Falha ao conectar no dispositivo QFace</h2>
<p dir="auto"><strong>Sintoma:</strong> Erros de conversão com mensagem <code>repp.message.24</code> ou "Falha ao conectar no dispositivo".</p>
<p dir="auto"><strong>Possíveis causas:</strong></p>
<ul>
<li>Dispositivo QFace desligado ou sem energia</li>
<li>IP ou porta errada na configuração</li>
<li>Firewall bloqueando a porta 12120</li>
<li>Dispositivo em outra sub-rede</li>
</ul>
<p dir="auto"><strong>Como investigar:</strong></p>
<ol>
<li>Verificar se o dispositivo está ligado (LEDs acesos)</li>
<li>Testar ping para o IP configurado: <code>ping 172.16.110.6</code></li>
<li>Verificar <code>config/application.json</code> → campos <code>deviceIp</code> e <code>devicePort</code></li>
<li>Verificar log: procurar por <code>[QFace SDK]</code> ou <code>QF_ERR_CANNOT_CONNECT_SOCKET</code></li>
</ol>
<p dir="auto"><strong>Como resolver:</strong></p>
<ul>
<li>Corrigir IP/porta nas <strong>Configurações</strong> do aplicativo</li>
<li>Verificar regras do Firewall do Windows para porta 12120</li>
<li>Confirmar que o dispositivo e o PC estão na mesma rede</li>
</ul>
<hr />
<h2><img src="http://insoft-docker1:4567/assets/plugins/nodebb-plugin-emoji/emoji/android/2757.png?v=8k80dgruung" class="not-responsive emoji emoji-android emoji--exclamation" title=":exclamation:" alt="❗" /> Problema 3: Imagens não geram template (qualidade ruim)</h2>
<p dir="auto"><strong>Sintoma:</strong> Retorno com <code>error: repp.message.27</code> (imagem inválida) ou qualidade muito baixa.</p>
<p dir="auto"><strong>Possíveis causas:</strong></p>
<ul>
<li>Imagem não contém rosto humano reconhecível</li>
<li>Resolução da imagem muito baixa</li>
<li>Imagem com iluminação inadequada (muito escura, muito clara, contra-luz)</li>
<li>Formato de imagem incompatível</li>
</ul>
<p dir="auto"><strong>Como investigar:</strong></p>
<ol>
<li>Verificar o campo <code>quality</code> no retorno (valores abaixo de 40 indicam baixa qualidade)</li>
<li>Revisar logs da API: <code>[biometricTemplateController]</code> → <code>enrollImage result</code></li>
</ol>
<p dir="auto"><strong>Como resolver:</strong></p>
<ul>
<li>Garantir imagens com rosto frontal, bem iluminado, mínimo 200x200 pixels</li>
<li>Verificar que o formato é JPEG ou PNG</li>
</ul>
<hr />
<h2><img src="http://insoft-docker1:4567/assets/plugins/nodebb-plugin-emoji/emoji/android/2757.png?v=8k80dgruung" class="not-responsive emoji emoji-android emoji--exclamation" title=":exclamation:" alt="❗" /> Problema 4: Câmera não funciona para captura ao vivo</h2>
<p dir="auto"><strong>Sintoma:</strong> Tela de captura abre mas câmera não inicializa ou mostra tela preta.</p>
<p dir="auto"><strong>Possíveis causas:</strong></p>
<ul>
<li>Permissão de câmera negada no Windows</li>
<li>Driver da câmera do QFace não instalado</li>
<li>Outro aplicativo está usando a câmera</li>
</ul>
<p dir="auto"><strong>Como investigar:</strong></p>
<ol>
<li>Verificar <strong>Configurações do Windows → Privacidade → Câmera</strong></li>
<li>O aplicativo possui botão "Abrir Configurações de Câmera" nas <strong>Configurações</strong></li>
<li>Verificar log: <code>[useCamera]</code> ou <code>[QFace SDK]</code></li>
</ol>
<p dir="auto"><strong>Como resolver:</strong></p>
<ul>
<li>Ativar permissão de câmera para o aplicativo</li>
<li>Reinstalar drivers do dispositivo QFace</li>
<li>Fechar outros aplicativos que possam estar usando a câmera</li>
</ul>
<hr />
<h2><img src="http://insoft-docker1:4567/assets/plugins/nodebb-plugin-emoji/emoji/android/2757.png?v=8k80dgruung" class="not-responsive emoji emoji-android emoji--exclamation" title=":exclamation:" alt="❗" /> Problema 5: WebSocket desconectado — eventos não chegam à interface</h2>
<p dir="auto"><strong>Sintoma:</strong> A tela de conversão não atualiza, ou a captura não é iniciada apesar da requisição ter chegado à API.</p>
<p dir="auto"><strong>Possíveis causas:</strong></p>
<ul>
<li>API rodando mas porta 3133 bloqueada por firewall</li>
<li>API reiniciou mas WebSocket do Electron ainda não reconectou</li>
</ul>
<p dir="auto"><strong>Como investigar:</strong></p>
<ol>
<li>Verificar log do Electron: procurar por <code>[WebSocket]</code></li>
<li>Verificar se o serviço da API está rodando (porta 3133)</li>
</ol>
<p dir="auto"><strong>Como resolver:</strong></p>
<ul>
<li>Reiniciar a API pelo Dashboard (botão "Reiniciar API")</li>
<li>O WebSocket reconecta automaticamente em até 5 segundos</li>
</ul>
<hr />
<h2><img src="http://insoft-docker1:4567/assets/plugins/nodebb-plugin-emoji/emoji/android/2757.png?v=8k80dgruung" class="not-responsive emoji emoji-android emoji--exclamation" title=":exclamation:" alt="❗" /> Problema 6: Erro de permissão / instalação de serviço falha</h2>
<p dir="auto"><strong>Sintoma:</strong> Botão "Instalar Serviço" retorna erro de permissão.</p>
<p dir="auto"><strong>Possíveis causas:</strong></p>
<ul>
<li>Aplicativo não está rodando como Administrador</li>
<li>Antivírus bloqueando criação de serviço</li>
</ul>
<p dir="auto"><strong>Como resolver:</strong></p>
<ul>
<li>Fechar e reabrir o aplicativo com <strong>"Executar como Administrador"</strong> (o instalador já solicita isso automaticamente)</li>
<li>Adicionar exceção no antivírus para <code>nssm.exe</code> e <code>insoft-qface-win-api.exe</code></li>
</ul>
<hr />
<h1><img src="http://insoft-docker1:4567/assets/plugins/nodebb-plugin-emoji/emoji/android/1f4dd.png?v=8k80dgruung" class="not-responsive emoji emoji-android emoji--memo" title=":memo:" alt="📝" /> 9. BOAS PRÁTICAS E OBSERVAÇÕES</h1>
<h2>Padrões utilizados no código</h2>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Padrão</th>
<th>Onde é usado</th>
<th>Motivo</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Mutex assíncrono</strong></td>
<td><code>QFaceMutex</code> na API</td>
<td>DLL não é thread-safe</td>
</tr>
<tr>
<td><strong>IPC com Context Bridge</strong></td>
<td><code>preload.ts</code></td>
<td>Segurança Electron: isola renderer do Node.js</td>
</tr>
<tr>
<td><strong>Mensagens codificadas</strong></td>
<td>Todo o sistema (<a href="http://MSG.XXX" rel="nofollow ugc">MSG.XXX</a>)</td>
<td>Internacionalização e rastreabilidade</td>
</tr>
<tr>
<td><strong>Polling de saúde</strong></td>
<td><code>startApiServer()</code></td>
<td>Garante que a API está realmente respondendo antes de sinalizar como ready</td>
</tr>
<tr>
<td><strong>Fila de eventos</strong></td>
<td><code>EventQueue</code></td>
<td>Evita perda de eventos se Electron conectar depois da API emitir</td>
</tr>
<tr>
<td><strong>Context API React</strong></td>
<td><code>ConfigContext</code>, <code>ThemeContext</code></td>
<td>Evita prop drilling e centraliza estado global</td>
</tr>
<tr>
<td><strong>Reconexão WebSocket</strong></td>
<td><code>reconnectionAttempts: Infinity</code></td>
<td>Alta disponibilidade da comunicação em tempo real</td>
</tr>
</tbody>
</table>
<h2>Cuidados ao modificar o sistema</h2>
<h3><img src="http://insoft-docker1:4567/assets/plugins/nodebb-plugin-emoji/emoji/android/26a0.png?v=8k80dgruung" class="not-responsive emoji emoji-android emoji--warning" title=":warning:" alt="⚠" />️ DLL nativa (<code>QFM_SDK_DLL.dll</code>)</h3>
<ul>
<li><strong>NUNCA</strong> fazer chamadas concorrentes à DLL sem usar o <code>qfaceMutex</code></li>
<li>A DLL é <strong>32-bit em alguns ambientes</strong> — verificar compatibilidade do processo</li>
<li>Alterações nas assinaturas de função precisam ser sincronizadas com <code>qface-sdk.ts</code></li>
</ul>
<h3><img src="http://insoft-docker1:4567/assets/plugins/nodebb-plugin-emoji/emoji/android/26a0.png?v=8k80dgruung" class="not-responsive emoji emoji-android emoji--warning" title=":warning:" alt="⚠" />️ Arquivo <code>application.json</code></h3>
<ul>
<li>É o <strong>único ponto de configuração</strong> compartilhado entre Electron e API</li>
<li>Tanto o Electron (<code>main.ts</code>) quanto a API (<code>configManager.ts</code>) leem este arquivo</li>
<li>Ao salvar configurações pela UI, o Electron atualiza o arquivo <strong>e</strong> notifica a API via HTTP (<code>/internal/config/update</code>)</li>
<li>Em produção, o arquivo fica na pasta do instalador, NÃO dentro do ASAR</li>
</ul>
<h3><img src="http://insoft-docker1:4567/assets/plugins/nodebb-plugin-emoji/emoji/android/26a0.png?v=8k80dgruung" class="not-responsive emoji emoji-android emoji--warning" title=":warning:" alt="⚠" />️ Mensagens i18n</h3>
<ul>
<li>Nunca usar strings literais de erro — sempre usar <code>MSG.NOME_DA_CONSTANTE</code></li>
<li>Ao adicionar nova mensagem: adicionar em <code>message-codes.json</code>, <code>en-US.json</code> E <code>pt-BR.json</code></li>
<li>Executar <code>npm run validate:i18n</code> para verificar consistência</li>
</ul>
<h3><img src="http://insoft-docker1:4567/assets/plugins/nodebb-plugin-emoji/emoji/android/26a0.png?v=8k80dgruung" class="not-responsive emoji emoji-android emoji--warning" title=":warning:" alt="⚠" />️ Gerenciamento de janela</h3>
<ul>
<li>A função <code>bringWindowToFront()</code> usa sequência específica para garantir que a janela apareça acima de outros aplicativos no Windows</li>
<li>O <code>setTimeout(180ms)</code> é intencional para estabilizar o foco após <code>setAlwaysOnTop</code></li>
</ul>
<h3><img src="http://insoft-docker1:4567/assets/plugins/nodebb-plugin-emoji/emoji/android/26a0.png?v=8k80dgruung" class="not-responsive emoji emoji-android emoji--warning" title=":warning:" alt="⚠" />️ Build e empacotamento</h3>
<ul>
<li>O <code>electron-builder.json</code> define que o instalador <strong>exige privilégios de Administrador</strong> (<code>requireAdministrator</code>)</li>
<li>A API <code>.exe</code> é copiada para <code>build-api/</code> antes do build do Electron</li>
<li>O NSSM é incluído para <strong>ambas as arquiteturas</strong> (win32/win64) e selecionado automaticamente</li>
</ul>
<h2>Portas utilizadas pelo sistema</h2>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Porta</th>
<th>Protocolo</th>
<th>Serviço</th>
<th>Configurável?</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>3333</code></td>
<td>HTTP</td>
<td>API REST principal</td>
<td>Sim (<code>serverPort</code> no config)</td>
</tr>
<tr>
<td><code>3133</code></td>
<td>HTTP/WebSocket</td>
<td><a href="http://Socket.IO" rel="nofollow ugc">Socket.IO</a> (eventos em tempo real)</td>
<td>Não (fixo no código)</td>
</tr>
<tr>
<td><code>12120</code></td>
<td>TCP</td>
<td>Dispositivo QFace</td>
<td>Sim (<code>devicePort</code> no config)</td>
</tr>
<tr>
<td><code>4443</code></td>
<td>HTTPS</td>
<td>API REST (modo SSL)</td>
<td>Não (fixo, fallback)</td>
</tr>
</tbody>
</table>
<h2>Estrutura do <code>application.json</code> (referência completa)</h2>
<pre><code class="language-json">{
  "deviceIp": "172.16.110.6",       // IP do dispositivo QFace
  "devicePort": 12120,               // Porta TCP do dispositivo
  "asciiMode": false,                // Protocolo binário (false) ou ASCII (true)
  "apiKey": "&lt;uuid&gt;",                // Chave de autenticação da API REST
  "useSsl": false,                   // Habilitar HTTPS na API
  "certFiles": null,                 // Caminho dos arquivos de certificado SSL
  "useCertificate": false,           // Usar certificado SSL customizado
  "backgroundMode": true,            // API roda em segundo plano
  "saveTemplates": true,             // Salvar templates em disco
  "saveImages": true,                // Salvar imagens em disco
  "serverIp": "localhost",           // IP de escuta da API REST
  "serverPort": 3333,                // Porta HTTP da API REST
  "theme": "dark",                   // Tema da UI: "dark" | "light"
  "qfaceCapture": true,              // Habilitar captura via câmera QFace
  "externalApiEnabled": false,       // Enviar templates para API externa
  "externalApiUrl": "",              // URL da API externa
  "externalApiUser": "",             // Usuário da API externa
  "externalApiPassword": "",         // Senha da API externa
  "apiEndpoints": "[]",              // Endpoints customizados (JSON)
  "payloadTemplate": "...",          // Template do payload de saída
  "backupRegistersDays": 7           // Dias de retenção de registros
}
</code></pre>
<hr />
<p dir="auto"><em>Documentação gerada em Abril de 2026 — Insoft4 Informática LTDA</em></p>
]]></description><link>http://insoft-docker1:4567/topic/502/documentação-técnica-app-api-rest-parte-2</link><generator>RSS for Node</generator><lastBuildDate>Sat, 06 Jun 2026 00:40:04 GMT</lastBuildDate><atom:link href="http://insoft-docker1:4567/topic/502.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 22 May 2026 14:35:54 GMT</pubDate><ttl>60</ttl></channel></rss>