Commit Graph

20 Commits

Author SHA1 Message Date
VPS 4 Builder d064aa9058 feat(contratos): sistema completo de contratos odontológicos
- Tabelas contratos e contrato_itens com migrações automáticas
- Endpoints CRUD com itens em transação
- ContratosView: listagem, filtro por status, cards, stats
- ContratoModal: wizard 3 abas (Dados/Itens/Cláusulas), catálogo de
  procedimentos, DnD para reordenar, financeiro completo, print A4
- Sidebar: novo item CONTRATOS
- App.tsx: nova rota /contratos com permissões dentista/funcionario
- PatientsView: botão CONTRATOS no menu financeiro

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 20:04:57 +02:00
VPS 4 Builder 15a8527f1c feat(pacientes): modais de receita, pedido de exame e edição em 4 páginas
- ReceitaModal: gerenciamento de modelos de receita por especialidade com
  drag-and-drop para reordenar medicamentos e preview de impressão
- PedidoExameModal: pedido de exames por catálogo (Raio-X / Tomografia /
  Outros) com DnD para ordenar, campos de região/observação por item e
  preview de impressão
- EditarPacienteModal: reformulado em 4 páginas (Dados / Família /
  Endereço / Histórico) com navegação anterior/próximo e modal 2xl
- Backend: tabelas modelos_receita, items_receita, pedidos_exame,
  items_pedido_exame criadas na migração; colunas de endereço adicionadas
  em pacientes; endpoints CRUD para receitas e pedidos de exame
- Integração: botões Receita e Raio-X no menu clínico agora abrem os
  novos modais reais em vez do placeholder

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 16:53:28 +02:00
VPS 4 Builder ee3f6c3bb2 feat(patients): fix date bug, convenio dropdown, redesign grupo familiar
- Fix dataNascimento date format error: convert dd/MM/yyyy → yyyy-MM-dd when
  loading EditarPacienteModal so <input type="date"> validates correctly
- Change convênio field from free text to dropdown populated from planos table
- Redesign grupo familiar: search a patient as family member instead of named
  group, with parentesco field (datalist with common options, accepts custom)
- GET /api/pacientes: proper camelCase aliases, LEFT JOINs for grupoFamiliarNome
  and indicadoPorNome, sort parameter support (az/za/convenio/recentes)
- Add startup migrations: ADD COLUMN IF NOT EXISTS for grupofamiliarid,
  grupofamiliarrelacao, indicadorporid on pacientes table
- savePaciente: preserve caller-supplied id instead of overwriting with Math.random
- Add grupoFamiliarRelacao to Paciente type

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 15:54:54 +02:00
VPS 4 Builder 6b67fbc26e fix(sync): truncate fields in import-legacy to match column VARCHAR limits
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 07:05:31 +02:00
VPS 4 Builder 6cf18c049f fix(sync): propagate real tab name in pushTableToSheet and pullTableFromSheet
Ensures values.update and values.get use the actual tab title returned by
ensureSheetTab (case-insensitive match) so writes don't fail when existing
Apps Script tabs have different casing than our expected names.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 06:46:30 +02:00
VPS 4 Builder 319c0dcedd fix(oauth): check googleCreds not process.env in URL guard
process.env is only set if env var exists; credentials saved via UI
live in googleCreds. Guard was blocking users who saved via DB.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 06:36:22 +02:00
VPS 4 Builder 263c98d74f feat(settings): Google OAuth credentials UI in Configurações
Backend:
- Load GOOGLE_CLIENT_ID/SECRET from DB at startup (env vars take priority)
- GET /api/settings/google-credentials → masked status (secret never returned)
- POST /api/settings/google-credentials → save to DB, hot-reload in memory
- /api/auth/google/url returns 503 with clear message when unconfigured

Frontend (ConfiguracoesView):
- OAuth credential inputs (Client ID + Client Secret with show/hide toggle)
- Shows configured status badge (ENV vs DB) and masked clientIdHint
- Instructions with redirect URI shown inline

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 05:56:00 +02:00
VPS 4 Builder fc891ab878 fix(oauth): set GOOGLE_REDIRECT_URI in docker-compose; guard missing credentials
- Add APP_URL and GOOGLE_REDIRECT_URI=https://scoreodonto.com/api/oauth2callback
  to docker-compose backend environment
- /api/auth/google/url returns 503 with clear message when CLIENT_ID/SECRET unset
- GoogleConnectButton shows alert instead of silently breaking on API error

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 05:52:33 +02:00
VPS 4 Builder 63962d51c1 feat(sync): Google Sheets bidirectional backup (PG ↔ Sheets)
Backend:
- Add SYNC_TABLES config (pacientes, agendamentos, financeiro, leads, guias)
- Add getSheetsClient(), ensureSheetTab(), pushTableToSheet(), pullTableFromSheet()
- Add schedulePush() debounced 5s auto-push after every write to main tables
- Add GET /api/sync/status, POST /api/sync/push, POST /api/sync/pull
- Update OAuth scope to include spreadsheets

Frontend:
- Redesign SyncView: per-table status grid, two-button operation (Backup/Restore),
  terminal log with color-coded lines, auto-backup info notice

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 05:44:52 +02:00
VPS 4 Builder 2f3c0420e3 feat(routing): switch from hash routing to HTML5 History API
Remove all window.location.hash assignments and hashchange events.
Navigate with history.pushState; listen on popstate. Fix base href to
'/' so assets resolve correctly on deep paths. Update magic link URL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 04:44:53 +02:00
VPS 4 Builder 435176c0c3 fix(backend): add camelCase response mapping for all GET endpoints
PG stores columns lowercase but frontend expects camelCase. Each GET endpoint
now maps the response to include camelCase aliases alongside the lowercase fields.

