Documentação Técnica
Sistema de Agendamento Médico - Prefeitura de Barueri
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
Camada de Aplicação
Camada de Dados
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
Usuário envia credenciais (email/CPF + senha)
API verifica hash bcrypt no DB_USUARIOS
JWT assinado com payload (userId, role, jti)
Sessão gravada com JTI para revogação futura
Frontend armazena token em localStorage
Stack Tecnológico
Frontend
React 18
Biblioteca para construção de interfaces de usuário com componentes reutilizáveis
Vite
Build tool moderna com Hot Module Replacement e compilação otimizada
Tailwind CSS
Framework CSS utilitário para estilização rápida e consistente
Lucide React
Biblioteca de ícones SVG otimizados para React
Backend
Hono.js
Framework web ultrarrápido para edge computing com suporte a middleware
Cloudflare Workers
Plataforma serverless com execução em edge global
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_medicoid | INTEGER PK | Identificador único do médico |
| ca_nomecompleto | TEXT | Nome completo do profissional |
| ca_crm | TEXT | Registro no Conselho Regional de Medicina |
| ca_cpf | TEXT | CPF do médico (somente números) |
| ca_telefone | TEXT | Telefone de contato |
| ca_unidadeid | INTEGER FK | Unidade de lotação principal |
| ca_limitevagas | INTEGER | Limite padrão de vagas por slot |
| ca_status | TEXT | Status: 'Ativo' ou 'Inativo' |
ca_paciente
| Campo | Tipo | Descrição |
|---|---|---|
| ca_pacienteid | INTEGER PK | Identificador único do paciente |
| ca_nomecompleto | TEXT | Nome completo do paciente |
| ca_cpf | TEXT UNIQUE | CPF (usado como login) |
| ca_datanascimento | TEXT | Data de nascimento (ISO 8601) |
| ca_telefone | TEXT | Telefone para contato |
| ca_email | TEXT | E-mail do paciente |
| ca_senhahash | TEXT | Hash bcrypt da senha |
| ca_status | TEXT | Status: 'Ativo' ou 'Inativo' |
| ca_tipo | TEXT | Tipo: 'Comum', 'Prioritário' |
ca_slotagenda
| Campo | Tipo | Descrição |
|---|---|---|
| ca_slotagendaid | INTEGER PK | Identificador único do slot |
| ca_gradeagendaid | INTEGER FK | Referência à grade de origem |
| ca_medicoid | INTEGER FK | Médico responsável (override) |
| ca_tiposlotid | INTEGER FK | Tipo do slot (Consulta, Retorno, etc.) |
| ca_datainicio | TEXT | Data/hora início (ISO 8601) |
| ca_datafim | TEXT | Data/hora fim (ISO 8601) |
| ca_status | TEXT | 'Livre', 'Ocupado', 'Cancelado' |
| ca_limitevagas | INTEGER | Máximo de agendamentos neste slot |
| ca_periodo | TEXT | 'Manhã', 'Tarde', 'Noite' |
ca_agendamento
| Campo | Tipo | Descrição |
|---|---|---|
| ca_agendamentoid | INTEGER PK | Identificador único do agendamento |
| ca_slotagendaid | INTEGER FK | Slot agendado |
| ca_pacienteid | INTEGER FK | Paciente agendado |
| ca_protocolo | TEXT | Código único do agendamento |
| ca_ordem | INTEGER | Ordem de chegada no slot |
| ca_status | TEXT | 'Ativo', 'Cancelado', 'Realizado' |
| ca_datacriacao | TEXT | Data 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:
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 |
|---|---|---|
| Sim | E-mail cadastrado no sistema (case-insensitive) | |
| Senha | Sim | Senha 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.
Funcionalidades Principais
Navegação por dias com visualização de slots disponíveis, ocupados e cancelados.
Filtragem por médico, especialidade, unidade e tipo de slot.
Clique em um slot para ver detalhes, agendar pacientes ou cancelar horários.
Identificação visual rápida do status e tipo de cada slot.
Legenda de Status
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.
Cadastro de profissionais com CRM, especialidades e limite de vagas.
Áreas médicas atendidas com configuração de cotas por tipo de slot.
Clínicas, hospitais e postos de atendimento com endereço.
Categorias de atendimento (Consulta, Retorno, Encaixe) com cores.
Configuração de templates de horários por médico/especialidade.
Cadastro de Médicos
| Campo | Obrigatório | Validação |
|---|---|---|
| Nome Completo | Sim | Mínimo 3 caracteres |
| CRM | Não | Formato livre |
| CPF | Não | 11 dígitos numéricos |
| Telefone | Não | Formato (XX) XXXXX-XXXX |
| Especialidades | Sim | Mínimo 1 selecionada |
| Unidade | Não | Unidade de lotação |
| Limite de Vagas | Não | Inteiro positivo (padrão: herda da especialidade) |
Cadastro de Especialidades
| Campo | Obrigatório | Descrição |
|---|---|---|
| Nome | Sim | Nome da especialidade (ex: Cardiologia) |
| Limite de Vagas | Não | Vagas padrão por slot (default: 10) |
| Cotas por Tipo | Não | Distribuiçã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.
70% Consultas | 20% Retornos | 10% Encaixes - Configurável por especialidade.
Parâmetros de Geração
| Parâmetro | Obrigatório | Descrição |
|---|---|---|
| Médico | Sim | Profissional para o qual serão gerados os slots |
| Especialidade | Sim | Especialidade do atendimento |
| Unidade | Sim | Local de atendimento |
| Consultório | Sim | Sala específica na unidade |
| Data Início | Sim | Primeiro dia da grade |
| Data Fim | Sim | Último dia da grade |
| Hora Início | Sim | Horário de início do expediente |
| Hora Fim | Sim | Horário de término do expediente |
| Duração Slot | Sim | Tempo de cada atendimento (minutos) |
| Dias da Semana | Sim | Dias em que haverá atendimento |
Algoritmo de Geração
-
Iteração por Datas
Para cada dia no intervalo selecionado, verifica se é um dia da semana ativo.
-
Cálculo de Slots
Divide o período (hora início → hora fim) em intervalos de duração especificada.
-
Distribuição por Tipo
Aplica percentuais de distribuição para definir o tipo de cada slot.
-
Verificação de Conflitos
Verifica slots existentes para evitar sobreposição.
-
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 |
|---|---|
| Paciente | Referência ao cadastro do paciente |
| Especialidade | Especialidade médica desejada |
| Prioridade | Alta, Média ou Baixa |
| Detalhes da Demanda | Observações sobre a necessidade do paciente |
| Data de Criação | Quando o paciente entrou na fila |
Priorização
Pacientes com urgência médica ou casos prioritários.
Demanda regular, sem urgência especial.
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 |
|---|---|---|
| Nome | Sim | Nome completo do usuário |
| Sim | E-mail único para login | |
| CPF | Não | CPF do usuário |
| Cargo | Não | Cargo ou função |
| Role | Sim | Nível de acesso no sistema |
| Senha | Sim (criação) | Mínimo 6 caracteres |
| Status | Sim | Ativo 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
Acesso total: gestão de usuários, logs de auditoria, configurações de sistema.
Gestão de unidades, médicos, especialidades, consultórios, tipos de slot, backlog.
Criação e edição de grades, geração de slots em lote.
Criação, edição e cancelamento de agendamentos individuais.
Visualização do dashboard, agendamentos e slots (somente leitura).
Matriz de Permissões
| Permissão | Nível Mínimo | Descrição |
|---|---|---|
| view_dashboard | 1 (visualizador) | Ver dashboard e calendário |
| view_agendamentos | 1 (visualizador) | Ver lista de agendamentos |
| view_slots | 1 (visualizador) | Ver detalhes de slots |
| create_agendamento | 2 (operador) | Criar novo agendamento |
| cancel_agendamento | 2 (operador) | Cancelar agendamento |
| edit_agendamento | 2 (operador) | Editar agendamento existente |
| create_grade | 3 (gerenciador) | Criar grade de agenda |
| generate_slots | 3 (gerenciador) | Gerar slots em lote |
| manage_medicos | 4 (administrador) | CRUD de médicos |
| manage_especialidades | 4 (administrador) | CRUD de especialidades |
| manage_unidades | 4 (administrador) | CRUD de unidades |
| manage_users | 5 (admin_master) | Gestão de usuários do sistema |
| view_audit_logs | 5 (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 Completo | Sim | Mínimo 3 caracteres |
| CPF | Sim | 11 dígitos, validação algoritmo RF |
| Data de Nascimento | Não | Formato DD/MM/AAAA |
| Telefone | Não | Formato (XX) XXXXX-XXXX |
| Não | Formato válido de e-mail | |
| Senha | Sim | Mínimo 6 caracteres |
| Confirmar Senha | Sim | Deve coincidir com a senha |
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 |
|---|---|
| CPF | CPF cadastrado (com ou sem pontuação) |
| Senha | Senha 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.
Escolha a área médica desejada
Escolha um profissional específico
Navegue pelo calendário de disponibilidade
Selecione um slot disponível
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
Cancelamento
Pacientes podem cancelar agendamentos ativos diretamente pelo portal. A vaga é liberada automaticamente para outros pacientes.
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
/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"
}
}
/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"
}
}
/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/slots | Lista todos os slots | Admin |
| GET | /api/slots/disponiveis | Lista slots disponíveis para agendamento | Admin/Paciente |
| GET | /api/slots/:id | Obtém detalhes de um slot | Admin |
| POST | /api/slots | Cria um novo slot | Admin (gerenciador+) |
| POST | /api/slots/bulk | Cria múltiplos slots | Admin (gerenciador+) |
| PUT | /api/slots/:id | Atualiza um slot | Admin (gerenciador+) |
| DELETE | /api/slots/:id | Remove um slot | Admin (gerenciador+) |
Agendamentos
| Método | Endpoint | Descrição | Auth |
|---|---|---|---|
| GET | /api/agendamentos | Lista todos os agendamentos | Admin |
| GET | /api/agendamentos/meus | Lista agendamentos do paciente logado | Paciente |
| GET | /api/agendamentos/:id | Obtém detalhes de um agendamento | Admin/Paciente |
| POST | /api/agendamentos | Cria um novo agendamento | Admin/Paciente |
| DELETE | /api/agendamentos/:id | Cancela um agendamento | Admin/Paciente |
Médicos
| Método | Endpoint | Descrição | Auth |
|---|---|---|---|
| GET | /api/medicos | Lista todos os médicos | Admin/Paciente |
| GET | /api/medicos/:id | Obtém detalhes de um médico | Admin |
| POST | /api/medicos | Cadastra um novo médico | Admin (administrador+) |
| PUT | /api/medicos/:id | Atualiza um médico | Admin (administrador+) |
| DELETE | /api/medicos/:id | Remove um médico | Admin (administrador+) |
Especialidades
| Método | Endpoint | Descrição | Auth |
|---|---|---|---|
| GET | /api/especialidades | Lista todas as especialidades | Admin/Paciente |
| GET | /api/especialidades/:id | Obtém detalhes de uma especialidade | Admin |
| POST | /api/especialidades | Cadastra uma nova especialidade | Admin (administrador+) |
| PUT | /api/especialidades/:id | Atualiza uma especialidade | Admin (administrador+) |
| DELETE | /api/especialidades/:id | Remove uma especialidade | Admin (administrador+) |
Unidades
| Método | Endpoint | Descrição | Auth |
|---|---|---|---|
| GET | /api/unidades | Lista todas as unidades | Admin/Paciente |
| GET | /api/unidades/:id | Obtém detalhes de uma unidade | Admin |
| POST | /api/unidades | Cadastra uma nova unidade | Admin (administrador+) |
| PUT | /api/unidades/:id | Atualiza uma unidade | Admin (administrador+) |
| DELETE | /api/unidades/:id | Remove uma unidade | Admin (administrador+) |
Pacientes
| Método | Endpoint | Descrição | Auth |
|---|---|---|---|
| GET | /api/pacientes | Lista pacientes (com busca) | Admin |
| GET | /api/pacientes/:id | Obtém detalhes de um paciente | Admin |
| POST | /api/pacientes | Cadastra um novo paciente | Admin |
| PUT | /api/pacientes/:id | Atualiza um paciente | Admin |
API - Tratamento de Erros
Códigos de Status HTTP
| Código | Significado | Descrição |
|---|---|---|
| 200 | OK | Requisição bem-sucedida |
| 201 | Created | Recurso criado com sucesso |
| 204 | No Content | Exclusão bem-sucedida |
| 400 | Bad Request | Dados inválidos na requisição |
| 401 | Unauthorized | Token ausente ou inválido |
| 403 | Forbidden | Sem permissão para o recurso |
| 404 | Not Found | Recurso não encontrado |
| 409 | Conflict | Conflito (ex: CPF já cadastrado) |
| 500 | Internal Server Error | Erro 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 fornecido | Header Authorization ausente | Incluir token no header |
| Sessão revogada | Usuário fez logout ou token foi invalidado | Fazer novo login |
| Acesso negado | Role insuficiente para a operação | Contatar administrador |
| CPF já cadastrado | Tentativa de cadastro duplicado | Usar CPF diferente ou fazer login |
| CPF inválido | CPF não passa na validação da RF | Verificar 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" │
└─────────────────────────────────────────────────────────────────────────────────────┘