feat(rx): multi-tenant por clinica_id + página /clients de clientes ativos

- clinica_id (tenant do scoreodonto, clinicas.id) como eixo de isolamento em
  clinics_devices e images (+índices); clinic_name vira rótulo legível.
- Cadastro de device, socket (machine_token) e uploads (direct + legado) gravam clinica_id.
- Listagens (/images, /patients, /by-patient, /unique-clinics) filtram por clinica_id.
- /clients: lista clientes Windows ativos (inclui autenticados sem client-identify),
  tempo real + polling, exibe a clínica.
- send-image marcado como legado (client real usa Direct Upload).

Inclui trabalho de dev acumulado no working tree (não havia commits desde origin/main).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
VPS 4 Deploy Agent
2026-06-12 16:17:09 +02:00
parent d9182cff09
commit 31022c6a6f
55 changed files with 6773 additions and 1350 deletions
+77
View File
@@ -0,0 +1,77 @@
# Contexto de Desenvolvimento e Melhorias Estéticas
Este documento serve como um mapa do estado atual do projeto, detalhando as diretrizes arquiteturais, o ambiente de desenvolvimento, e o que foi feito na nossa refatoração premium. O objetivo é manter o contexto intacto para continuarmos os trabalhos amanhã de onde paramos.
---
## 1. Contexto de Deploy e Desenvolvimento
**Ambiente e Stack:**
- **Frontend:** Vite + React (rodando no container `rx_dev_client` na porta 5173).
- **Backend:** Node.js (Express) com Socket.io (rodando no container `rx_dev_api` na porta 3000).
- **Banco de Dados:** PostgreSQL (com proxies/cache via Redis/DragonflyDB).
- **Infraestrutura:** Docker Compose com persistência e mapeamento de portas (`network_mode: host` para desenvolvimento).
**Estabilidade e Otimizações Críticas Alcançadas:**
1. **Fim do Loop de WebSocket:** O backend estava travando em um loop infinito porque JWTs (que podiam conter hífens) estavam sendo tratados como UUIDs de `machine_token` no login do Socket, crachando o Postgres. A regra foi substituída por uma RegEx estrita de UUID, estabilizando a API e o proxy do Vite.
2. **Performance Extrema em `/patients`:** A listagem de pacientes executava múltiplas subqueries correlacionadas dentro de um `GROUP BY`, causando lentidão severa. A query foi reescrita utilizando **CTE (WITH)** e **LEFT JOIN LATERAL** do Postgres, reduzindo o tempo de resposta da rota de múltiplos segundos para cerca de **9 milissegundos**.
3. **Resolução de Quedas do WebSocket (O bug do "WebSocket is closed before the connection is established"):**
- **Diagnóstico:** O erro era causado pelo `React StrictMode` no ambiente de desenvolvimento, que executa o `useEffect` duas vezes (monta, desmonta e remonta quase instantaneamente). Na primeira montagem, a conexão do Socket.IO era iniciada, mas o cleanup imediato a desconectava antes do handshake finalizar, lançando o erro no proxy do Vite e sujando o console.
- **Correção no Código:** Implementamos um atraso inteligente (`setTimeout(150ms)`) na criação do socket dentro de `SocketContext.jsx`. Dessa forma, o ciclo rápido do StrictMode cancela o timer *antes* da conexão sequer iniciar, subindo apenas a segunda conexão de forma estável. Em Produção, isso garante um delay imperceptível sem impacto negativo.
- **Esclarecimento de Infraestrutura (Traefik):** O Traefik da VPS 1 lida com conexões WSS automaticamente por padrão. Falsas soluções, como forçar middlewares de injecção de cabeçalho (`Upgrade: websocket`) nas rotas do Traefik, são prejudiciais pois injetam esse header em *todas* as requisições HTTP estáticas (ex: `/favicon.ico` ou `/`), levando o Node/Express a rejeitá-las e causando erros `502 Bad Gateway` no ambiente de produção. As configurações do Traefik voltaram ao estado padrão, já que a solução de código no React eliminou o problema raiz.
---
## 2. Como as coisas estão sendo feitas (A Nova Diretriz)
A regra de ouro estabelecida para o UX/UI do projeto é:
> *"Esquece o sidebar (para aberturas dinâmicas), foque nas páginas. Vamos trocar modais empilhados por páginas dedicadas!"*
**Fluxo de Trabalho:**
- Nenhuma ação complexa (como criar um paciente ou detalhar uma GTO) deve acontecer em um Modal apertado.
- Tudo agora utiliza rotas reais do `react-router-dom` (ex: `/gtos/new`, `/patients/:id`), controladas pelo hook `useNavigate`.
- O código das listagens perdeu centenas de linhas inúteis e ficou puramente focado em listar, buscar e filtrar.
---
## 3. Estética Premium: Desktop vs Mobile
Estamos implementando uma estética "WOW" moderna, que transparece profissionalismo e luxo (vibrant colors, glassmorphism, micro-animações, sombras sutis).
### 💻 Para Desktop:
- **Telas Imersivas (Full-page):** Ao invés de um modal de 400px, a criação de itens abre uma página inteira. O formulário é apresentado dentro de um card central (`boxShadow: 0 4px 20px rgba(0,0,0,0.04)`) com inputs largos e bem espaçados.
- **Navegação "Breadcrumb":** Botões nativos estilizados com setas para voltar (`<I.arrowLeft />`) e cabeçalhos (`main-header`) limpos.
- **Tipografia e Cores:** O contraste foi ajustado para usar `var(--ink)` para títulos de peso 800 e `var(--muted)` para legendas, entregando uma hierarquia visual sofisticada.
- **Tabelas Interativas:** As linhas das tabelas agora possuem *hover states* sutis (`var(--surface-hover)`) e botões de ação ("Acessar", "Editar") visíveis sem poluir o grid.
### 📱 Para Mobile / Responsivo:
- **App-like Experience:** O mobile não é apenas uma versão espremida do desktop; ele possui componentes dedicados (`.mob-screen`, `MobileUI`).
- **Bottom Sheets & Drawers:** Ações rápidas de revisão abrem em "Bottom Sheets" (`.sheet-in`) que deslizam de baixo para cima, imitando a navegação nativa do iOS/Android.
- **Botões Flutuantes e Floating Actions:** Botões de criar novo (`+`) e pesquisar foram promovidos para o topo como botões estilo pílula (`.pill-btn.lg`), muito mais acessíveis para toques com os polegares.
- **Scroll Inteligente:** Listagens no mobile usam *Infinite Scroll* escondendo o overflow horizontal, garantindo que o usuário só mova a tela para cima e para baixo.
---
## 4. Onde Paramos e Próximos Passos (Para Amanhã)
**O que já está 100% migrado para a nova arquitetura de Páginas:**
**GTOs:** `/gtos`, `/gtos/new`, `/gtos/:id`
**Pacientes:** `/patients`, `/patients/new`, `/patients/:id`
**🎯 Foco para Amanhã (Acesso via API):**
1. **Sistema de Tokens / API:**
- Melhorar a estética do painel de integrações.
- Criar um card premium "Zapier CRM" ao lado do botão de gerar token.
- Criar o botão mágico **"Copiar Documentação Completa"** — que, após gerar o nome da integração, ativa e copia todas as APIs de uma vez (economizando tempo de implementação em outros sistemas).
2. **Endpoints e Sincronização:**
- Criar paciente via App Client Windows (comunicação externa).
- Enviar sinal de sincronização.
- Criar acessos / clínicas via API.
- Listar pacientes e seus RXs.
- Listar GTOs e detalhamentos.
- *Nota: Tudo isso será feito 100% via API documentada.*
3. **Continuação do UI (Desktop baseando-se no Mobile):**
- Iniciar o processo inverso: pegar a estética que deu certo no Mobile/Responsivo e trazer melhorias para a versão Desktop.
- **Primeiro alvo de UI:** A página **Galeria** (conforme solicitado anteriormente).
- Migrar as demais páginas restantes (ex: Configurações, Usuários) removendo completamente a dependência de Modais, seguindo o padrão de rotas limpas inaugurado hoje.