A91 Platform
arquitetura de dados · saúde B2B2C

Um banco operacional.
A IA numa unidade à parte.
Pronto para FHIR.

PostgreSQL como base operacional — relacional, documentos e séries temporais no mesmo lugar — e um Vector Store dedicado (pgvector) à parte para a IA, isolado porque ali os dados não são anonimizados. Cadeia B2B2C controlada, dados de saúde que nunca se perdem e o caminho aberto para o padrão da saúde brasileira.

⚛️ React
⚙️ PHP 8
🐘 PostgreSQL único
📄 JSONB
📈 TimescaleDB
🧠 Vector Store (pgvector)
🔥 HL7 FHIR R4
💬 Comunicação paciente ↔ profissional
🔒 LGPD
Decisão

A stack: PostgreSQL como banco único

Em vez de operar dois bancos (relacional + NoSQL), consolidamos o operacional no Postgres — ele cobre relacional, documentos e séries temporais num sistema só, com transações ACID atravessando identidade, saúde e consentimento. A IA fica num Vector Store dedicado, à parte.

banco único

🐘 PostgreSQL

A fonte da verdade de tudo. Maduro, ACID, barato de operar e com extensões que dispensam um segundo banco. Anonimização, cadeia B2B2C e consentimento vivem num lugar só — mais fácil de auditar para a LGPD.

EXTENSÃO
🗂️

Relacional

núcleo nativo

Cadeia de custódia B2B2C, identidade, vínculos e consentimento. Chaves estrangeiras e row-level security.

EXTENSÃO
📄

JSONB

documentos flexíveis

Faz o papel que o MongoDB faria: a balança manda 12 campos, o anel manda 4, e nada quebra. Indexável.

EXTENSÃO
📈

TimescaleDB

séries temporais

Para batimento contínuo de alta frequência. Comprime e consulta no tempo sem sair do Postgres.

UNIDADE À PARTE
🧠

Vector Store

pgvector dedicado · IA

Instância própria, fora do banco operacional. Embeddings do histórico e refeições para o nutricionista — com dados não anonimizados, então tem acesso e governança próprios.

OPCIONAL

Redis

cache / tempo real

Sessões e últimos valores de cada dispositivo, para o dashboard abrir instantâneo.

Como se organiza

Um banco operacional, três camadas

Não há mais "ponte entre bancos": o operacional é todo o mesmo Postgres, e identidade e saúde se ligam por chave estrangeira interna. Só a IA mora fora — num Vector Store dedicado, porque ali os dados não são anonimizados.

🗂️
Relacional
cadeia B2B2C · identidade · consentimento
tabelas + RLS
📄
JSONB
documentos de saúde flexíveis por aparelho
jsonb
📈
Time-series
batimento e sinais de alta frequência
hypertable

O que amarra tudo

Cada linha de saúde (em JSONB ou na hypertable) carrega as mesmas chaves da camada relacional. Não é uma ligação entre bancos — é uma FK dentro do mesmo banco.

usuario_id·equipamento_id

Resultado: uma consulta única pode juntar "quem é o paciente + o que ele mediu + se há consentimento" numa transação só — algo que exigiria orquestração entre dois sistemas no modelo anterior.

🧠
Vector Store · pgvector
unidade separada do banco operacional
⚠️ dados não anonimizados
Recebe embeddings do histórico e refeições para a IA do nutricionista — busca semântica, "pacientes parecidos" e RAG. Como o vetor pode reconstruir conteúdo identificável, aqui os dados não são anonimizados; por isso isolamos a unidade, com acesso, consentimento e auditoria próprios. Liga ao operacional só pelo usuario_id.
saude_embeddings (
  usuario_id uuid,
  origem     text,  -- refeicao…
  conteudo   text,
  embedding  vector(1536)
)
Interoperabilidade

Alinhado ao HL7 FHIR

FHIR é o padrão da saúde para representar e trocar dados (recursos como Patient, Observation, Device). Não viramos um servidor FHIR agora, mas nomeamos e estruturamos o schema espelhando esses recursos — assim expor uma camada FHIR depois (parceiros, prontuários, RNDS) vira pouco trabalho.

usuariosPatient
O paciente. No Brasil, o perfil exige o CNS.
profissionaisPractitioner
Nutricionista / treinador (+ PractitionerRole).
empresasOrganization
Distribuidor, clínica ou academia.
equipamentosDevice
Anel, pulseira e balança (+ DeviceMetric).
leituras / bioimpedanciaObservation
Cada métrica é uma Observation; bioimpedância vira painel com componentes.
consentimentosConsent
O FHIR tem um recurso próprio para isso.
vinculosCareTeam
A relação paciente ↔ profissional.
comunicacoesCommunication
Mensagens nas duas vias entre paciente e profissional.
planos_cuidadoCarePlan
Planos de dieta (NutritionOrder) e treino enviados ao app.
gruposGroup
Família / amigos da gamificação.
🇧🇷 Por que isso importa no Brasil: a RNDS (Rede Nacional de Dados em Saúde, do Ministério da Saúde) só recebe dados no padrão HL7 FHIR R4, com perfis nacionais (ex.: Patient com CNS, exames com LOINC). Se a A91 algum dia conversar com o SUS ou com prontuários, FHIR deixa de ser opcional. Modelar alinhado desde já evita retrabalho.

