# 🦷 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=__DEFINIR_NO_.secrets__ # NÃO commitar valor real (fora do git) DB_NAME=dental_images REDIS_HOST=10.99.0.3 REDIS_PORT=6379 REDIS_PASSWORD=__DEFINIR_NO_.secrets__ # NÃO commitar valor real 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 ` 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 | ===================================================================