Documentação Técnica

Sistema de Agendamento Médico - Prefeitura de Barueri

v1.0.0 Janeiro 2026

Introdução

Visão Geral do Sistema

O Command Agenda é uma plataforma completa de agendamento médico desenvolvida para o Núcleo de Inteligência em Saúde de Barueri (NIB). O sistema oferece uma solução integrada para gestão de consultas, permitindo que pacientes agendem atendimentos de forma autônoma enquanto administradores gerenciam toda a operação da unidade de saúde.

Portal Administrativo

Interface completa para gestão de médicos, especialidades, unidades e geração de grades de atendimento.

Portal do Paciente

Aplicação responsiva para agendamento de consultas, visualização de histórico e cancelamentos.

API RESTful

Backend serverless em Cloudflare Workers com alta disponibilidade e baixa latência.

Segurança RBAC

Controle de acesso baseado em papéis com 5 níveis de permissões hierárquicas.

Módulos do Sistema

Módulo Descrição Tecnologia Principal
Command-Agendamento-Api Backend RESTful com autenticação JWT e múltiplos bancos de dados Hono.js + Cloudflare Workers
Command-Agendamento-Adm Portal administrativo com gestão completa do sistema React + Vite + Tailwind CSS
Command-Agendamento-Paciente Portal do paciente para agendamentos e consultas React + Vite + Tailwind CSS

Arquitetura do Sistema

Arquitetura de Alto Nível

Camada de Apresentação

Portal Admin React + Vite
Portal Paciente React + Vite
HTTPS / REST API

Camada de Aplicação

API Gateway Hono.js Router
Auth Middleware JWT + RBAC
Business Routes 13 Módulos
SQL / Bindings

Camada de Dados

DB Principal Grades e Slots
DB Histórico Agendamentos
DB Usuários Auth e Pacientes
DB Parâmetros Configurações
Arquitetura Multi-Database

O sistema utiliza 4 bancos D1 (SQLite distribuído) separados por domínio de dados, permitindo isolamento lógico, escalabilidade independente e maior segurança através de segregação de responsabilidades.

Fluxo de Autenticação

1
Requisição de Login

Usuário envia credenciais (email/CPF + senha)

2
Validação de Credenciais

API verifica hash bcrypt no DB_USUARIOS

3
Geração do Token

JWT assinado com payload (userId, role, jti)

4
Registro de Sessão

Sessão gravada com JTI para revogação futura

5
Token no Cliente

Frontend armazena token em localStorage

Stack Tecnológico

Frontend

React

React 18

Biblioteca para construção de interfaces de usuário com componentes reutilizáveis

Vite

Vite

Build tool moderna com Hot Module Replacement e compilação otimizada

Tailwind

Tailwind CSS

Framework CSS utilitário para estilização rápida e consistente

Lucide

Lucide React

Biblioteca de ícones SVG otimizados para React

Backend

Hono

Hono.js

Framework web ultrarrápido para edge computing com suporte a middleware

Cloudflare

Cloudflare Workers

Plataforma serverless com execução em edge global

D1

Cloudflare D1

Banco de dados SQLite distribuído com replicação global

JWT + Bcrypt

Autenticação stateless com tokens seguros e senhas hasheadas

Modelo de Dados

Distribuição de Bancos de Dados

DB (Principal)

Dados operacionais de agendamento

  • ca_gradeagenda
  • ca_slotagenda
  • ca_consultorio
  • ca_regradistribuicao

DB_HISTORICO

Registros de agendamentos

  • ca_agendamento
  • ca_backlog
  • ca_log_auditoria

DB_USUARIOS

Autenticação e cadastros

  • ca_usuario_admin
  • ca_paciente
  • ca_medico
  • ca_sessao / ca_sessao_paciente
  • ca_medico_especialidade

DB_PARAMETROS

Configurações do sistema

  • ca_unidade
  • ca_especialidade
  • ca_tiposlot
  • ca_especialidade_cota

Dicionário de Dados - Entidades Principais

ca_medico

