{"id":48814967,"url":"https://github.com/anamartinsr/agendamento_consultas_api","last_synced_at":"2026-04-14T10:34:29.227Z","repository":{"id":260521055,"uuid":"881401895","full_name":"anamartinsr/agendamento_consultas_api","owner":"anamartinsr","description":"API Rest com Node.js, Postgres, Prisma, Docker e Swagger. (Refatorando)","archived":false,"fork":false,"pushed_at":"2025-10-28T20:18:04.000Z","size":384,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-28T22:24:07.453Z","etag":null,"topics":["docker","husky","jwt","nodejs","postgresql","rest-api","swagger"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anamartinsr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-10-31T13:58:54.000Z","updated_at":"2025-10-28T20:18:08.000Z","dependencies_parsed_at":"2024-12-26T18:32:37.453Z","dependency_job_id":"bfebd4a9-84ed-40a8-bb50-cfe461bf7204","html_url":"https://github.com/anamartinsr/agendamento_consultas_api","commit_stats":null,"previous_names":["ribbeiroana/agendamento_consultas_api","anamartinsr/agendamento_consultas_api"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/anamartinsr/agendamento_consultas_api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anamartinsr%2Fagendamento_consultas_api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anamartinsr%2Fagendamento_consultas_api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anamartinsr%2Fagendamento_consultas_api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anamartinsr%2Fagendamento_consultas_api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anamartinsr","download_url":"https://codeload.github.com/anamartinsr/agendamento_consultas_api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anamartinsr%2Fagendamento_consultas_api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31793220,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T02:24:21.117Z","status":"ssl_error","status_checked_at":"2026-04-14T02:24:20.627Z","response_time":153,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","husky","jwt","nodejs","postgresql","rest-api","swagger"],"created_at":"2026-04-14T10:34:29.169Z","updated_at":"2026-04-14T10:34:29.221Z","avatar_url":"https://github.com/anamartinsr.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Refatoração da API de Agendamento de Consultas\n\n## Contexto\nA API foi desenvolvida em um momento inicial de aprendizado, utilizando Prisma, MongoDB, JWT, Nodemailer, Swagger, entre outras ferramentas.\nCom o crescimento do projeto e a necessidade de alinhar com boas práticas de mercado, foi identificada a necessidade de uma refatoração completa da arquitetura e stack, visando escalabilidade, segurança e manutenibilidade.\n\n---\n\n## Stack Atualizado\n- Backend: Node.js + Express\n- Banco de Dados: PostgreSQL + Prisma (ORM)\n- Autenticação: JWT (access + refresh tokens com rotação)\n- Criptografia: Argon2\n- Validação: Zod\n- Documentação: OpenAPI 3 + Swagger UI\n- Logs: Pino\n- Testes: Jest + Supertest\n- CI/CD: GitHub Actions + Husky + Lint-staged + Commitlint\n- Deploy: Docker + docker-compose (Nginx como proxy reverso em produção)\n- Segurança: Helmet, CORS configurado, express-rate-limit, cookies HttpOnly/Secure\n\n---\n## Ambiente Docker \n\nA API agora conta com um ambiente totalmente configurado para execução via Docker e Docker Compose, garantindo isolamento, portabilidade e fácil replicação em diferentes máquinas.\n\n---\n## Estrutura de Containers\n\n- backend → Container da aplicação Node.js\n  - Constrói a imagem a partir do Dockerfile\n  - Instala dependências, copia o código e executa npm start\n  - Porta exposta: 3000\n\n- postgres → Container do banco de dados PostgreSQL\n  - Baseado na imagem oficial postgres:16-alpine\n  - Configurado com variáveis de ambiente (DB_USER, DB_PASSWORD, DB_NAME)\n  - Armazena dados de forma persistente via volume Docker\n\n- Redes\n- O Compose cria duas redes:\n  - internal-network: comunicação segura entre containers\n  - external-network: usada para expor a aplicação externamente\n  - O banco de dados é acessível apenas internamente, evitando exposição pública.\n\n- Comandos\n\n Subir os containers em segundo plano\n```\ndocker compose up -d\n```\n\nVisualizar status dos serviços\n```\ndocker compose ps\n```\n\nVer logs da aplicação\n```\ndocker logs -f api_scheduling\n```\n\nRecriar após alterações\n```\ndocker compose down\ndocker compose up -d --build\n```\n\n## Atualização de Modelagem\n\nDurante a etapa de análise e modelagem, o esquema inicial foi **refatorado** após identificar inconsistências relacionadas ao armazenamento de documentos e à flexibilidade da agenda dos profissionais.\n\nAs principais mudanças foram:\n\n- **Remoção do campo de documento de identificação (CPF/RG)**, pois o envio físico ocorre presencialmente.\n- **Implementação de upload para documentos médicos**, como **exames, receitas e relatórios**.\n- **Substituição do campo `password` por `passwordHash`**, garantindo **criptografia de senhas**.\n- **Ajuste no controle de agenda**, permitindo:\n  - **dias fixos de atendimento** (agenda semanal padrão);\n  - **exceções de disponibilidade** (férias, ausência, bloqueio temporário).\n- **Manutenção do escopo para uma única clínica/hospital**, mas com estrutura flexível para expansão futura.\n\n---\n\n## Regras de Negócio\n\n### Usuário (Paciente)\n- Realiza o cadastro e pode atualizar seu perfil com dados básicos e médicos.\n- As senhas são **armazenadas de forma criptografada** (`passwordHash`).\n- Pode **agendar consultas presenciais** apenas em horários disponíveis.\n- Pode **enviar documentos médicos** (exames, receitas, relatórios) associados às consultas.\n- Pode **cancelar consultas** enquanto estiverem nos status `PENDING` ou `ACCEPTED`.\n- Visualiza:\n  - **Consultas futuras** (status diferente de `COMPLETED`)\n  - **Histórico de consultas concluídas**\n\n---\n\n### Profissional (Médico)\n- Possui uma **agenda fixa semanal** definida no banco (`Availability`).\n- Pode ter **exceções** de atendimento (`ScheduleException`), como:\n  - férias;\n  - afastamentos;\n  - bloqueios temporários.\n- Recebe solicitações de agendamento com status inicial `PENDING`.\n- Pode:\n  - **Aceitar** (`ACCEPTED`);\n  - **Recusar** (`REJECTED`);\n  - **Concluir** consultas (`COMPLETED`).\n- Todas as ações são registradas em **histórico de agendamentos** (`AppointmentHistory`).\n\n---\n\n### Agendamento de Consultas\n**Fluxo de criação:**\n1. O paciente seleciona o profissional e o horário desejado.  \n2. O sistema valida:\n   - se o profissional existe e está ativo;\n   - se o horário pertence à sua disponibilidade semanal;\n   - se não há **exceções de ausência**;\n   - se não existe outro agendamento no mesmo horário.\n3. Cria a consulta com status inicial `PENDING`.\n4. O profissional recebe a solicitação e pode **aceitar** ou **rejeitar**.\n\n**Atualizações:**\n- Mudanças de status (aceite, cancelamento, conclusão) geram um novo registro em `AppointmentHistory`, com:\n  - autor da ação (usuário ou profissional),\n  - status anterior e novo status,\n  - data e hora da alteração.\n\n---\n\n### Documentos Médicos\n- São armazenados em `MedicalDocument`, vinculados ao usuário e, opcionalmente, a uma consulta específica.\n- Cada documento possui:\n  - título;\n  - tipo (`EXAM`, `PRESCRIPTION`, `REPORT`);\n  - URL do arquivo;\n  - data de upload.\n- O backend armazena apenas o **link do arquivo**, não o binário, seguindo boas práticas de segurança e armazenamento em nuvem.\n\n---\n\n##  Segurança e Boas Práticas\n- **Senhas criptografadas**: nunca armazenadas em texto puro.  \n- **Controle de acesso baseado em papéis** (`ADMIN`, `USER`, `PROFESSIONAL`).  \n- **Histórico auditável**: toda mudança de status é registrada.  \n- **Uploads protegidos**: validação de formato e tamanho de arquivo.  \n- **Escalabilidade futura**: o modelo permite expansão para múltiplas clínicas sem grandes alterações estruturais.\n\n---\n\n##  Estrutura de Entidades\n\n| Entidade | Finalidade | Relações principais |\n|-----------|-------------|--------------------|\n| `User` | Todos os tipos de usuário (paciente, profissional, admin) | `Professional`, `Appointment`, `MedicalDocument` |\n| `Professional` | Dados e agenda do médico | `User`, `Specialty`, `Availability`, `ScheduleException` |\n| `Specialty` | Especialidades médicas | `Professional` |\n| `Availability` | Agenda fixa semanal | `Professional` |\n| `ScheduleException` | Períodos de ausência/férias | `Professional` |\n| `Appointment` | Consulta agendada | `User`, `Professional`, `AppointmentHistory` |\n| `AppointmentHistory` | Registro de ações e mudanças de status | `Appointment`, `User`, `Professional` |\n| `MedicalDocument` | Exames, receitas e relatórios digitais | `User`, `Appointment` |\n\n---\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanamartinsr%2Fagendamento_consultas_api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanamartinsr%2Fagendamento_consultas_api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanamartinsr%2Fagendamento_consultas_api/lists"}