# 🦷 GUIA DE IMPLANTAÇÃO E ARQUITETURA - RX.SCOREODONTO.COM
===================================================================
Última atualização: 27/05/2026

## 📦 Versões Atuais

| Componente             | Versão   | Localização                              |
|------------------------|----------|------------------------------------------|
| Server (dental-server) | v2.0.0   | VPS 1 (prod) / VPS 4 (staging)           |
| Client Windows         | v1.1.0   | C:\ProgramData\RF\dental-client\          |
| Node.js (runtime)      | 22 LTS   | Docker - node:22-alpine                  |
| PostgreSQL             | 18       | VPS 3 (10.99.0.3:5432)                   |
| DragonflyDB (Redis)    | latest   | VPS 3 (10.99.0.3:6379)                   |

As versões são exibidas visualmente:
- **Servidor Web**: Badge no rodapé da sidebar → "Server v2.0.0"
- **Client Windows**: Badge no cabeçalho da janela de configuração → "Client v1.1.0"

---

## 🌍 Estrutura do Ecossistema e IPs

| VPS | IP VPN      | Papel                        | Acesso SSH          |
|-----|-------------|------------------------------|---------------------|
| 1   | 10.99.0.1   | Produção (Traefik + App)     | `ssh 10.99.0.1`     |
| 3   | 10.99.0.3   | Banco de dados + Gitea       | (sem acesso direto) |
| 4   | 10.99.0.4   | Dev / Staging / Build        | `ssh 10.99.0.04`    |

### ⚠️ Diretórios CRÍTICOS — NÃO TOCAR

**VPS 1 (Produção):**
- `/home/deploy/stack/traefik/` — Roteador de borda (proxy reverso)
- `/home/deploy/stack/portainer/` — Gerenciamento de containers
- `/home/deploy/stack/soc/` — CrowdSec / firewall de segurança

**VPS 4 (Laboratório):**
- `/home/deploy/stack/webhook-listener/` — Pipeline CI/CD (porta 9000)
- `/home/deploy/stack/scoreodonto.com/` — Staging do ScoreOdonto
- `/home/deploy/stack/subdominio.clube67.com/` — Subdomínio manager
- `/home/deploy/stack/self-healing/` — Auto-recuperação de serviços

---

## 📁 Organização de Pastas Locais (Seu Computador)

`C:\ProgramData\RF\`

| Pasta              | Descrição                                                          |
|--------------------|--------------------------------------------------------------------|
| `dental-server/`   | **Fonte principal do servidor** (Node.js/Express). Usar para edições. |
| `dental-client/`   | **Fonte do client desktop** (Electron). Compilar daqui.            |
| `deploy.ps1`       | **Script de deploy** — sincroniza notebook → VPS 4 → VPS 1.       |
| `docs-client/`     | Documentação do client.                                            |

> ✅ `vps-server-src/` foi **apagada** em 26/05/2026 (versão legada MySQL/SQLite, substituída).

---

## 🔄 Fluxo de Deploy — Script Automático (RECOMENDADO)

> ✅ **Use sempre o `deploy.ps1`.** Não é necessário entrar na VPS manualmente.
> Fazer `docker compose restart` ou `docker compose down` na VPS 1 MANUALMENTE
> **DERRUBA sessões ativas de todos os clientes conectados.** NUNCA faça isso.

### ⚡ Comando rápido (uso diário):

Abra PowerShell em `C:\ProgramData\RF\` e execute:

```powershell
# Deploy completo (tudo)
.\deploy.ps1

# Com mensagem de commit direta
.\deploy.ps1 -msg "feat: nova funcionalidade X"

# Só o frontend (HTML/CSS/JS da pasta public/)
.\deploy.ps1 -soPublic -msg "fix: corrigir botao sair"

# Só o backend (server.js, routes/, auth.js, etc)
.\deploy.ps1 -soServidor -msg "fix: corrigir query SQL"
```

### Como funciona internamente o pipeline:

```
[Edição local dental-server/ no notebook]
        ↓