Campo Tipo Descrição
ca_medicoidINTEGER PKIdentificador único do médico
ca_nomecompletoTEXTNome completo do profissional
ca_crmTEXTRegistro no Conselho Regional de Medicina
ca_cpfTEXTCPF do médico (somente números)
ca_telefoneTEXTTelefone de contato
ca_unidadeidINTEGER FKUnidade de lotação principal
ca_limitevagasINTEGERLimite padrão de vagas por slot
ca_statusTEXTStatus: 'Ativo' ou 'Inativo'

ca_paciente

Campo Tipo Descrição
ca_pacienteidINTEGER PKIdentificador único do paciente
ca_nomecompletoTEXTNome completo do paciente
ca_cpfTEXT UNIQUECPF (usado como login)
ca_datanascimentoTEXTData de nascimento (ISO 8601)
ca_telefoneTEXTTelefone para contato
ca_emailTEXTE-mail do paciente
ca_senhahashTEXTHash bcrypt da senha
ca_statusTEXTStatus: 'Ativo' ou 'Inativo'
ca_tipoTEXTTipo: 'Comum', 'Prioritário'

ca_slotagenda

Campo Tipo Descrição
ca_slotagendaidINTEGER PKIdentificador único do slot
ca_gradeagendaidINTEGER FKReferência à grade de origem
ca_medicoidINTEGER FKMédico responsável (override)
ca_tiposlotidINTEGER FKTipo do slot (Consulta, Retorno, etc.)
ca_datainicioTEXTData/hora início (ISO 8601)
ca_datafimTEXTData/hora fim (ISO 8601)
ca_statusTEXT'Livre', 'Ocupado', 'Cancelado'
ca_limitevagasINTEGERMáximo de agendamentos neste slot
ca_periodoTEXT'Manhã', 'Tarde', 'Noite'

ca_agendamento

Campo Tipo Descrição
ca_agendamentoidINTEGER PKIdentificador único do agendamento
ca_slotagendaidINTEGER FKSlot agendado
ca_pacienteidINTEGER FKPaciente agendado
ca_protocoloTEXTCódigo único do agendamento
ca_ordemINTEGEROrdem de chegada no slot
ca_statusTEXT'Ativo', 'Cancelado', 'Realizado'
ca_datacriacaoTEXTData de criação do registro

Autenticação Administrativa

Processo de Login

O portal administrativo utiliza autenticação baseada em JWT (JSON Web Token) com as seguintes características:

Requisitos de Segurança

Senhas devem ter no mínimo 6 caracteres. O sistema utiliza hash bcrypt com salt automático para armazenamento seguro.

Campos do Formulário

Campo Obrigatório Descrição
E-mailSimE-mail cadastrado no sistema (case-insensitive)
SenhaSimSenha de acesso (mínimo 6 caracteres)

Resposta de Sucesso

{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "usuario": {
        "id": 1,
        "nome": "Administrador",
        "email": "admin@barueri.sp.gov.br",
        "cpf": "12345678901",
        "cargo": "Gestor de TI",
        "role": "administrador_master"
    }
}

Validade do Token

Por padrão, tokens JWT expiram em 8 horas. Após expiração, o usuário é automaticamente redirecionado para a tela de login.

Dashboard Administrativo

Visão Geral

O dashboard é a tela principal do sistema administrativo, oferecendo uma visão consolidada dos agendamentos através de um calendário interativo e filtros avançados.

Dashboard - Visão Geral do Calendário

Funcionalidades Principais

Calendário Interativo

Navegação por dias com visualização de slots disponíveis, ocupados e cancelados.

Filtros Avançados

Filtragem por médico, especialidade, unidade e tipo de slot.

Modal de Detalhes

Clique em um slot para ver detalhes, agendar pacientes ou cancelar horários.

Código de Cores

Identificação visual rápida do status e tipo de cada slot.

Legenda de Status

Livre Slot disponível para agendamento
Ocupado Todas as vagas preenchidas
Parcial Algumas vagas ainda disponíveis
Cancelado Slot não disponível

Configurações do Sistema

Abas de Configuração

O módulo de configurações permite o cadastro e manutenção de todas as entidades base do sistema. Acesso restrito a usuários com role administrador ou superior.

Médicos

Cadastro de profissionais com CRM, especialidades e limite de vagas.

Especialidades

Áreas médicas atendidas com configuração de cotas por tipo de slot.

Unidades

Clínicas, hospitais e postos de atendimento com endereço.

