Skip to content

REF-901-03: Jira SLA Integration

ADR: ADR-901 — IntegrationsEscopo: Jira aplica SLAs, Plugin exibe, webhook flow, REST API sync, responsabilidade por dado, plugin NÃO roda relógio próprio


1. Princípio Central

Jira APLICA SLAs (motor nativo). Plugin EXIBE status no portal e agrega dados para relatórios.

Plugin NÃO roda relógio de SLA próprio. Razões:

  1. Jira já faz isso — motor de SLA lida com pausa/retomada, calendários, feriados
  2. Relógios paralelos criam drift (discrepâncias)
  3. Calendários de feriados e horário de verão precisam de fonte única
  4. Equipe mínima não consegue manter dois motores de SLA

2. Webhook Flow

Jira Service Management

├── Webhook: issue_created
│   └── Plugin: cria ServiceRequest (espelho)
│       ├── Preenche: jira_issue_key, priority, status
│       └── Inicia: sla_target baseado em support_class do Entitlement

├── Webhook: issue_updated
│   └── Plugin: atualiza SR
│       ├── Status sincronizado
│       ├── Campos SLA atualizados (sla_elapsed, sla_status)
│       └── Prioridade reclassificada (se equipe alterou)

├── Webhook: sla_breached
│   └── Plugin: marca SR como violada
│       ├── sla_status → breached
│       └── sla_breach_log atualizado

└── Webhook: issue_resolved / issue_closed
    └── Plugin: SR → completed / closed
        └── UST real preenchida (se aplicável)

3. REST API Sync Periódico

Cron do plugin reconcilia dados com Jira via REST API:

FrequênciaO Que Faz
A cada 15 minBusca SRs com status divergente (Jira vs Plugin)
DiárioReconcilia campos SLA de todas as SRs abertas
SemanalGera relatório de conformidade de SLA

Trata webhooks perdidos (Jira fora, webhook falhou, etc.).


4. Responsabilidade por Dado

DadoSource of TruthSyncNotas
Status da OSJiraJira → PluginJira vence para workflow
PrioridadeJiraJira → PluginEquipe define na triagem
Campos SLA (elapsed)JiraJira → PluginMotor de SLA roda no Jira
SLA breachedJiraJira → PluginPlugin espelha estado
UST estimadaPluginPlugin → JiraPlugin define, Jira lê via campo custom
UST realPluginCalculadoWorklogs Jira + complexidade
Valor faturadoPluginN/APlugin é autoridade única de billing
Tipo de serviçoPluginPlugin → JiraCatálogo do plugin
Tarefas / subtarefasJiraN/APlugin não replica gestão de projeto

5. Modelo de Dados SLA no Plugin

ServiceRequest
├── jira_issue_key: "PROJ-123"
├── priority: P1 | P2 | P3 | P4 | P5
├── sla_started_at: datetime
├── sla_paused_at: datetime | null
├── sla_elapsed: int (seconds, do Jira)
├── sla_target: int (seconds, derivado de support_class × priority)
├── sla_calendar: "24/7" | "BH" (derivado da matrix)
├── sla_status: "on_track" | "at_risk" | "breached" (computed)
└── sla_breach_log: [
      { metric: "first_response", breached_at: datetime, target: 3600, actual: 4200 }
    ]

6. Exibição no Portal

SR-20260042 — "Página de login retornando erro 500"
Prioridade: P2 Urgente
Classe: Business

Status do SLA:
┌──────────────────────────────────────────────────┐
│ Primeira Resposta [====........]  48min / 2h  ✅  │
│ Resolução         [==..........]  48min / 8h  ✅  │
└──────────────────────────────────────────────────┘

Cores: on_track (verde) → at_risk (amarelo, 80%+) → breached (vermelho).


7. Dashboard Admin

VisualizaçãoConteúdo
Visão Geral SLA% conformidade por classe no mês corrente
Itens VioladosSRs com SLA violado, por prioridade
Itens em RiscoSRs em 80%+ da meta, não violadas
Resumo por OrgPerformance SLA por organization nos últimos 30/60/90 dias

8. Escopo de Versão

Funcionalidadev5.0v5.0.x
SR criada via webhook JiraBásicoCompleto
Status sincronizadoBásicoBidirecional
SLA exibido no portalEstáticoTempo real
Worklogs → UST real
Relatórios de conformidade SLA
Criação de projeto Jira automática

9. Plugin→Jira: CRUD Integration

Além do fluxo Jira→Plugin (seções 1-8), o plugin também CRIA e GERENCIA issues no Jira.

Namespace

