KB-PLUGIN-040: Kanban multi-itemtype em plugin (agregacao, mapa coluna<->estado, update() nativo)
Aprendizado do mindscrum 0.2.0. Inclui o achado de que update(status=5) resolve o chamado sem exigir a solucao do formulario ITIL. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
c51827a57c
commit
e497e96274
2 changed files with 124 additions and 0 deletions
22
index.json
22
index.json
|
|
@ -763,6 +763,28 @@
|
|||
"severity": "high",
|
||||
"path": "records/plugin-dev/KB-PLUGIN-039-glpi11-project-ticket-pm-substrate.md",
|
||||
"summary": "id: KB-PLUGIN-039"
|
||||
},
|
||||
{
|
||||
"id": "KB-PLUGIN-040",
|
||||
"title": "\"GLPI 11 — Kanban multi-itemtype num plugin (Chamados + Tarefas de Projeto): agregação, mapa coluna↔estado e escrita via update() nativo\"",
|
||||
"domain": "plugin-dev",
|
||||
"tags": [
|
||||
"glpi11",
|
||||
"plugin",
|
||||
"kanban",
|
||||
"board",
|
||||
"ticket",
|
||||
"projecttask",
|
||||
"projectstate",
|
||||
"drag-drop",
|
||||
"ajax",
|
||||
"twig",
|
||||
"mindscrum"
|
||||
],
|
||||
"status": "active",
|
||||
"severity": "high",
|
||||
"path": "records/plugin-dev/KB-PLUGIN-040-glpi11-unified-kanban-multi-itemtype.md",
|
||||
"summary": "id: KB-PLUGIN-040"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,102 @@
|
|||
---
|
||||
id: KB-PLUGIN-040
|
||||
title: "GLPI 11 — Kanban multi-itemtype num plugin (Chamados + Tarefas de Projeto): agregação, mapa coluna↔estado e escrita via update() nativo"
|
||||
domain: plugin-dev
|
||||
tags:
|
||||
- glpi11
|
||||
- plugin
|
||||
- kanban
|
||||
- board
|
||||
- ticket
|
||||
- projecttask
|
||||
- projectstate
|
||||
- drag-drop
|
||||
- ajax
|
||||
- twig
|
||||
- mindscrum
|
||||
status: active
|
||||
severity: high
|
||||
created_at: 2026-07-10
|
||||
updated_at: 2026-07-10
|
||||
applies_to:
|
||||
- GLPI 11.0.8 dev
|
||||
- plugin mindscrum 0.2.0
|
||||
related_records:
|
||||
- KB-PLUGIN-039
|
||||
- KB-PLUGIN-010
|
||||
- KB-PLUGIN-028
|
||||
- KB-PLUGIN-036
|
||||
---
|
||||
|
||||
# GLPI 11 — Kanban multi-itemtype num plugin (Chamados + Tarefas de Projeto)
|
||||
|
||||
O Kanban nativo é **single-itemtype** (KB-PLUGIN-039). Um board que mistura
|
||||
`Ticket` + `ProjectTask` na mesma tela é viável num plugin **agregando os dados
|
||||
e roteando o drop para o `update()` do itemtype certo** — sem tocar no motor.
|
||||
Validado no mindscrum 0.2.0 (E2E via bootstrap do Kernel, KB-PLUGIN-031).
|
||||
|
||||
## Arquitetura que funcionou
|
||||
|
||||
- **Colunas unificadas fixas** (PoC): Novo / Em andamento / Pendente / Concluído.
|
||||
- **`ColumnMap`** — o miolo da regra, reconcilia dois modelos:
|
||||
- `Ticket.status` (enum 1..6) ↔ coluna;
|
||||
- `ProjectTask.projectstates_id` (`ProjectState`: 1=New, 2=Processing, 3=Closed) ↔ coluna.
|
||||
- Dois sentidos: leitura `estado → coluna` (montar o board) e escrita
|
||||
`coluna → estado` (aplicar no drop).
|
||||
- **`CardProvider`** — agrega via `$DB->request()`: tickets com
|
||||
`getEntitiesRestrictCriteria('glpi_tickets')`; project tasks com LEFT JOIN em
|
||||
`glpi_projects` para o nome do projeto.
|
||||
- **Render server-side**: `TemplateRenderer::getInstance()->display('@mindscrum/board.html.twig', [...])`
|
||||
a partir de `front/board.php` (sem `inc/includes.php` — KB-PLUGIN-028; namespace
|
||||
`@<key>` auto — KB-PLUGIN-036).
|
||||
- **Drop → `ajax/move.php`**: `fetch` POST com header `X-Glpi-Csrf-Token` +
|
||||
`X-Requested-With: XMLHttpRequest` (KB-PLUGIN-010). O endpoint **não** chama
|
||||
`checkCSRF` (o kernel já fez), só `checkLoginUser` + `haveRight` + `canUpdateItem`,
|
||||
e delega para o model.
|
||||
- **Drag-drop sem dependência**: HTML5 DnD nativo (o core tem `sortable.js` em
|
||||
`public/lib/`, mas o nativo dispensa registro de asset e resolve o PoC).
|
||||
|
||||
## Regra de escrita — SEMPRE pelo model nativo
|
||||
|
||||
```php
|
||||
$item = new $itemtype(); // 'Ticket' | 'ProjectTask' (allowlist!)
|
||||
$item->getFromDB($items_id);
|
||||
$input = ['id' => $items_id];
|
||||
$itemtype === 'Ticket'
|
||||
? $input['status'] = ColumnMap::ticketStatusForColumn($col)
|
||||
: $input['projectstates_id'] = ColumnMap::projectStateForColumn($col);
|
||||
$ok = $item->update($input); // preserva histórico (Log), date_mod e regras
|
||||
```
|
||||
|
||||
Nunca `UPDATE` direto no banco: perderia histórico e validações. Validado:
|
||||
`Ticket.status 2→4` e `2→5`, `ProjectTask.projectstates_id 1→3` — todos
|
||||
`update()=true`, refletidos no banco e reversíveis.
|
||||
|
||||
## ⚠️ Achado — `update(['status' => 5])` NÃO exige solução
|
||||
|
||||
Colocar um chamado em **Resolvido (5)** ou **Fechado (6)** via `$ticket->update()`
|
||||
**funciona sem a solução** que o formulário ITIL de solução normalmente exige
|
||||
(`update()=true`, `status=5` no banco, sem mensagem de bloqueio).
|
||||
|
||||
Ou seja, `update(status)` **bypassa a regra de negócio da solução**. Implicações:
|
||||
- Para um Kanban, mover para "Concluído" muda o status limpo — ótimo para UX.
|
||||
- Mas se o processo exige registrar solução, o plugin precisa **impor isso na sua
|
||||
camada** (pedir texto e gravar via `ITILSolution`) em vez de só `update(status)`.
|
||||
- Não confiar que "mudar status = disparar as regras do formulário ITIL".
|
||||
|
||||
## Gotchas confirmados
|
||||
|
||||
- **Bump de versão** (0.1.0→0.2.0) marca o plugin como "Para atualizar"; rodar
|
||||
`bin/console plugin:install <key>` + `plugin:activate <key>` para reativar
|
||||
(KB-PLUGIN-013). Install/rights são idempotentes.
|
||||
- **Twig cacheia em produção**: template novo compila na 1ª vez, mas ao **editar**
|
||||
um `.twig` limpar `/var/glpi/files/_cache/*-production/templates`.
|
||||
- **Entidade em ProjectTask**: `glpi_projecttasks` não tem `entities_id` próprio
|
||||
(herda do projeto). O PoC não restringe tasks por entidade — pendência: filtrar
|
||||
via join com `glpi_projects.entities_id`.
|
||||
|
||||
## Próxima evolução
|
||||
|
||||
Colunas **configuráveis** (criar/renomear, mapeadas a estados nativos, incl.
|
||||
`ProjectState` customizados) — hoje são fixas no `ColumnMap`. É o requisito de
|
||||
"budgets herdam estados nativos" levado adiante.
|
||||
Loading…
Reference in a new issue