Tipos de Slot

Categorias de atendimento (Consulta, Retorno, Encaixe) com cores.

Grade de Agenda

Configuração de templates de horários por médico/especialidade.

Cadastro de Médicos

Campo Obrigatório Validação
Nome CompletoSimMínimo 3 caracteres
CRMNãoFormato livre
CPFNão11 dígitos numéricos
TelefoneNãoFormato (XX) XXXXX-XXXX
EspecialidadesSimMínimo 1 selecionada
UnidadeNãoUnidade de lotação
Limite de VagasNãoInteiro positivo (padrão: herda da especialidade)

Cadastro de Especialidades

Campo Obrigatório Descrição
NomeSimNome da especialidade (ex: Cardiologia)
Limite de VagasNãoVagas padrão por slot (default: 10)
Cotas por TipoNãoDistribuição percentual por tipo de slot

Gerador de Grade

Geração Automática de Slots

O Gerador de Grade permite criar múltiplos slots de atendimento automaticamente, baseado em parâmetros de data, horário e distribuição por tipo.

Distribuição Padrão

70% Consultas | 20% Retornos | 10% Encaixes - Configurável por especialidade.

Parâmetros de Geração

Parâmetro Obrigatório Descrição
MédicoSimProfissional para o qual serão gerados os slots
EspecialidadeSimEspecialidade do atendimento
UnidadeSimLocal de atendimento
ConsultórioSimSala específica na unidade
Data InícioSimPrimeiro dia da grade
Data FimSimÚltimo dia da grade
Hora InícioSimHorário de início do expediente
Hora FimSimHorário de término do expediente
Duração SlotSimTempo de cada atendimento (minutos)
Dias da SemanaSimDias em que haverá atendimento

Algoritmo de Geração

  1. Iteração por Datas

    Para cada dia no intervalo selecionado, verifica se é um dia da semana ativo.

  2. Cálculo de Slots

    Divide o período (hora início → hora fim) em intervalos de duração especificada.

  3. Distribuição por Tipo

    Aplica percentuais de distribuição para definir o tipo de cada slot.

  4. Verificação de Conflitos

    Verifica slots existentes para evitar sobreposição.

  5. Persistência em Lote

    Envia todos os slots válidos para API em uma única requisição bulk.

Gestão de Backlog

Fila de Espera

O Backlog é uma lista de pacientes aguardando agendamento, útil para gestão de demanda reprimida e priorização de atendimentos.

Campos do Backlog

Campo Descrição
PacienteReferência ao cadastro do paciente
EspecialidadeEspecialidade médica desejada
PrioridadeAlta, Média ou Baixa
Detalhes da DemandaObservações sobre a necessidade do paciente
Data de CriaçãoQuando o paciente entrou na fila

Priorização

Alta

Pacientes com urgência médica ou casos prioritários.

Média

Demanda regular, sem urgência especial.

Baixa

Consultas de rotina ou acompanhamento.

Gestão de Usuários

Administração de Contas

O módulo de usuários permite criar, editar e desativar contas de acesso ao sistema administrativo. Funcionalidade restrita ao role administrador_master.

Campos do Usuário

Campo Obrigatório Descrição
NomeSimNome completo do usuário
E-mailSimE-mail único para login
CPFNãoCPF do usuário
CargoNãoCargo ou função
RoleSimNível de acesso no sistema
SenhaSim (criação)Mínimo 6 caracteres
StatusSimAtivo ou Inativo

Controle de Acesso (RBAC)

Role-Based Access Control

O sistema implementa controle de acesso baseado em papéis (RBAC) com hierarquia de 5 níveis. Cada nível herda todas as permissões dos níveis inferiores.

Hierarquia de Roles

5
administrador_master

Acesso total: gestão de usuários, logs de auditoria, configurações de sistema.

4
administrador

Gestão de unidades, médicos, especialidades, consultórios, tipos de slot, backlog.

3
gerenciador

Criação e edição de grades, geração de slots em lote.

2
operador

Criação, edição e cancelamento de agendamentos individuais.

1
visualizador

Visualização do dashboard, agendamentos e slots (somente leitura).

Matriz de Permissões

