Medical Research Skills for Claude Code, Codex, Cursor & Copilot
58 個開源技能,涵蓋完整的醫學研究全生命週期。由醫師打造,於真實出版物上測試。
AI 翻譯
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
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.檢視完整 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 |