Middag\Account\Integration\Jira\
├── JiraClientInterface          # Port: contrato HTTP (get/post/put/delete/upload)
├── JiraClient                   # Adapter: Guzzle, Basic Auth, retry on 429
├── JiraIssueService             # Issues CRUD + transitions + search + createFromOrder()
├── JiraProjectService           # Projects + issue types listing
├── JiraCommentService           # Comments CRUD
├── JiraAttachmentService        # Upload/delete attachments (multipart)
├── JiraWorklogService           # Worklogs CRUD
├── AdfBuilder                   # Fluent builder para Atlassian Document Format (API v3)
├── DTO/
│   ├── JiraIssueDTO
│   ├── JiraProjectDTO
│   ├── JiraIssueTypeDTO
│   ├── JiraTransitionDTO
│   └── JiraCommentDTO
└── Exception/
    ├── JiraApiException
    └── JiraRateLimitException

Todos os Services e Client têm sufixos auto-registráveis pelo ServiceProvider (auto-discovery). JiraClientInterface fica em Integration\Jira\ (não em Contract\ — seria ignorada pelo scanner). Auto-alias: Container::get(JiraClientInterface::class)JiraClient.


10. JiraClient — HTTP Layer

  • Base URL: https://{JIRA_DOMAIN}.atlassian.net/rest/api/3
  • Auth: Basic ({JIRA_EMAIL}:{JIRA_API_TOKEN})
  • Timeout: 30s
  • Rate limiting: retry on HTTP 429 com Retry-After header, máximo 3 tentativas
  • Operações: get(), post(), put(), delete(), upload() (multipart para attachments)

Env Vars

VariávelExemploObrigatório
JIRA_DOMAINmiddagSim
JIRA_EMAILintegrations@middag.com.brSim
JIRA_API_TOKENATATT3xFfGF0...Sim

Graceful Degradation

Se env vars ausentes: JiraClient inoperante — todos os métodos lançam JiraApiException. Consumers (hooks, controllers) capturam exception e logam warning. Sistema funciona normalmente sem Jira. Mesmo pattern do code-intel (integração opcional).


11. Order→Jira Automation

Trigger

woocommerce_order_status_completedJiraOrderHooks::onOrderCompleted()

Localização: Middag\Account\WordPress\Hook\JiraOrderHooks (auto-discovered pelo HookRegistrar).

Flow

  1. Hook recebe $orderId
  2. Para cada item do pedido, verifica se produto tem _middag_jira_enabled = yes
  3. Se sim, lê config Jira do produto (project_key, issue_type_id)
  4. Chama JiraIssueService::createFromOrder() com dados do pedido
  5. AdfBuilder gera description em formato ADF (heading, dados cliente, itens, total)
  6. Issue criada → issue.key salvo como order meta _middag_jira_issue_{item_id}
  7. Falha: log warning, não bloqueia pedido

Product Meta Keys

KeyTipoObrigatório
_middag_jira_enabledyes/noSim
_middag_jira_project_keystring (ex: MIDDAG)Sim (se enabled)
_middag_jira_issue_type_idstring (ex: 10001)Sim (se enabled)
_middag_jira_summary_templatestring (ex: Onboarding: {billing_name})Não

Pattern idêntico ao _middag_nfse_* — consistência com mapeamentos existentes.


12. REST API Endpoints (Admin + Portal)

Controller: Middag\Account\Api\V1\JiraController (scope = 'jira')

MétodoEndpointDescrição
GETmiddag-account/v1/jira/projectsLista projetos Jira
GETmiddag-account/v1/jira/projects/{key}/issue-typesIssue types de um projeto
POSTmiddag-account/v1/jira/issuesCria issue
GETmiddag-account/v1/jira/issues/{key}Busca issue por key
PUTmiddag-account/v1/jira/issues/{key}Atualiza issue
GETmiddag-account/v1/jira/issues/search?jql=...Busca JQL
POSTmiddag-account/v1/jira/issues/{key}/transitionsTransiciona issue
POSTmiddag-account/v1/jira/issues/{key}/commentsAdiciona comentário

13. ADF Builder

API v3 do Jira exige Atlassian Document Format para descriptions e comments. AdfBuilder oferece fluent API: heading(), paragraph(), richParagraph(), bold(), link(), bulletList(), codeBlock(), divider(), toArray().

Usado por JiraIssueService::createFromOrder() para montar description estruturada com dados do pedido.


14. DI Container Registration

Nenhuma alteração em Container.php necessária. Auto-discovery resolve:

ClasseSufixoAuto-registradoAuto-alias
JiraClientClientSim→ JiraClientInterface
JiraIssueServiceServiceSim
JiraProjectServiceServiceSim
JiraCommentServiceServiceSim
JiraAttachmentServiceServiceSim
JiraWorklogServiceServiceSim
AdfBuilderBuilderSim
JiraControllerControllerSim
JiraOrderHooksNão (HookRegistrar)

15. Implementation Waves

Wave 1 — Fundação (sem WordPress deps):
  JiraClientInterface, JiraClient, Exceptions, AdfBuilder, DTOs

Wave 2 — Services:
  JiraProjectService, JiraIssueService, JiraCommentService,
  JiraAttachmentService, JiraWorklogService

Wave 3 — WordPress integration:
  JiraOrderHooks (automação pagamento), JiraController (API v1)

Wave 4 — Admin UI:
  JiraProductHooks (campos Jira no editor de produto WC)