Permissão Nível Mínimo Descrição
view_dashboard1 (visualizador)Ver dashboard e calendário
view_agendamentos1 (visualizador)Ver lista de agendamentos
view_slots1 (visualizador)Ver detalhes de slots
create_agendamento2 (operador)Criar novo agendamento
cancel_agendamento2 (operador)Cancelar agendamento
edit_agendamento2 (operador)Editar agendamento existente
create_grade3 (gerenciador)Criar grade de agenda
generate_slots3 (gerenciador)Gerar slots em lote
manage_medicos4 (administrador)CRUD de médicos
manage_especialidades4 (administrador)CRUD de especialidades
manage_unidades4 (administrador)CRUD de unidades
manage_users5 (admin_master)Gestão de usuários do sistema
view_audit_logs5 (admin_master)Ver logs de auditoria

Portal do Paciente - Cadastro e Login

Primeiro Acesso

Pacientes que ainda não possuem cadastro podem criar uma conta diretamente no portal, informando seus dados pessoais e criando uma senha de acesso.

Campos do Cadastro

Campo Obrigatório Validação
Nome CompletoSimMínimo 3 caracteres
CPFSim11 dígitos, validação algoritmo RF
Data de NascimentoNãoFormato DD/MM/AAAA
TelefoneNãoFormato (XX) XXXXX-XXXX
E-mailNãoFormato válido de e-mail
SenhaSimMínimo 6 caracteres
Confirmar SenhaSimDeve coincidir com a senha
Validação de CPF

O sistema implementa validação completa do CPF utilizando o algoritmo oficial da Receita Federal, incluindo verificação dos dígitos verificadores.

Login

Pacientes já cadastrados acessam o sistema informando CPF e senha. O CPF pode ser digitado com ou sem formatação.

Campos do Login

Campo Descrição
CPFCPF cadastrado (com ou sem pontuação)
SenhaSenha definida no cadastro

Token de Paciente

Após login bem-sucedido, o sistema emite um JWT com validade de 24 horas, armazenado em localStorage sob a chave paciente_token.

Portal do Paciente - Agendamento

Fluxo de Agendamento

O paciente pode agendar consultas em horários disponíveis, filtrando por especialidade, médico e data desejada.

1
Selecionar Especialidade

Escolha a área médica desejada

2
Filtrar Médico (opcional)

Escolha um profissional específico

3
Selecionar Data

Navegue pelo calendário de disponibilidade

4
Escolher Horário

Selecione um slot disponível

5
Confirmar Agendamento

Revise e confirme sua consulta

Informações do Agendamento

Após confirmação, o paciente recebe:

  • Protocolo único do agendamento
  • Data e horário confirmados
  • Nome do médico e especialidade
  • Unidade e endereço de atendimento
  • Ordem de chegada (em caso de múltiplas vagas)

Portal do Paciente - Histórico

Meus Agendamentos

A tela principal do portal do paciente exibe todos os agendamentos, organizados por status e data.

Status dos Agendamentos

Agendado Consulta confirmada e aguardando realização
Realizado Consulta já foi realizada
Cancelado Agendamento foi cancelado

Cancelamento

Pacientes podem cancelar agendamentos ativos diretamente pelo portal. A vaga é liberada automaticamente para outros pacientes.

Atenção

Recomenda-se cancelar com antecedência mínima de 24 horas para permitir que outros pacientes possam agendar.

API - Autenticação

Endpoints de Autenticação

POST /api/auth/login

Autenticação de usuários administrativos.

Request Body
{
    "email": "admin@exemplo.com",
    "senha": "suaSenhaSegura"
}
Response (200)
{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "usuario": {
        "id": 1,
        "nome": "Administrador",
        "email": "admin@exemplo.com",
        "role": "administrador"
    }
}
POST /api/auth/paciente/login

Autenticação de pacientes por CPF.

Request Body
{
    "cpf": "12345678901",
    "senha": "suaSenhaSegura"
}
Response (200)
{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "paciente": {
        "id": 1,
        "nome": "João da Silva",
        "cpf": "12345678901",
        "email": "joao@email.com"
    }
}
POST /api/auth/paciente/register

Cadastro de novos pacientes.

Request Body
{
    "nomeCompleto": "João da Silva",
    "cpf": "12345678901",
    "senha": "suaSenhaSegura",
    "email": "joao@email.com",
    "telefone": "11999998888",
    "dataNascimento": "1990-01-15"
}

