From 13b0e1827dafae3c57216f879d38e1055e1225fe Mon Sep 17 00:00:00 2001 From: Gemini Date: Fri, 3 Jul 2026 09:18:29 -0300 Subject: [PATCH] =?UTF-8?q?KB-PLUGIN-037:=20motor=20de=20templates=20de=20?= =?UTF-8?q?payload=20(2.0)=20+=20decis=C3=A3o=20de=20escopo=20(sem=20overr?= =?UTF-8?q?ide/multi-Redmine)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- index.json | 2 +- ...-PLUGIN-037-redmine-plugin-api-contract.md | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/index.json b/index.json index f983cf7..310426d 100755 --- a/index.json +++ b/index.json @@ -1,6 +1,6 @@ { "version": "1.0.0", - "last_updated": "2026-07-02", + "last_updated": "2026-07-03", "records": [ { "id": "KB-INFRA-001", diff --git a/records/plugin-dev/KB-PLUGIN-037-redmine-plugin-api-contract.md b/records/plugin-dev/KB-PLUGIN-037-redmine-plugin-api-contract.md index 8bacc98..a891662 100644 --- a/records/plugin-dev/KB-PLUGIN-037-redmine-plugin-api-contract.md +++ b/records/plugin-dev/KB-PLUGIN-037-redmine-plugin-api-contract.md @@ -103,6 +103,33 @@ Escrita: `POST /projects.json` (criar projeto c/ custom fields), `POST /issues.j (issue do chamado), `PUT /issues/:id.json` (status), `POST /time_entries.json` (tempo), `POST /projects/:id/memberships.json` (auto-membership). +## Motor de Templates de Payload (2.0) + +A partir da **2.0** o corpo de cada operação (`create_issue`, `log_time`, +`update_status`, `create_project`) pode vir de um **template editável** em vez de +ser montado no código — o objetivo é o plugin virar **produto ambiente-agnóstico** +(cada Redmine tem seus campos obrigatórios/personalizados). Guia do usuário: +`docs/TEMPLATES.md`; contrato de dev: `docs/API.md`. + +- **`PluginRedmineTemplateengine`** (`inc/templateengine.class.php`): tabela + `glpi_plugin_redmine_templates`, renderizador **mustache-like** (`{{ var | filtro }}`; + tag ocupando o valor inteiro → **tipo nativo**; lookup indexado `map.status[chamado.status]`; + filtros `truncar/sem_html/minusculo/identificador/padrao`; `prune` de nulos), seeds + equivalentes ao 1.x, descoberta de custom fields e os contextos (`buildContext`, + `buildFormContext`, `sampleContext`). +- **Precedência**: template **ativo** → renderiza e envia; erro de **render** → log + + **fallback 1.x**; **sem** template ativo → comportamento **1.x idêntico**. Ou seja, + atualizar da 1.x para a 2.0 **não muda nada** até ativar um template. +- **UI** (config): editor linha-a-linha "DE → PARA" (paleta de variáveis GLPI via + autocomplete + dicionário dos campos que o Redmine espera, com obrigatoriedade e + valores), botão "Gerar template" (local, sem reload) e **testador** + (`ajax/template_test.php`): preview do render + dry-run que cria/apaga objeto de + teste e **traduz os 422** em dicas. +- **NÃO virou template** (é motor, não payload): impersonation, idempotência, + membership, gates (Feito/duração), recuperação de issue órfã. +- Decisão de escopo (2026-07-03): **não** implementar override por vínculo nem perfis + multi-Redmine sem caso real (YAGNI) — o template global cobre o cenário atual. + ## Gotchas de manutenção - Dev = GLPI 11.0.7, prod = **11.0.4**: desenvolver mirando 11.0.0+ (sem