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
+50 -1
View File
@@ -12,13 +12,20 @@ import AdminClinicsPage from './pages/AdminClinicsPage';
import ResetPage from './pages/ResetPage';
import DownloadPage from './pages/DownloadPage';
import PatientsPage from './pages/PatientsPage';
import CreatePatientPage from './pages/CreatePatientPage';
import PatientDetailsPage from './pages/PatientDetailsPage';
import SettingsPage from './pages/SettingsPage';
import GtosPage from './pages/GtosPage';
import CreateGtoPage from './pages/CreateGtoPage';
import GtoDetailsPage from './pages/GtoDetailsPage';
import ImageDetailsPage from './pages/ImageDetailsPage';
import UsersPage from './pages/UsersPage';
import SyncPage from './pages/SyncPage';
import ApiDocsPage from './pages/ApiDocsPage';
export default function App() {
return (
<BrowserRouter>
<BrowserRouter future={{ v7_startTransition: true, v7_relativeSplatPath: true }}>
<AuthProvider>
<ToastProvider>
<SocketProvider>
@@ -53,6 +60,18 @@ export default function App() {
</AdminRoute>
} />
<Route path="/api-docs" element={
<AdminRoute>
<ApiDocsPage />
</AdminRoute>
} />
<Route path="/users" element={
<AdminRoute>
<UsersPage />
</AdminRoute>
} />
<Route path="/reset" element={
<AdminRoute>
<ResetPage />
@@ -71,6 +90,24 @@ export default function App() {
</ProtectedRoute>
} />
<Route path="/patients/new" element={
<ProtectedRoute>
<CreatePatientPage />
</ProtectedRoute>
} />
<Route path="/patients/:id" element={
<ProtectedRoute>
<PatientDetailsPage />
</ProtectedRoute>
} />
<Route path="/sync" element={
<ProtectedRoute>
<SyncPage />
</ProtectedRoute>
} />
<Route path="/settings" element={
<AdminRoute>
<SettingsPage />
@@ -83,6 +120,18 @@ export default function App() {
</ProtectedRoute>
} />
<Route path="/gtos/new" element={
<ProtectedRoute>
<CreateGtoPage />
</ProtectedRoute>
} />
<Route path="/gtos/:id" element={
<ProtectedRoute>
<GtoDetailsPage />
</ProtectedRoute>
} />
<Route path="/:patientName/:imageId" element={
<ProtectedRoute>
<ImageDetailsPage />