Uso do Token

Todas as requisições protegidas devem incluir o token no header Authorization:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

API - Endpoints

Recursos Disponíveis

Slots

Método Endpoint Descrição Auth
GET/api/slotsLista todos os slotsAdmin
GET/api/slots/disponiveisLista slots disponíveis para agendamentoAdmin/Paciente
GET/api/slots/:idObtém detalhes de um slotAdmin
POST/api/slotsCria um novo slotAdmin (gerenciador+)
POST/api/slots/bulkCria múltiplos slotsAdmin (gerenciador+)
PUT/api/slots/:idAtualiza um slotAdmin (gerenciador+)
DELETE/api/slots/:idRemove um slotAdmin (gerenciador+)

Agendamentos

Método Endpoint Descrição Auth
GET/api/agendamentosLista todos os agendamentosAdmin
GET/api/agendamentos/meusLista agendamentos do paciente logadoPaciente
GET/api/agendamentos/:idObtém detalhes de um agendamentoAdmin/Paciente
POST/api/agendamentosCria um novo agendamentoAdmin/Paciente
DELETE/api/agendamentos/:idCancela um agendamentoAdmin/Paciente

Médicos

Método Endpoint Descrição Auth
GET/api/medicosLista todos os médicosAdmin/Paciente
GET/api/medicos/:idObtém detalhes de um médicoAdmin
POST/api/medicosCadastra um novo médicoAdmin (administrador+)
PUT/api/medicos/:idAtualiza um médicoAdmin (administrador+)
DELETE/api/medicos/:idRemove um médicoAdmin (administrador+)

Especialidades

Método Endpoint Descrição Auth
GET/api/especialidadesLista todas as especialidadesAdmin/Paciente
GET/api/especialidades/:idObtém detalhes de uma especialidadeAdmin
POST/api/especialidadesCadastra uma nova especialidadeAdmin (administrador+)
PUT/api/especialidades/:idAtualiza uma especialidadeAdmin (administrador+)
DELETE/api/especialidades/:idRemove uma especialidadeAdmin (administrador+)

Unidades

Método Endpoint Descrição Auth
GET/api/unidadesLista todas as unidadesAdmin/Paciente
GET/api/unidades/:idObtém detalhes de uma unidadeAdmin
POST/api/unidadesCadastra uma nova unidadeAdmin (administrador+)
PUT/api/unidades/:idAtualiza uma unidadeAdmin (administrador+)
DELETE/api/unidades/:idRemove uma unidadeAdmin (administrador+)

Pacientes

Método Endpoint Descrição Auth
GET/api/pacientesLista pacientes (com busca)Admin
GET/api/pacientes/:idObtém detalhes de um pacienteAdmin
POST/api/pacientesCadastra um novo pacienteAdmin
PUT/api/pacientes/:idAtualiza um pacienteAdmin

API - Tratamento de Erros

Códigos de Status HTTP

Código Significado Descrição
200OKRequisição bem-sucedida
201CreatedRecurso criado com sucesso
204No ContentExclusão bem-sucedida
400Bad RequestDados inválidos na requisição
401UnauthorizedToken ausente ou inválido
403ForbiddenSem permissão para o recurso
404Not FoundRecurso não encontrado
409ConflictConflito (ex: CPF já cadastrado)
500Internal Server ErrorErro interno do servidor

Formato de Resposta de Erro

{
    "error": "Descrição do erro",
    "details": "Detalhes técnicos (quando disponível)",
    "status": 400
}

Erros Comuns

Erro Causa Solução
Token não fornecidoHeader Authorization ausenteIncluir token no header
Sessão revogadaUsuário fez logout ou token foi invalidadoFazer novo login
Acesso negadoRole insuficiente para a operaçãoContatar administrador
CPF já cadastradoTentativa de cadastro duplicadoUsar CPF diferente ou fazer login
CPF inválidoCPF não passa na validação da RFVerificar digitação do CPF

Diagrama de Componentes

Arquitetura de Componentes

