Files
NoIdle/ESPECIFICACAO_CLIENTE_WINDOWS.md
root 6086c13be7 feat: Implementação completa do NoIdle - Cliente, Backend e Scripts
- Cliente Windows com modo silencioso e auto-start robusto
- Backend Node.js + API REST
- Frontend Next.js + Dashboard
- Scripts PowerShell de configuração e diagnóstico
- Documentação completa
- Build scripts para Windows e Linux
- Solução de auto-start após reinicialização

Resolução do problema: Cliente não voltava ativo após reboot
Solução: Registro do Windows + Task Scheduler + Modo silencioso
2025-11-16 22:56:35 +00:00

266 lines
6.5 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Especificação Completa - Cliente Windows NoIdle
## 📋 Visão Geral
O cliente Windows deve monitorar e enviar para o servidor:
1. **Aplicativos ativos** (window_title, application_name)
2. **Histórico de navegação** (URLs do Chrome/Edge)
3. **Eventos de sessão** (logon/logoff do Windows)
---
## 🔌 Endpoints da API
### Base URL
```
https://admin.noidle.tech
```
---
## 1⃣ Registrar Atividade (Aplicativos)
**Endpoint:** `POST /api/activity/log`
**Frequência:** A cada 5-10 segundos (quando há mudança de aplicativo/janela)
**Headers:**
```
Content-Type: application/json
```
**Body:**
```json
{
"device_id": "DEV-1762999424206-0BJR2Q",
"window_title": "Documento - Word",
"application_name": "WINWORD.EXE",
"idle_time_seconds": 0,
"urls": [
{
"url": "https://example.com/page",
"title": "Example Page",
"browser": "Chrome"
}
]
}
```
**Campos Obrigatórios:**
- `device_id` (string): ID único do dispositivo
- `window_title` (string): Título da janela ativa (NÃO pode ser "System Idle" ou vazio)
- `application_name` (string): Nome do executável (ex: "chrome.exe", "WINWORD.EXE", "notepad.exe")
- `idle_time_seconds` (number): Tempo em segundos que o usuário está inativo (0 = ativo)
**Campos Opcionais:**
- `urls` (array): Array de objetos com histórico de navegação (ver seção 2)
**⚠️ IMPORTANTE:**
- **NÃO** envie `window_title = "System Idle"` ou `application_name = "[IDLE]"` quando o usuário está realmente usando um aplicativo
- Se o usuário estiver inativo por mais de 30 segundos, aí sim pode enviar `idle_time_seconds > 0`
- Capture o título real da janela e o executável real usando APIs do Windows
**Exemplo de Resposta:**
```json
{
"success": true,
"message": "Atividade registrada"
}
```
---
## 2⃣ Histórico de Navegação (Chrome/Edge)
**Endpoint:** `POST /api/activity/log` (mesmo endpoint, campo `urls`)
**Frequência:** A cada vez que uma nova URL é visitada no navegador
**Como Capturar:**
- Use a API do Chrome/Edge para monitorar abas abertas
- Capture URLs de todas as abas ativas
- Envie no array `urls` dentro do mesmo POST de atividade
**Estrutura do Array `urls`:**
```json
{
"urls": [
{
"url": "https://www.google.com/search?q=exemplo",
"title": "exemplo - Pesquisa Google",
"browser": "Chrome"
},
{
"url": "https://github.com/user/repo",
"title": "user/repo · GitHub",
"browser": "Chrome"
}
]
}
```
**Campos:**
- `url` (string): URL completa visitada
- `title` (string): Título da página/aba
- `browser` (string): "Chrome" ou "Edge"
**⚠️ IMPORTANTE:**
- Envie URLs de TODAS as abas abertas, não apenas a ativa
- Atualize a lista sempre que uma nova aba for aberta ou fechada
- Não envie URLs vazias ou inválidas
---
## 3⃣ Eventos de Sessão (Logon/Logoff)
**Endpoint:** `POST /api/activity/session`
**Frequência:** Imediatamente quando ocorre logon ou logoff
**Headers:**
```
Content-Type: application/json
```
**Body para LOGON:**
```json
{
"device_id": "DEV-1762999424206-0BJR2Q",
"event_type": "logon",
"username": "Sergio.Dev"
}
```
**Body para LOGOFF:**
```json
{
"device_id": "DEV-1762999424206-0BJR2Q",
"event_type": "logoff",
"username": "Sergio.Dev"
}
```
**Campos Obrigatórios:**
- `device_id` (string): ID único do dispositivo
- `event_type` (string): "logon" ou "logoff"
- `username` (string): Nome do usuário do Windows
**Como Capturar:**
- Use eventos do Windows: `SessionSwitch`, `SessionLock`, `SessionUnlock`
- Monitore o evento de logon do sistema operacional
- Capture o username do usuário logado
**Exemplo de Resposta:**
```json
{
"success": true,
"message": "Evento logon registrado"
}
```
---
## 4⃣ Heartbeat (Opcional mas Recomendado)
**Endpoint:** `POST /api/devices/heartbeat`
**Frequência:** A cada 30-60 segundos
**Body:**
```json
{
"device_id": "DEV-1762999424206-0BJR2Q"
}
```
**Nota:** O heartbeat é opcional se você estiver enviando atividades regularmente, mas ajuda a manter o dispositivo marcado como ativo.
---
## 🔧 Implementação Técnica
### Capturar Window Title e Application Name (C#/PowerShell)
```csharp
using System;
using System.Runtime.InteropServices;
using System.Text;
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
// Obter janela ativa
IntPtr hwnd = GetForegroundWindow();
StringBuilder windowTitle = new StringBuilder(256);
GetWindowText(hwnd, windowTitle, 256);
// Obter processo
uint processId;
GetWindowThreadProcessId(hwnd, out processId);
Process process = Process.GetProcessById((int)processId);
string appName = process.ProcessName + ".exe";
```
### Capturar URLs do Chrome (PowerShell)
```powershell
# Usar Chrome DevTools Protocol ou ler histórico do Chrome
# Alternativa: usar extensão do Chrome que envia dados via API local
```
### Capturar Eventos de Sessão (C#)
```csharp
using Microsoft.Win32;
SystemEvents.SessionSwitch += (sender, e) => {
if (e.Reason == SessionSwitchReason.SessionLock) {
// Logoff ou bloqueio
} else if (e.Reason == SessionSwitchReason.SessionUnlock) {
// Logon ou desbloqueio
}
};
```
---
## ✅ Checklist de Implementação
- [ ] Cliente captura `window_title` real (não "System Idle")
- [ ] Cliente captura `application_name` real (exe do processo)
- [ ] Cliente envia atividades a cada 5-10 segundos quando há mudança
- [ ] Cliente monitora e envia URLs do Chrome/Edge
- [ ] Cliente detecta eventos de logon/logoff do Windows
- [ ] Cliente envia eventos de sessão imediatamente
- [ ] Cliente trata erros de rede e faz retry
- [ ] Cliente valida dados antes de enviar
---
## 🐛 Troubleshooting
### Problema: Apenas "System Idle" aparece nas atividades
**Solução:** Verifique se o código está capturando a janela ativa corretamente. Use `GetForegroundWindow()` e não confie em valores padrão.
### Problema: URLs não aparecem
**Solução:** Verifique se o array `urls` está sendo enviado no POST `/api/activity/log` e se contém dados válidos.
### Problema: Eventos de sessão não aparecem
**Solução:** Verifique se o cliente está escutando eventos do Windows corretamente e se está fazendo POST para `/api/activity/session`.
---
## 📞 Suporte
Para problemas técnicos, verifique:
1. Logs do cliente (console/arquivo de log)
2. Logs do servidor: `pm2 logs pointcontrol-api`
3. Resposta HTTP dos endpoints (status code, mensagem de erro)