Plano de Execução: Integração GLPI & Framework de Ações/Eventos Externos

Este documento unifica e consolida o plano de desenvolvimento de backend para a Integração com GLPI e a fundação do Framework de Ações e Eventos Externos (compatível e reutilizável para outras integrações).


1. Visão Geral da Arquitetura

O sistema é dividido em dois fluxos complementares:

  1. Outbound (Ações de Saída): O Agente ou a Plataforma executa ações em ferramentas externas baseadas em gatilhos específicos (ex: ON_REQUEST_CONFIRMED).
  2. Inbound (Eventos de Entrada/Webhooks): Sistemas externos notificam a plataforma sobre atualizações (ex: alteração do status de um ticket no GLPI).
[Diagram]

2. Modelagem de Dados (Prisma Schema)

As seguintes tabelas serão adicionadas/atualizadas no arquivo schema.prisma:

// 1. Ações Externas e Histórico (Outbound)

model agent_template_tool_actions {
  id                    String                 @id @default(dbgenerated("uuidv7()")) @db.Uuid
  agent_template_id     String                 @db.Uuid
  integration_action_id String                 @db.Uuid
  trigger               String                 // ex: ON_REQUEST_CONFIRMED
  input_mapping         Json                   // Mapeia chaves do schema da action para caminhos (ex: artifact.name)
  output_mapping        Json?
  status_mapping        Json?
  required              Boolean                @default(true)
  sort_order            Int                    @default(0)
  created_at            DateTime               @default(now()) @db.Timestamptz(6)
  updated_at            DateTime               @default(now()) @db.Timestamptz(6)

  integration_actions   integration_actions    @relation(fields: [integration_action_id], references: [id], onDelete: Cascade)
  integration_executions integration_executions[]
}

model request_external_references {
  id                  String               @id @default(dbgenerated("uuidv7()")) @db.Uuid
  request_id          String               @db.Uuid
  integration_tool_id String               @db.Uuid
  external_id         String               // ex: ID do ticket no GLPI
  resource_state      String?              // ex: open, solved, closed
  sync_enabled        Boolean              @default(true)
  last_synced_at      DateTime?            @db.Timestamptz(6)
  metadata            Json?                @default("{}") // Armazena dados extras retornados pela API externa
  created_at          DateTime             @default(now()) @db.Timestamptz(6)

  requests            requests             @relation(fields: [request_id], references: [id], onDelete: Cascade)
  integration_tools   integration_tools    @relation(fields: [integration_tool_id], references: [id])
  integration_executions integration_executions[]
}

model integration_executions {
  id                              String                        @id @default(dbgenerated("uuidv7()")) @db.Uuid
  request_id                      String                        @db.Uuid
  agent_template_tool_action_id   String                        @db.Uuid
  request_external_reference_id   String?                       @db.Uuid
  status                          String                        // PENDING, RUNNING, SUCCESS, FAILED
  started_at                      DateTime                      @default(now()) @db.Timestamptz(6)
  finished_at                     DateTime?                     @db.Timestamptz(6)
  duration_ms                     Int?
  input_payload                   Json?
  output_payload                  Json?
  error                           Json?
  metadata                        Json?                         @default("{}")
  created_at                      DateTime                      @default(now()) @db.Timestamptz(6)

  requests                        requests                      @relation(fields: [request_id], references: [id], onDelete: Cascade)
  agent_template_tool_actions     agent_template_tool_actions   @relation(fields: [agent_template_tool_action_id], references: [id], onDelete: Cascade)
  request_external_references     request_external_references?  @relation(fields: [request_external_reference_id], references: [id], onDelete: SetNull)
}

// 2. Eventos Recebidos / Ingress (Webhooks / Inbound)

model integration_events {
  id                  String                       @id @default(dbgenerated("uuidv7()")) @db.Uuid
  integration_tool_id String                       @db.Uuid
  event_key           String                       // ex: ticket_updated, message_received
  description         String?                      @default("")
  payload_schema      Json?                        @default("{}") // Validação do payload recebido do webhook
  created_at          DateTime                     @default(now()) @db.Timestamptz(6)

  integration_tools   integration_tools            @relation(fields: [integration_tool_id], references: [id], onDelete: Cascade)
  agent_template_tool_events agent_template_tool_events[]
  integration_event_logs     integration_event_logs[]

  @@unique([integration_tool_id, event_key], map: "uq_integration_events_tool_event")
}

model agent_template_tool_events {
  id                    String             @id @default(dbgenerated("uuidv7()")) @db.Uuid
  agent_template_id     String             @db.Uuid
  integration_event_id  String             @db.Uuid
  handler_key           String             // Nome da classe/função que processa (ex: update_request_status)
  config                Json               // Configurações específicas do processamento (mapeamento de campos)
  enabled               Boolean            @default(true)
  created_at            DateTime           @default(now()) @db.Timestamptz(6)

  integration_events    integration_events @relation(fields: [integration_event_id], references: [id], onDelete: Cascade)
}

model integration_event_logs {
  id                  String              @id @default(dbgenerated("uuidv7()")) @db.Uuid
  tenant_id           String?             @db.Uuid // Pode ser resolvido a partir do webhook (subdomínio ou payload)
  integration_tool_id String              @db.Uuid
  integration_event_id String?             @db.Uuid // Opcional, caso não consiga mapear o evento
  event_key           String              // Salva a key crua recebida
  raw_payload         Json                // Payload integral recebido do webhook
  status              String              // PENDING, PROCESSED, FAILED, IGNORED
  error_log           Json?               @default("{}")
  created_at          DateTime            @default(now()) @db.Timestamptz(6)

  integration_tools   integration_tools   @relation(fields: [integration_tool_id], references: [id])
  integration_events  integration_events? @relation(fields: [integration_event_id], references: [id], onDelete: SetNull)
}

3. Detalhamento das Subtasks de Desenvolvimento

Abaixo estão listadas as especificações detalhadas de cada subtask necessárias para a execução completa do plano.


Modelagem de Banco de Dados


Definir Contratos de Actions e Resolver Input Mapping


Criar ToolExecutor Desacoplado de Ferramentas Específicas


Executar Ações Externas ao Confirmar Request


Criar Endpoint para Testar Execução de Action


Sincronizar Estado de Referências Externas


Expor Referências Externas e Status na API de Requests


Criar Processador Genérico de Eventos Externos e Webhooks


Implementar Evento glpi.ticket_updated no Processador