┌─────────────────────────────────────────────────────────────────────────────┐
│                           COMMAND AGENDA SYSTEM                              │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  ┌──────────────────────────┐     ┌──────────────────────────┐             │
│  │    FRONTEND ADMIN        │     │   FRONTEND PACIENTE      │             │
│  │  ┌────────────────────┐  │     │  ┌────────────────────┐  │             │
│  │  │   React + Vite     │  │     │  │   React + Vite     │  │             │
│  │  │   Tailwind CSS     │  │     │  │   Tailwind CSS     │  │             │
│  │  └────────────────────┘  │     │  └────────────────────┘  │             │
│  │  ┌────────────────────┐  │     │  ┌────────────────────┐  │             │
│  │  │ Services Layer     │  │     │  │ Services Layer     │  │             │
│  │  │ - authService      │  │     │  │ - authAPI          │  │             │
│  │  │ - slotsService     │  │     │  │ - slotsAPI         │  │             │
│  │  │ - medicosService   │  │     │  │ - agendamentosAPI  │  │             │
│  │  │ - agendamentos...  │  │     │  └────────────────────┘  │             │
│  │  └────────────────────┘  │     │                          │             │
│  └──────────────────────────┘     └──────────────────────────┘             │
│               │                              │                              │
│               │         HTTPS/REST           │                              │
│               └──────────────┬───────────────┘                              │
│                              ▼                                              │
│  ┌──────────────────────────────────────────────────────────────────────┐  │
│  │                        API GATEWAY (Hono.js)                          │  │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  │  │
│  │  │    CORS     │  │ Auth Admin  │  │ Auth Pacien │  │    RBAC     │  │  │
│  │  │ Middleware  │  │ Middleware  │  │ Middleware  │  │ Middleware  │  │  │
│  │  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘  │  │
│  ├──────────────────────────────────────────────────────────────────────┤  │
│  │                          BUSINESS ROUTES                              │  │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐        │  │
│  │  │  auth   │ │  slots  │ │agendamen│ │ medicos │ │pacientes│        │  │
│  │  └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘        │  │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐        │  │
│  │  │especiali│ │unidades │ │consultor│ │tiposSlot│ │ backlog │        │  │
│  │  └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘        │  │
│  │  ┌─────────┐ ┌─────────┐                                             │  │
│  │  │  grade  │ │usuarios │                                             │  │
│  │  └─────────┘ └─────────┘                                             │  │
│  └──────────────────────────────────────────────────────────────────────┘  │
│                              │                                              │
│                              │  SQL Queries                                 │
│                              ▼                                              │
│  ┌──────────────────────────────────────────────────────────────────────┐  │
│  │                     CLOUDFLARE D1 DATABASES                           │  │
│  │  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │  │
│  │  │      DB      │ │ DB_HISTORICO │ │ DB_USUARIOS  │ │DB_PARAMETROS │ │  │
│  │  │   Principal  │ │              │ │              │ │              │ │  │
│  │  │ ─────────────│ │ ─────────────│ │ ─────────────│ │ ─────────────│ │  │
│  │  │ gradeagenda  │ │ agendamento  │ │usuario_admin │ │  unidade     │ │  │
│  │  │ slotagenda   │ │ backlog      │ │ paciente     │ │especialidade │ │  │
│  │  │ consultorio  │ │ log_auditoria│ │ medico       │ │ tiposlot     │ │  │
│  │  │ regradistrib │ │              │ │ sessao       │ │              │ │  │
│  │  └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │  │
│  └──────────────────────────────────────────────────────────────────────┘  │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘
                    

Diagramas de Sequência

Fluxo de Login (Administrador)

