Post

Case: middleware Rails para sincronizar Jira e Azure DevOps

Case: middleware Rails para sincronizar Jira e Azure DevOps

Por que construir um middleware Jira ↔ Azure

Times diferentes usavam Jira e Azure DevOps em paralelo. Havia dupla digitação, status divergentes e anexos que não chegavam para quem precisava agir. A solução foi um serviço Rails dedicado a intermediar os dois mundos e manter fluxos consistentes.

Arquitetura em alto nível

  • Entradas HTTP: POST /webhooks (Jira) e POST /webhooks_azure (Azure Service Hooks). Cada payload é salvo em WebhookLog com estados received, processing, completed ou failed, permitindo replay seguro.
  • Regras de skip: eventos irrelevantes (worklogs, attachments triviais, automations de terceiros) são descartados cedo para evitar ruído.
  • Mapeamento de domínios: o campo de domínio do Jira decide o AreaPath/Iteration no Azure. O serviço ajusta isso antes de criar ou atualizar qualquer Work Item.
  • Criação/atualização: para issues com prefixo alvo (ex.: PS), se o tipo é Incident, cria/atualiza Bug; caso contrário, cria/atualiza Feature. Comentários privados e anexos são convertidos e replicados; work items existentes são reabertos quando o Jira retorna a um estado anterior.
  • Sincronismo reverso: webhooks do Azure atualizam domínio/AreaPath no Jira e executam transições quando Bugs/Features vão para Blocked, Closed ou estados equivalentes.
  • Transições configuráveis: há um painel admin que versiona status e mapeia “de/para” de Jira ↔ Azure sem precisar redeploy.
  • Deploy e saúde: healthchecks (/status, /up), smoke test de integração e deploy zero-downtime via Kamal.

Arquitetura (diagrama simplificado)

flowchart LR
  Jira[Webhook Jira] -->|POST /webhooks| IngestJira[WebhookLog<br/>source=jira]
  Azure[Service Hook Azure] -->|POST /webhooks_azure| IngestAzure[WebhookLog<br/>source=azure]

  IngestJira -->|skip rules| SkipJira[Descarta eventos irrelevantes]
  IngestJira -->|processa| JiraSvc[JiraWebhookService<br/>domínio -> AreaPath/Iteration]
  JiraSvc -->|Incident| BugSvc[Cria/atualiza Bug]
  JiraSvc -->|Feature| FeatureSvc[Cria/atualiza Feature]
  BugSvc --> Replay[WebhookLog.complete!/fail!]
  FeatureSvc --> Replay

  IngestAzure --> AzureSvc[AzureWebhookService<br/>AreaPath -> domínio]
  AzureSvc --> AzureStatus[StatusSync<br/>Blocked/Closed -> transição Jira]
  AzureStatus --> Replay

Operação e rastreabilidade

  • Cada webhook gera log com payload, metadata de status e erros, permitindo auditar e reprocessar.
  • Textos são normalizados (wiki → Markdown/HTML) para preservar formatação em ambos os sistemas.
  • Correções de AreaPath e Iteration ocorrem mesmo se o estado não muda, evitando drift entre squads.

Impacto observado

  • Fim da dupla digitação e menos perda de contexto entre squads.
  • Status e domínios alinhados automaticamente, reduzindo handoffs manuais.
  • Comentários/anexos replicados com consistência, diminuindo reprocesso e tempo de resposta.

Métricas (anonimizadas)

  • Redução >60% em reprocesso manual de tickets após mapear domínios e normalizar AreaPath/Iteration.
  • Queda >80% em falhas de sincronismo críticas depois de adicionar telemetria por webhook e smoke tests de ponta a ponta.
  • Sincronismos sustentados entre ~150–300 eventos/dia sem filas acumuladas após limpeza de eventos irrelevantes.

O que você pode reutilizar

  • Log e replay de webhooks antes de processar a lógica de negócio.
  • Mapeamento configurável de status e domínios para AreaPath/Iteration.
  • Conversão de texto para manter formatação entre ferramentas diferentes.
  • Smoke tests de ponta a ponta para validar integrações críticas antes do deploy.
Esta postagem está licenciada sob CC BY 4.0 pelo autor.