Medical Research Skills for Claude Code, Codex, Cursor & Copilot
58 open-source skills for the full medical research lifecycle. Built by physicians, tested on real publications.
Plataforma de telemedicina: consulte médicos especialistas de qualquer lugar, com segurança e comodidade.
Translation pending
HealthJavaScript · TypeScriptGitHub @hugommeiraOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
Sistema completo de telemedicina com arquitetura modular, pronto para produção. bash npm install bash cp .env.example .env.local Preencher DATABASE_URL, NEXTAUTH_SECRET, ASAAS_API_KEY, etc.Read the full README ↗
Plataforma de telessaúde para acompanhamento médico do emagrecimento, com atendimento só por consulta agendada. TCC da Escola Técnica Pandiá Calógeras (Técnico de Informática, Equipe 6). Banca: 03/11/2026.
PROJETO-STATUS.md ·
roteiro da banca: docs/roteiro-demonstracao.md| Pessoa | Responsabilidade |
|---|---|
| Hugo Meira Maia | site (todo o repositório fora de mobile/), GitHub, Vercel, Neon e serviços; faz os merges na main |
| Julia | app Flutter (mobile/) |
Repositório: https://github.com/hugommeira/TCC-EMACRESCERE
.ics), entra na consulta por
vídeo, conversa por chat (durante a consulta e por 24 h depois), recebe
receita digital assinada e acompanha peso, IMC e outras medidas (cintura,
quadril, gordura corporal, massa magra) em gráficos./prescricao/{id}), sem login.mobile/): paciente e médico no celular. Android pelo
APK ou pela versão web; iPhone pela versão web do próprio app, instalada pelo
Safari. No app,
receita só é visualizada/baixada (emissão é pelo site), cartão de crédito
abre o site, e não há login com Google nem painel de administração.A plataforma não vende, não indica e não entrega medicamentos: toda conduta
é decisão do médico. A fila de atendimento imediato (on-demand) foi descartada
pelo grupo; o código ficou desligado em QUEUE_ENABLED (lib/constants.ts) e
kQueueEnabled (app).
| Camada | Tecnologia |
|---|---|
| Framework | Next.js 14 (App Router), React 18 |
| Linguagem | TypeScript (strict, exactOptionalPropertyTypes) |
| Estilos | TailwindCSS 3; 3D com three.js + @react-three/fiber/drei |
| ORM / banco | Prisma 5 + PostgreSQL (Neon, região sa-east-1) |
| Auth | NextAuth v5 (Auth.js): e-mail/senha, Google, Facebook* |
| Pagamentos | Asaas (sandbox) |
| Vídeo | LiveKit Cloud |
| Resend (modo sandbox) | |
| Tempo real | SSE + consulta periódica (ver Tempo real) |
| Testes | Vitest (site) e flutter test (app) |
| App | Flutter (mobile/) |
| Deploy | Vercel (região gru1), automático a cada push na main |
* O login com Facebook está pronto no código, mas sem credenciais da Meta (ver Autenticação).
TCC-EMACRESCERE/
├── app/ # Next.js App Router (rotas; NÃO é o aplicativo)
│ ├── api/ # Route handlers: admin, auth, avatar, chat, checkout,
│ │ # consultations, doctor(s), files, followup, health,
│ │ # livekit, measurements, medications, notifications,
│ │ # patient, prescription(s), profile, realtime, users,
│ │ # webhooks, weight (queue/ e dev/ existem, desligados)
│ ├── auth/ # login, cadastro (paciente e médico), esqueci/redefinir
│ │ # senha, erro, acesso negado
│ ├── consulta/[id]/ # sala da consulta (vídeo, chat, prontuário, peso, receita)
│ ├── dashboard/
│ │ ├── patient/ # início, agendar, consultas, peso e medidas, receitas, perfil
│ │ ├── doctor/ # início, consultas, receitas, certificado, perfil
│ │ └── admin/ # visão geral, médicos, usuários, consultas, pagamentos,
│ │ # receitas, certificados, auditoria
│ ├── prescricao/[id]/ # validação pública de receita
│ ├── privacidade/ termos/ # páginas legais
│ └── page.tsx # página inicial (seções em components/landing)
├── components/ # landing, auth, layout, patient, doctor, admin, consulta,
│ # weight, measures, profile, prescription, three (3D), ui...
├── hooks/ # useSSE, useChat, useConsultation, useAuth...
├── lib/ # auth (auth.ts + auth.config.ts), scheduling, bmi, measures,
│ # calendar, chat-access, realtime, s3 (arquivos), sign-pdf,
│ # prescription-pdf, security, audit, error-catalog,
│ # oauth-profile, redirect, validations/ (+ testes *.test.ts)
├── services/
│ ├── api/ # cliente tipado do front (consultation, payment, weight...)
│ └── external/ # Asaas, CFM (simulado), e-mail (Resend)
├── prisma/ # schema.prisma, seed.ts, seed-demo.ts, seed-test.ts, medicamentos
├── public/ # app.apk, app/ (build web do app), 3d/, photos/, QR codes
├── mobile/ # app Flutter (paciente + médico) — ver mobile/HANDOFF.md
├── docs/ # roteiro da banca, auditoria, catálogo de erros, front-end,
│ # planejamento, 3D, fotos
├── scripts/ # gerar-catalogo-erros.ts (gera docs/catalogo-erros.md)
├── types/ # tipos globais e extensão de tipos do NextAuth
├── art/3d-src/ # arquivos .blend dos modelos 3D
├── test/ # falhas/ (testes de queda e do catálogo) e stubs/
├── middleware.ts # protege rotas e restringe /dashboard/* por papel
└── vercel.json # build, ignoreCommand, região e headers do APK
Atenção: existe um único banco, e é o de produção. O
.env.localaponta para ele. Tudo o que você fizer rodando localmente (cadastros, pagamentos de teste, pesagens) aparece no site público. Teste que grava dado precisa desfazer o que gravou.
Pré-requisitos: Node.js 18.17 ou mais novo (recomendado 20) com npm; para o
app, Flutter com Dart 3.10 ou mais novo (mobile/pubspec.yaml).
npm install # também roda prisma generate
cp .env.example .env.local # preencher os valores (pedir ao Hugo)
npm run dev # http://localhost:3000
Nunca rode npm run build localmente. O script faz prisma db push e o
seed de demonstração no banco de produção (em produção isso é desejado; na sua
máquina, não). Também nunca use prisma db push --accept-data-loss.
Scripts do Prisma (leem o .env.local via dotenv-cli, então agem no banco
de produção): npm run prisma:studio, prisma:push, prisma:seed,
prisma:seed-demo. Num banco novo e vazio, a ordem é prisma:push →
prisma:seed → prisma:seed-demo.
O app não precisa de .env: por padrão ele fala com a API de produção.
cd mobile
flutter pub get
dart run tool/dev_web.dart # no navegador (sobe o app + proxy de API com CORS)
flutter run -d <device-id> # num Android físico (flutter devices lista)
flutter test # testes do app
Não use flutter run -d chrome direto (o navegador bloqueia o cookie de
sessão). Outro servidor: --dart-define=API_BASE_URL=.... Detalhes em
mobile/HANDOFF.md.
| Script | O que faz |
|---|---|
npm run dev | servidor local em :3000 (banco real) |
npm run build | só na Vercel: prisma generate + db push + seed demo + next build |
npm start | serve o build |
npm run lint / npm run typecheck | ESLint / tsc --noEmit |
npm test | Vitest (vitest run) |
npm run prisma:generate | gera o cliente Prisma |
npm run prisma:push / prisma:migrate | aplica o schema no banco (produção) |
npm run prisma:studio | abre o Prisma Studio (produção) |
npm run prisma:seed / prisma:seed-demo | seed inicial / dados de demonstração |
npx tsx scripts/gerar-catalogo-erros.ts | regera docs/catalogo-erros.md |
npx tsc --noEmit | grep -c "error TS" # 60 erros antigos (dívida): não pode subir
npx vitest run # 177 testes em 20 arquivos (24/10/2026)
npx eslint <arquivos alterados> # ou: npx next lint --dir components --dir app
cd mobile && flutter test # se mexeu no app
O build da Vercel ignora erros de TypeScript e de lint (ignoreBuildErrors em
next.config.mjs), por isso essa checagem manual é obrigatória.
NextAuth v5 com sessão JWT (30 dias). A senha fica com hash bcrypt e o papel
(PATIENT, DOCTOR, ADMIN) é revalidado no banco a cada 60 s. O login
aceita 5 tentativas a cada 15 min por e-mail (contador em memória: reiniciar o
servidor zera). O
callbackUrl do login só aceita caminhos internos do site.
.env.local: RESEND_API_KEY=re_... e
EMAIL_FROM="Emacrescere <[email protected]>".RESEND_API_KEY, o token
é gerado no banco, mas o e-mail não sai (só um aviso no log).O link vale 15 minutos e é de uso único.
Credencial "Aplicativo da Web" no Google Cloud (Google Auth Platform), com os redirecionamentos:
https://tcc-emacrescere.vercel.app/api/auth/callback/googlehttp://localhost:3000/api/auth/callback/googleVariáveis GOOGLE_CLIENT_ID e GOOGLE_CLIENT_SECRET (na Vercel, ambientes
Production e, desde 04/10/2026, Preview). Escopos: só openid, email e profile. Enquanto o app do
Google estiver em modo "Teste", só entram os e-mails cadastrados como usuários
de teste.
O código está pronto, mas falta a credencial: o cadastro de desenvolvedor na
Meta travou na verificação por SMS. Para ativar: app em
https://developers.facebook.com com o produto Facebook Login, redirecionamento
https://tcc-emacrescere.vercel.app/api/auth/callback/facebook e as variáveis
FACEBOOK_CLIENT_ID/FACEBOOK_CLIENT_SECRET. A Meta exige a URL de instruções
de exclusão de dados: https://tcc-emacrescere.vercel.app/privacidade#exclusao-de-dados.
avatarUrl (lib/oauth-profile.ts).Senha das contas de demonstração: Demo@12345. Elas são criadas por
prisma/seed-demo.ts, que roda em todo deploy de produção (é idempotente: só
cria o que falta) ou com npm run prisma:seed-demo.
| Perfil | Situação | |
|---|---|---|
| Paciente | [email protected] | 4 consultas (88,2 → 83,8 kg), receita emitida — a melhor para a banca |
| Paciente | [email protected] | 5 consultas (79,0 → 75,2 kg), receita emitida |
| Paciente | [email protected] | 3 consultas (104,5 → 101,0 kg), receita emitida |
| Paciente | [email protected] | 3 consultas (96,3 → 93,7 kg) |
| Paciente | [email protected] | 4 consultas (91,5 → 87,6 kg), receita emitida |
| Paciente | [email protected] | 4 consultas (112,0 → 106,1 kg), receita emitida |
| Paciente | [email protected] | 3 consultas (74,8 → 73,0 kg), receita de controle especial |
| Paciente | [email protected] | 2 consultas concluídas, receitas, retorno marcado |
| Paciente | [email protected] | concluída + cancelada + retorno marcado |
| Paciente | [email protected] | receita de controle especial |
| Paciente | [email protected] | concluída + faltou |
| Paciente | [email protected] | receita em rascunho |
| Paciente | [email protected] | consulta próxima |
| Médica | [email protected] | aprovada, com certificado de teste |
| Médico | [email protected] | aprovado, com certificado de teste |
| Médico | [email protected] | aguardando aprovação (CRM ativo) |
| Médica | [email protected] | aguardando aprovação (CRM suspenso) |
| Médico | [email protected] |
Contas do seed inicial (prisma/seed.ts): admin [email protected] /
Admin@12345, médico [email protected] / Doctor@12345, paciente
[email protected] / Patient@12345. O CPF da Maria (22222222222) é inválido e o
Asaas recusa a cobrança: para testar pagamento, use um paciente de demonstração.
Evite na demonstração o médico [email protected]: é uma conta de
teste de credenciamento que ficou aprovada no banco.
Certificado digital dos médicos de demonstração. No banco de produção, a
Dra. Fernanda e o Dr. Ricardo já têm um certificado de teste com arquivo
(gerado pela tela) e emitem receitas assinadas. Num banco novo, o seed cria só
os metadados do certificado; para emitir receita, o médico precisa gerar o
certificado de teste em Certificado digital (/dashboard/doctor/certificate).
O certificado de teste é autoassinado: a receita sai assinada, mas sem
validade jurídica (a página de validação e o PDF avisam isso).
Conta sandbox própria, com PAYMENT_MOCK=false em produção: Pix, boleto e
cartão geram cobranças reais de sandbox. A confirmação chega pelo webhook
/api/webhooks/asaas (token no header asaas-access-token). Para confirmar um
Pix/boleto, use o painel do Asaas Sandbox, ou ligue PAYMENT_MOCK=true na
Vercel (aparece o botão "Simular pagamento"). Consulta não paga segura o horário
por 30 minutos.
Política de cancelamento: reembolso integral cancelando com 24 h ou mais de antecedência; com menos de 24 h ou falta do paciente, sem reembolso; se o médico cancelar, sempre integral.
O deploy é automático: cada push na main publica o site (projeto
tcc-emacrescere, região gru1). Merge na main = site público mudado, então
só quando o dono do projeto pedir.
O build (npm run build, chamado pelo vercel.json) faz prisma generate,
prisma db push, o seed de demonstração e next build. Em prévias
(VERCEL_ENV=preview) ele pula o db push e o seed: prévia nunca altera o
banco.
O ignoreCommand do vercel.json decide se o build roda. A Vercel olha só o
último commit do push:
| Situação | Builda? |
|---|---|
Mensagem com [build] (qualquer branch) | sempre |
main, commit que muda algo fora de mobile/ | sim |
main, commit que toca só mobile/, ou commit vazio | não (use [build] para forçar um redeploy) |
Outra branch, mensagem com [preview] (inclusive commit vazio) | sim (prévia) |
Outra branch sem [preview] | não |
| Vercel sem o commit anterior (clone raso) | sim (o erro é sempre para o lado de construir) |
Consequências práticas:
main, deixe por último o merge que mexe no
site; se o último commit tocar só mobile/, a Vercel pula o deploy.[build] na main.tcc-emacrescere-git-<branch>-….vercel.app)
cadastrado nos redirecionamentos do Google; o endereço com código aleatório
muda a cada deploy e o Google recusa. Detalhes em docs/frontend-handoff.md.[preview] e depois para a
main, o status "sucesso" no GitHub pode ser o da prévia: confira o deploy
de Production antes de testar o site público.lib/realtime.ts publica eventos por pg LISTEN/NOTIFY e as rotas SSE
(app/api/realtime/*, app/api/chat/[roomToken]/stream) os entregam ao
navegador. Em produção (Neon serverless + Vercel), porém, o NOTIFY não chega
de forma confiável. Por isso a interface também consulta periodicamente: o
chat da sala a cada 5 s (30 s com a consulta encerrada), e o mesmo vale para o
status da consulta e o prontuário. Quando o SSE funciona, ele só acelera a
entrega.
lib/s3.ts usa um bucket S3 (Contabo) quando as variáveis S3_* estão
preenchidas; sem elas, guarda tudo no próprio banco (tabela stored_files),
com links de download assinados. Hoje o S3 não está configurado: os
arquivos ficam no banco. Preencher as S3_* muda o armazenamento sem mudar
código. Sem S3, a Vercel recusa uploads acima de ~4,5 MB; o site limita os
anexos a 4 MB (MAX_UPLOAD_BYTES em lib/constants.ts).
lib/error-catalog.ts (código, mensagem ao
usuário, ação sugerida). Servidor: new AppError("CODIGO") /
apiError("CODIGO") (lib/api-response.ts); site: apiFetch
(lib/api-client.ts); app: ApiError.from (mobile/lib/services/api_error.dart).docs/catalogo-erros.md é gerado pelo
script scripts/gerar-catalogo-erros.ts; o teste
test/falhas/catalogo.test.ts reprova se ele ficar desatualizado. A seção
"Problemas conhecidos" desse documento lista os defeitos registrados e ainda
não corrigidos./api/health: sem login mostra só o estado geral; o admin vê o card
"Saúde do sistema" no painel (banco testado na hora; serviços externos
conferidos pela configuração).test/falhas/.A seção do app na landing (/#app) é um único retângulo, "Nosso Aplicativo",
com as duas opções e o QR code real de cada uma (o QR some no celular, onde a
pessoa já está no aparelho):
/app/, que roda no Android
e no iPhone. Na web o PDF da receita não baixa (a receita é conferida pelo
link de validação do site); no APK, baixa.O QR aponta para https://tcc-emacrescere.vercel.app/app.apk (arquivo em
public/app.apk, build arm64 do app Flutter, ~35 MB). Para publicar uma versão
nova:
# dentro de mobile/ (o app vive neste repositório; não precisa de .env)
flutter build apk --release --split-per-abi
cp build/app/outputs/flutter-apk/app-arm64-v8a-release.apk ../public/app.apk
Commit + push e a Vercel serve o arquivo (headers em vercel.json). O SVG do
QR (public/qr-app.svg) só precisa ser gerado de novo se a URL do site mudar
(foi gerado com o pacote Dart qr, conteúdo = URL acima).
Não há app na App Store: no iPhone roda a versão web do próprio app (que também
funciona no Android), servida
pelo site em https://tcc-emacrescere.vercel.app/app/ (arquivos em
public/app/; build e cópia descritos em mobile/HANDOFF.md, seção "Versão web
(iPhone)").
Para instalar no iPhone:
tcc-emacrescere.vercel.app/app no Safari.No Android, pelo Chrome: menu ⋮ → Adicionar à tela inicial (ou
Instalar app, se aparecer; o public/app/manifest.json tem nome, ícones e
display: standalone).
O QR da versão web (public/qr-app-iphone.svg, conteúdo
https://tcc-emacrescere.vercel.app/app/) foi gerado sem acrescentar
dependência ao projeto, nas mesmas cores do QR do Android:
npx --yes [email protected] -t svg -d 0f3d2eff -l ffffffff -m 2 \
-o public/qr-app-iphone.svg "https://tcc-emacrescere.vercel.app/app/"
Também só precisa ser gerado de novo se a URL do site mudar.
Para atualizar o app web, é preciso gerar o build de novo (flutter build web)
e copiá-lo para public/app/; mudar só o código em mobile/ não muda o que
/app/ serve. Depois da atualização, o iPhone pode manter a versão antiga em
cache: teste numa aba privada ou apague os dados do site no Safari.
| Documento | Para quê |
|---|---|
PROJETO-STATUS.md | estado atual, pendências e histórico |
CLAUDE.md | regras e arquitetura para quem (pessoa ou Claude) vai mexer no código |
docs/roteiro-demonstracao.md | roteiro da banca |
docs/auditoria-seguranca.md | auditoria de segurança e LGPD |
docs/catalogo-erros.md | todos os códigos de erro e os problemas conhecidos (gerado) |
docs/planejamento-novas-implementacoes.md | planejamento e decisões (D1–D9) das últimas entregas |
docs/plano-de-testes.md | checklist completo de testes (site, app, celular) para os testadores |
mobile/PENDENCIAS-DO-SITE.md | o que já está no site e ainda falta no app |
docs/frontend-handoff.md · |
services/external/cfm.ts: final "000" = não
encontrado, "999" = suspenso). Integração real com o CFM fica para depois.QUEUE_ENABLED), não apagada.ignoreBuildErrors.robots.txt, sitemap.xml, imagem de Open Graph e monitoramento de erros.docs/auditoria-seguranca.md.docs/catalogo-erros.md.mobile/PENDENCIAS-DO-SITE.md).| reprovado |
docs/frontend-diagnostico.md| regras visuais e diagnóstico do front-end |
docs/3d/ · docs/fotos/ | modelos 3D e fotos do site |
mobile/HANDOFF.md · mobile/CLAUDE.md | app Flutter |
docs/contexto-claude-projeto.md | resumo autocontido para o conhecimento do projeto no claude.ai |