┌────────┐          ┌────────┐          ┌────────┐          ┌────────────┐
│Frontend│          │API Gtwy│          │auth.js │          │ DB_USUARIOS│
└───┬────┘          └───┬────┘          └───┬────┘          └─────┬──────┘
    │                   │                   │                     │
    │ POST /auth/login  │                   │                     │
    │ {email, senha}    │                   │                     │
    │──────────────────>│                   │                     │
    │                   │                   │                     │
    │                   │ handleLogin()     │                     │
    │                   │──────────────────>│                     │
    │                   │                   │                     │
    │                   │                   │ SELECT usuario      │
    │                   │                   │ WHERE email = ?     │
    │                   │                   │────────────────────>│
    │                   │                   │                     │
    │                   │                   │     usuario         │
    │                   │                   │<────────────────────│
    │                   │                   │                     │
    │                   │                   │ verifyPassword()    │
    │                   │                   │─────────┐           │
    │                   │                   │         │ bcrypt    │
    │                   │                   │<────────┘           │
    │                   │                   │                     │
    │                   │                   │ generateToken()     │
    │                   │                   │─────────┐           │
    │                   │                   │         │ JWT       │
    │                   │                   │<────────┘           │
    │                   │                   │                     │
    │                   │                   │ INSERT sessao       │
    │                   │                   │────────────────────>│
    │                   │                   │                     │
    │                   │   {token, user}   │                     │
    │                   │<──────────────────│                     │
    │                   │                   │                     │
    │  200 {token,user} │                   │                     │
    │<──────────────────│                   │                     │
    │                   │                   │                     │
    │ localStorage.set  │                   │                     │
    │ ('auth_token')    │                   │                     │
    │                   │                   │                     │
                    

Fluxo de Agendamento (Paciente)

┌────────┐      ┌────────┐      ┌──────────┐      ┌────────┐      ┌──────────┐
│Paciente│      │Frontend│      │API Gateway│      │agendame│      │Databases │
└───┬────┘      └───┬────┘      └────┬─────┘      └───┬────┘      └────┬─────┘
    │               │                │                │                │
    │ Clicar        │                │                │                │
    │ "Agendar"     │                │                │                │
    │──────────────>│                │                │                │
    │               │                │                │                │
    │               │ GET /slots/    │                │                │
    │               │ disponiveis    │                │                │
    │               │───────────────>│                │                │
    │               │                │                │                │
    │               │                │ authMiddleware │                │
    │               │                │ Paciente       │                │
    │               │                │────────┐       │                │
    │               │                │        │       │                │
    │               │                │<───────┘       │                │
    │               │                │                │                │
    │               │                │ Query slots +  │                │
    │               │                │ grades + tipos │                │
    │               │                │───────────────────────────────>│
    │               │                │                │                │
    │               │  200 [slots]   │                │                │
    │               │<───────────────│                │                │
    │               │                │                │                │
    │  Exibir slots │                │                │                │
    │  disponíveis  │                │                │                │
    │<──────────────│                │                │                │
    │               │                │                │                │
    │ Selecionar    │                │                │                │
    │ horário       │                │                │                │
    │──────────────>│                │                │                │
    │               │                │                │                │
    │               │ POST /agendame │                │                │
    │               │ {slotId,       │                │                │
    │               │  pacienteId}   │                │                │
    │               │───────────────>│                │                │
    │               │                │                │                │
    │               │                │ criar()        │                │
    │               │                │───────────────>│                │
    │               │                │                │                │
    │               │                │                │ INSERT agend.  │
    │               │                │                │───────────────>│
    │               │                │                │                │
    │               │                │                │ UPDATE slot    │
    │               │                │                │ (se limite)    │
    │               │                │                │───────────────>│
    │               │                │                │                │
    │               │                │  {agendamento, │                │
    │               │                │   protocolo}   │                │
    │               │                │<───────────────│                │
    │               │                │                │                │
    │               │  201 Created   │                │                │
    │               │<───────────────│                │                │
    │               │                │                │                │
    │  Confirmação  │                │                │                │
    │  + Protocolo  │                │                │                │
    │<──────────────│                │                │                │
    │               │                │                │                │
                    

Diagrama Entidade-Relacionamento

Modelo Relacional