[.\deploy.ps1  ← roda no notebook]
        ↓
[SCP: copia arquivos alterados para VPS 4]
        ↓
[git add -A + commit + push na VPS 4]
        ↓
[Gitea (VPS 3) recebe o push no branch main]
        ↓
[Webhook Global → http://10.99.0.4:9000/webhook]
        ↓
[webhook-listener (VPS 4) identifica o repositório]
        ↓
[Executa /home/deploy/stack/rx.scoreodonto.com/deploy-prod.sh]
        ↓
[Git pull executado apenas localmente na VPS 4]
        ↓
[Rsync transfere arquivos limpos (sem .git) para a VPS 1]
        ↓
[Script SSH entra na VPS 1 e apenas dá build/up --no-deps]
        ↓
[Container atualizado SEM DOWNTIME — sessões preservadas]
        ↓
[Gitea marca o commit como ✅ success]
```

### Acompanhar deploy em tempo real:
```bash
ssh 10.99.0.04 "tail -f /home/deploy/stack/webhook-listener/deploy.log"
```

---

## 🔧 Comandos Úteis — Apenas Para Emergências

> Use apenas quando o pipeline automático falhar ou para diagnóstico.

### VPS 4 (Dev/Staging):
```bash
ssh 10.99.0.04
cd /home/deploy/stack/rx.scoreodonto.com

# Ver logs do container
docker logs -f rx_scoreodonto_app

# Rebuild e restart (staging apenas)
docker compose up -d --build

# Status do webhook listener
systemctl status webhook-listener

# Log do CI/CD
tail -50 /home/deploy/stack/webhook-listener/deploy.log
```

### VPS 1 (Produção) — CUIDADO:
```bash
ssh 10.99.0.1
# SEMPRE prefixar com DOCKER_HOST em todos os comandos docker:
export DOCKER_HOST=unix:///run/user/1000/docker.sock

# Ver logs (ok fazer)
docker logs -f rx_scoreodonto_app

# ⚠️ Rebuild manual (apenas se o pipeline automático falhar)
# Isso causa breve downtime — avise antes
# NUNCA USE GIT PULL AQUI (sem chaves na VPS 1).
# Se precisar forçar, entre na VPS 4 e execute o script de deploy:
# ssh 10.99.0.04
# /home/deploy/stack/rx.scoreodonto.com/deploy-prod.sh
```

---

## ⚙️ Variáveis de Ambiente do Servidor

Configuradas no `docker-compose.yml` (sem `.env` em produção):

```env
PORT=3000
NODE_ENV=production
DB_TYPE=postgres
DB_HOST=10.99.0.3
DB_PORT=5432
DB_USER=clube67
DB_PASSWORD=clube67_db_pass_9903
DB_NAME=dental_images
REDIS_HOST=10.99.0.3
REDIS_PORT=6379
REDIS_PASSWORD=clube67_db_pass_9903
UPLOAD_DIR=/app/uploads
PROCESSED_DIR=/app/processed
```

> ⚠️ **PENDENTE**: Adicionar `JWT_SECRET` fixo no docker-compose.yml para que tokens
> sobrevivam a restarts. Atualmente usa o valor padrão hardcoded em `auth.js`.

---

## 💻 Compilação do Client Windows (Electron)

### Pré-requisitos:
- Node.js 18+ instalado na máquina local
- Executar `npm install` na primeira vez

### Compilar instalador `.exe`:
```powershell
cd C:\ProgramData\RF\dental-client

# Instalar dependências (só na primeira vez ou após mudança no package.json)
npm install

# Gerar instalador Windows (.exe via NSIS)
npm run dist
```

O instalador será gerado em:
```
C:\ProgramData\RF\dental-client\dist\ScoreOdonto Dental Client Setup 1.1.0.exe
```

### Testar sem compilar (modo dev):
```powershell
cd C:\ProgramData\RF\dental-client
npm start
```

### Configurações do build (`package.json`):
- **appId**: `com.scoreodonto.dentalclient`
- **productName**: `ScoreOdonto Dental Client`
- **Installer**: NSIS one-click, instalação para todos os usuários
- **Atalhos**: Área de trabalho + Menu Iniciar
- **Ícone**: `favicon.png`

---

## 🔑 Autenticação e Tokens

### Fluxo do Administrador (Painel Web):
1. Login em `/login` com usuário/senha do servidor
2. JWT gerado e salvo no `localStorage` (chave `token`)
3. Todas as chamadas API enviam `Authorization: Bearer <token>`
4. Rota `/admin-clinics.html` → requer `is_admin = true` no JWT

### Fluxo do Client Desktop (ScoreOdonto Dental Client):
1. Admin acessa o painel web em **Gerenciar Clínicas** (`/admin-clinics.html`)
2. Clica em **+ Nova Clínica** e preenche: Nome da Clínica, Email, Senha, Nome do PC
3. Sistema gera um `machine_token` (UUID) exibido na tela após salvar — **copie imediatamente**
4. No Client Windows: abra Configurações → cole o token no campo **🔑 Token do Servidor**
5. O client usa esse token para autenticar via Socket.IO no servidor

---

## 🏗️ Arquitetura do Webhook CI/CD (Técnica)

```
Gitea (VPS 3:3000)
  └── System Webhook Global (hook ID: 10)
        URL: http://10.99.0.4:9000/webhook
        Token: gitea_webhook_secret_clube67_58e4a92c3d18
        Evento: push (branch *)

webhook-listener (VPS 4, systemd service)
  └── /home/deploy/stack/webhook-listener/listener.js
        Porta: 9000 (bind: 10.99.0.4)
        Roteamento por repositório:
          rx.scoreodonto.com → deploy-prod.sh
          clube67            → deploy-prod-builder.sh

deploy-prod.sh (VPS 4, executado por repositório)
  └── /home/deploy/stack/rx.scoreodonto.com/deploy-prod.sh
        Local (VPS 4):
          git fetch origin main && git reset --hard
          rsync -avz --exclude '.git' para VPS 1
        SSH → VPS 1:
          docker compose build app
          docker compose up -d --no-deps app  ← sem derrubar sessões
```

---

## ✨ Histórico de Atualizações

| Data       | Versão | O que mudou                                                                     |
|------------|--------|---------------------------------------------------------------------------------|
| 27/05/2026 | v2.0.0 | **Segurança Zero-Trust**: deploy refeito via rsync, remoção de git pull na VPS 1 e alteração de URL para HTTP no `.git/config` para evitar rate-limit e loop SSH na porta 22 |
| 26/05/2026 | v2.0.0 | **Script `deploy.ps1`**: deploy em um comando, notebook → VPS 4 → VPS 1 automático |
| 26/05/2026 | v2.0.0 | **Apagada `vps-server-src/`** (legado MySQL/SQLite, não usada)                 |
| 26/05/2026 | v2.0.0 | Fix `admin-clinics.js`: redirect para login se sem token + verificar Content-Type antes de parsear JSON |
| 26/05/2026 | v2.0.0 | **Pipeline CI/CD corrigido**: token configurado no Webhook Global, listener atualizado com roteamento por repositório, deploy-prod.sh sem downtime |
| 26/05/2026 | v2.0.0 | Correção auth admin-clinics (req.session → req.user JWT), fix erro JSON 500    |
| 26/05/2026 | v2.0.0 | Restauração da UI (modal RX, sidebar dropdown), badge de versão em todos os painéis |
| 25/05/2026 | v2.0.0 | Botão Sair no sidebar, link Gerenciar Clínicas no menu lateral                  |
| 25/05/2026 | v2.0.0 | Correção PostgreSQL GROUP BY no endpoint `/api/images/patients`                 |
| 25/05/2026 | v2.0.0 | Migração SQLite/MySQL → PostgreSQL 18 + DragonflyDB na VPS 3                   |
| 25/05/2026 | v1.1.0 | Client: painel de configuração com token de máquina e autenticação JWT          |

===================================================================
