Plataforma SaaS de clínicas médicas rodando 100% em Cloudflare Workers. 5 produtos publicados em repos independentes, arquitetura de 3 camadas (R1/R2/R3), filas, Durable Objects e OpenAI Responses API.
Serviço central de autenticação. Emite JWTs usados por TODOS os outros produtos. Users, accounts, profiles.
Plataforma clínica: pacientes, consultas, profissionais, agendas, convênios, sincronia Google Calendar.
Gateway multi-canal (WhatsApp, SMS). Substitui o Chatwoot. Adapters pluggable, queues, webhooks.
Orquestrador de agentes IA. OpenAI Responses API, Durable Objects, tool execution engine, followups agendados.
Painel superadmin para operadores da plataforma. Gerência accounts, usuários, produtos, integrações.
Um Worker dedicado que abstrai TODO acesso ao Postgres.
POST /Workers para R2 buckets e/ou consumers de Cloudflare Queues.
Workers REST API que expoe a logica de negocio. Divididos em r3-api (backend) e r3-app (frontend).
r3-api: REST routes + servicesr3-app: Next.js 16 SPA@greatapps/*Framework HTTP estilo Express para Workers, com middleware injection e queues.
Camada CRUD que consome r1-api-postgresql. Métodos insert, update, view, delete, restore.
Validação e type coercion. Define entidades com tipos, validations e multi-tenancy.
Encode/decode JWT via Web Crypto API (nativa no Workers runtime).
Cache distribuido backed por KV. TTLs, invalidacao por prefixo.
HTTP client com retry automático, caching e timeout.
Fila com controle de concorrência para executar N tarefas async.
Crypto, string, date, UUID. Utilitarios compartilhados.
Encode/decode de strings para comunicação inter-serviços.
Componentes React compartilhados: login, app shell, inbox, composer, dashboard de agentes.
Agrega mensagens fragmentadas (WhatsApp multi-part), processa áudio/vision, gerência buffer por conversa. Arquitetura modular em 6 arquivos.
Agenda followups futuros por conversa. Um DO por conversa. Usa alarms nativos do Cloudflare.
Sincrona, sem polling. Substitui threads por conversations. gpt-5.4-mini default.
Compactacao server-side automática a 200K tokens. Preserva histórico sem custo explosivo.
Todas as tools forcam strict: true, garantindo JSON valido em toda resposta.
SHA-256 do system prompt armazenado em prompt_versions. Detecta mudanças.
4 executors pluggaveis: google-calendar, gagents-api, execute-skill, gclinic-internal. Com cache.
3x exponential backoff (500ms base). Não retry em 400/401/403/404/422.
Sincrona, sem HTTP. Worker A chama Worker B diretamente. Usada entre r3-api e r1-api-postgresql.
Assincrona, durable. Entre gchat e gagents. Batch=20, retry=10, delay exponencial.
Frontend → API pública. Webhooks externos (providers). Autenticado por JWT.
jti.# Next.js apps (com Hyperdrive NAO usar 'bun run deploy') cd gclinic/gclinic-r3-app bun run build # 1. Next.js build bun run build:worker # 2. @opennextjs/cloudflare build bunx wrangler deploy # 3. Deploy direto pelo wrangler # APIs simples (r1, r3-api) cd gauth/gauth-r3-api bunx wrangler deploy bunx wrangler tail # stream logs
gclinic-r3-app chama gauth, gchat, gagents, gclinic via fetch manual. Não ha OpenAPI, tRPC ou codegen. Cada mudança de schema e risco de quebra silenciosa em producao.
Multi-sessão em processo Go único no Fly.io funciona bem para dezenas de clínicas, mas não escala linearmente. Cada sessão carrega ~30-100MB de estado crypto. Um crash derruba todas simultaneamente. Falta estratégia de sharding por session_id.
POST / que aceita JSON de operaçãoPerde-se tipagem de SQL em compile time. Objetos { type: 'SELECT', table, where } passam por runtime validation. Erros de schema/coluna so aparecem em producao.
{ status: 0 } em vez de throwFalhas silenciosas são anti-pattern. Dev esquece de checar result?.status !== 1 e continua como se tivesse dado certo. Pior: update() sem match atualiza 0 linhas e retorna sucesso.
TOOL_ERROR, DISCARDED, etc.)Tool outputs, meta-agent authorizations e followups usam strings para representar estado. Sem enum, sem tipos. Um typo quebra em runtime silenciosamente.
Cada produto (gauth, gclinic, gchat, gagents, gadmin) e publicado em seu próprio repo. Localmente são agrupados em uma pasta. Não ha orquestracao de versão entre eles — deploy coordenado depende de disciplina humana.
deleted INTEGER (0/1) em vez de booleanSchema declara boolean mas o DB precisa ser integer. Gambiarra historica que exige treinar todo novo dev. Postgres tem BOOLEAN nativo desde sempre.
Apesar das criticas, ha muitas decisões excelentes. Service Bindings, Durable Objects, Responses API. Ver detalhes.