┌─────────────────────────────────────────────────────────────────────────────────────┐
│                           DIAGRAMA ENTIDADE-RELACIONAMENTO                          │
└─────────────────────────────────────────────────────────────────────────────────────┘

                                    ┌─────────────────┐
                                    │   ca_unidade    │
                                    ├─────────────────┤
                                    │ PK unidadeid    │
                                    │    nome         │
                                    │    tipo         │
                                    │    endereco     │
                                    │    status       │
                                    └────────┬────────┘
                                             │
                    ┌────────────────────────┼────────────────────────┐
                    │ 1                      │ 1                      │ 1
                    ▼                        ▼                        ▼
           ┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
           │  ca_consultorio │     │   ca_medico     │     │ ca_gradeagenda  │
           ├─────────────────┤     ├─────────────────┤     ├─────────────────┤
           │ PK consultorioid│     │ PK medicoid     │     │ PK gradeagendaid│
           │ FK unidadeid    │     │    nomecompleto │     │ FK medicoid     │
           │    nome         │     │    crm          │     │ FK especialidaid│
           └────────┬────────┘     │    cpf          │     │ FK unidadeid    │
                    │              │    telefone     │     │ FK consultorioid│
                    │              │ FK unidadeid    │     │    vigencia     │
                    │              │    limitevagas  │     │    limitevagas  │
                    │              │    status       │     │    status       │
                    │              └────────┬────────┘     └────────┬────────┘
                    │                       │                       │
                    │                       │ N                     │ 1
                    │                       ▼                       │
                    │          ┌────────────────────────┐           │
                    │          │ca_medico_especialidade │           │
                    │          ├────────────────────────┤           │
                    │          │ PK,FK medicoid         │           │
                    │          │ PK,FK especialidadeid  │           │
                    │          └────────────┬───────────┘           │
                    │                       │ N                     │
                    │                       ▼                       │
                    │              ┌─────────────────┐              │
                    │              │ca_especialidade │              │
                    │              ├─────────────────┤              │
                    │              │PK especialidaid │              │
                    │              │   nome          │◄─────────────┘
                    │              │   limitevagas   │
                    │              │   duracaopadrao │
                    │              └─────────────────┘
                    │
                    │              ┌─────────────────┐
                    │              │  ca_slotagenda  │
                    │              ├─────────────────┤
                    │              │ PK slotagendaid │
                    │              │ FK gradeagendaid│◄─────────────────────────────────┐
                    │              │ FK medicoid     │                                  │
                    └─────────────►│ FK tiposlotid   │◄────────┐                        │
                                   │    datainicio   │         │                        │
                                   │    datafim      │    ┌────┴────────┐     ┌────────┴────────┐
                                   │    status       │    │ ca_tiposlot │     │ ca_gradeagenda  │
                                   │    limitevagas  │    ├─────────────┤     │   (definido     │
                                   │    periodo      │    │PK tiposlotid│     │    acima)       │
                                   └────────┬────────┘    │   nome      │     └─────────────────┘
                                            │             │   canalorigem│
                                            │ 1           │   cor       │
                                            │             └─────────────┘
                                            ▼
                                   ┌─────────────────┐
                                   │ ca_agendamento  │
                                   ├─────────────────┤
                                   │PK agendamentoid │
                                   │FK slotagendaid  │
                                   │FK pacienteid    │──────────────┐
                                   │   protocolo     │              │
                                   │   ordem         │              │ N
                                   │   status        │              ▼
                                   │   datacriacao   │     ┌─────────────────┐
                                   └─────────────────┘     │  ca_paciente    │
                                                           ├─────────────────┤
                                                           │ PK pacienteid   │
                                                           │    nomecompleto │
                                                           │    cpf          │
                                                           │    datanascimen │
                                                           │    telefone     │
                                                           │    email        │
                                                           │    senhahash    │
                                                           │    status       │
                                                           │    tipo         │
                                                           └────────┬────────┘
                                                                    │
                                                                    │ 1
                                                                    ▼
                                                           ┌─────────────────────┐
                                                           │ca_sessao_paciente   │
                                                           ├─────────────────────┤
                                                           │ PK sessaoid         │
                                                           │ FK pacienteid       │
                                                           │    tokenjti         │
                                                           │    ipaddress        │
                                                           │    datacriacao      │
                                                           │    dataexpiracao    │
                                                           │    revogado         │
                                                           └─────────────────────┘


┌─────────────────────────────────────────────────────────────────────────────────────┐
│                                    LEGENDA                                           │
├─────────────────────────────────────────────────────────────────────────────────────┤
│  PK = Primary Key (Chave Primária)                                                  │
│  FK = Foreign Key (Chave Estrangeira)                                               │
│  ───► = Relacionamento (seta aponta para a tabela referenciada)                     │
│  1    = Cardinalidade "Um"                                                          │
│  N    = Cardinalidade "Muitos"                                                      │
└─────────────────────────────────────────────────────────────────────────────────────┘