- agendamentos: dentistaId, pacienteNome, pacienteCelular
- dentistas: corAgenda
- procedimentos: especialidadeId, especialidadeNome, valorParticular, codigoInterno;
  fix valoresPlanos filter (v.procedimentoid) and map planoId, planoNome, codigoPlano
- guias: full camelCase map (dataSolicitacao, beneficiarioNome, tipoTratamento, etc.)
- gto-builder: map items (builderId, procedimentoId, codigoTUSS, valorTotal, etc.)
  and builder fields (pacienteId, dentistaId, credenciadaId)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 04:26:03 +02:00
VPS 4 Builder 38bbf36735 fix(backend): lowercase all column names in buildInsert/buildUpdate and explicit queries
All PostgreSQL columns are stored lowercase (PG folds unquoted identifiers).
The previous code quoted camelCase keys ("corAgenda", "builderId", etc.) which
caused column-not-found errors.

- buildInsert: k.toLowerCase() for all column names, no more double-quotes
- buildUpdate: k.toLowerCase() for SET clause and WHERE column
- dentistas/register: "corAgenda" → coragenda
- procedimentos PUT: "procedimentoId" → procedimentoid in DELETE
- gto_builders INSERT: "pacienteId"/"dentistaId"/"credenciadaId" → lowercase
- gto_items queries: "builderId" → builderid, "valorTotal" → valortotal
- guias: "dataSolicitacao"/"beneficiarioNome"/etc → lowercase with normalizedSort

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 04:18:29 +02:00
VPS 4 Builder e61ef6c0ca fix(backend): move procedimentos/reorder before /:id to prevent route shadowing
Express matches routes in registration order. PUT /procedimentos/:id was
registered before /procedimentos/reorder, causing 'reorder' to be captured
as an id param and the reorder endpoint to be unreachable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 23:20:39 +02:00
VPS 4 Builder a0ab095923 refactor(backend): migrate all queries to native PostgreSQL, remove MySQL shim
- Remove translateQuery function, pool.query override, and pool.getConnection mock entirely
- Replace all ? placeholders with $N positional parameters throughout
- Replace INSERT INTO t SET ? with buildInsert() helper across pacientes, dentistas, especialidades, planos, procedimentos, financeiro, leads, gto_items
- Replace UPDATE t SET ? WHERE id = ? with buildUpdate() helper across the same tables
- Replace all pool.getConnection()/beginTransaction/commit/rollback blocks with withTransaction()
- Convert ON DUPLICATE KEY UPDATE to ON CONFLICT DO UPDATE SET in dentistas/register (usuarios, vinculos, dentistas tables)
- Fix dentistas/register to use withTransaction instead of SET FOREIGN_KEY_CHECKS
- Fix all [rows] array destructuring to { rows } object destructuring (PG native result shape)
- Fix guias dynamic WHERE builder to use incrementing $N parameter indices
- Fix double-quoted string literal bug in procedimentos categoria query ("Particular" → 'Particular')
- Quote camelCase column names in gto_items/gto_builders queries ("builderId", "valorTotal", etc.)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 23:13:35 +02:00
VPS 4 Builder 1330147eaf fix: corrige inconsistências críticas de backend e navegação
- Backend: substitui string literals com aspas duplas por aspas simples
  nas queries PostgreSQL (settings, GTO builder, google_tokens delete)
- Backend: corrige alias SQL 'dentistanome' para 'dentistaNome' (quoted)
  e ajusta frontend para usar 'pacientenome' (lowercase do PG)
- Backend: move app.listen() para após todas as rotas registradas
- Backend: ativa generateIntelligentNotifications no startup + intervalo 5min
- Backend: magic link usa process.env.APP_URL em vez de localhost:3000 hardcoded
- Frontend: adiciona 'relatorios' às permissões do role 'funcionario'
- Frontend: adiciona onClick ao botão Relatórios do Dashboard
- Frontend: adiciona Content-Type e JWT token em salvarAgendamento/atualizarAgendamento
- Frontend: MeusTratamentos passa JWT token nas chamadas a /api/guias
- Frontend: ClinicasView passa JWT token no endpoint de atualização de cor
- Frontend: corrige subtítulo 'MYSQL + GOOGLE' para 'POSTGRESQL + GOOGLE'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:43:23 +02:00
VPS 4 Builder 0f71db2205 fix(backend): correct lowercase column names in dashboard stats query (datavencimento, dentistaid); fix notificacoes routes to use PG syntax; exclude base/ from .gitignore 2026-05-13 15:54:01 +02:00
VPS 4 Builder e260eed28b fix(backend): Convert legacy queries and add translate wrapper 2026-05-13 09:53:00 +02:00
Antigravity AI Agent 606da6de97 feat: migrate ScoreOdonto CRM to Docker, PostgreSQL, and DragonflyDB 2026-05-13 07:13:41 +02:00
Antigravity AI Agent 4917d03bdf chore: clean up codebase content, keeping only the environment and infrastructure configurations 2026-05-13 05:21:31 +02:00
Antigravity AI Agent 19dbbae8b8 chore: initial setup with PostgreSQL, DragonflyDB, and Nginx routing configs 2026-05-13 05:12:32 +02:00