⚠️ Cuidado prático: FHIR é verboso para dado de wearable de alta frequência. Guardamos o bruto eficiente (JSONB / Timescale) e projetamos para FHIR na borda/API — não no armazenamento.
Privacidade · LGPD

Pseudonimização e anonimização

São coisas diferentes — e usamos as duas. Pseudonimização protege a operação do dia a dia (reversível com a chave do cofre). Anonimização é irreversível e serve para dados que saem da plataforma (pesquisa, estatística).

O padrão "cofre" (pseudonimização)

🔒 usuarios_identidade
nome, cpf, e-mail, foto — cifrados, isolados, acesso auditado
1:1 · só com chave
🆔 usuarios
só o pseudônimo usr_8a1f + sexo, faixa etária
usuario_id
📄📈 Camadas de saúde (JSONB / Timescale)
leituras, bioimpedância, resumo — nunca veem PII, só o pseudônimo

Registro do Eduardo

🔓 Cofre aberto — visão identificada 🔒 Visão operacional — pseudonimizada
idusr_8a1f3c
nome EEduardo Silva ?guardado no cofre
cpf 123.456.789-00 •••.•••.•••-•• · cifrado
nascimento 14/03/1990 faixa 35–39(generalizado)
sexoM
dados saúde→ vinculados a usr_8a1f3c

Duas trilhas, dois propósitos

🔑 Pseudonimização

operacional · reversível
  • Roda o dia a dia: dashboard, profissional, gamificação
  • PII no cofre cifrado; resto usa o pseudônimo usuario_id
  • Reidentificar exige a chave + consentimento ativo
  • Equivale ao "crypto-hash" das ferramentas de de-id do FHIR

🎭 Anonimização

pesquisa · irreversível
  • Para dados que saem da plataforma: estudos, estatística
  • Sem chave de volta — não dá para reidentificar
  • Deslocamento de datas, generalização e k-anonimato
  • Gerada num ambiente separado, espelhando o de-id do FHIR
🧠 Exceção — o Vector Store: a unidade de IA (pgvector) guarda embeddings que podem reconstruir conteúdo identificável, então ali os dados não são anonimizados. Por isso ela fica fora do banco operacional, com acesso, consentimento e auditoria próprios — em vez de herdar o cofre.
Camada relacional

Modelo relacional

Clique numa tabela para destacar suas conexões. Cada uma traz o recurso FHIR que ela espelha.

PK chave primária
FK chave estrangeira
1:N um para muitos
FHIR recurso equivalente
Camadas JSONB · Timescale

Dados de saúde no Postgres

O que antes seria o MongoDB agora são tabelas do próprio Postgres. Todas carregam usuario_id e equipamento_id — a FK que liga à camada relacional.

Fluxograma animado

Como tudo se conecta

O banco operacional no centro: os dados de saúde entram pela esquerda; o app do Eduardo e o profissional ficam à direita, trocando informação nas duas vias (sempre com consentimento). A IA mora embaixo, num Vector Store à parte — porque ali os dados não são anonimizados.

usuario_id (FK) embeddings (IA) consentimento 🔒 Acessórios 💍 Anel ⌚ Pulseira ⚖️ Balança steps · hr · spo2 · sono… Ingestion API carimba os IDs 🐘 PostgreSQL banco operacional 🗂️ Relacional · consentimento 📄 JSONB · documentos de saúde 📈 Timescale · séries temporais 💬 Comunicações · mensagens/planos 🔒 Cofre PII (cifrado, isolado) RLS aplica consentimento por escopo 📱 App do Eduardo dashboard · idade fisiológica ↓ recebe: dados, planos, alertas ↑ envia: mensagens, sintomas 🩺 Profissional nutricionista / treinador ↑ envia: recomendações, planos ↓ recebe: dados (com consentimento) 🧠 Vector Store unidade separada pgvector · IA do nutricionista ⚠️ dados NÃO anonimizados
dado de saúde entrando
dados/resumo entregues
mensagens nas duas vias (Communication)
FK interna (usuario_id)
embeddings → Vector Store (à parte)
Ponta a ponta

O caminho de um dado

Do anel no dedo do Eduardo até o número no dashboard — tudo dentro do mesmo Postgres.

Resumo

Tecnologias adotadas