knowledge-base/records/plugin-dev/KB-PLUGIN-039-glpi11-project-ticket-pm-substrate.md
Gemini c51827a57c KB-PLUGIN-039: substrato nativo GLPI 11 de projetos/chamados reutilizavel (base do mindscrum)
Mapeia o que o core ja entrega (Kanban trait single-itemtype, ProjectTaskLink
com 4 tipos de precedencia, ProjectTask_Ticket, PlanningEvent +
checkAlreadyPlanned, TeamworkInterface, Gantt como plugin) e a tabela
herdar-vs-construir do plugin mindscrum.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 15:03:24 -03:00

127 lines
6 KiB
Markdown

---
id: KB-PLUGIN-039
title: "GLPI 11 — Substrato nativo de gestão de projetos/chamados (Kanban, precedência, planning) reutilizável por plugin"
domain: plugin-dev
tags:
- glpi11
- plugin
- kanban
- project
- projecttask
- ticket
- planning
- gantt
- precedence
- teamwork
- mindscrum
- architecture
status: active
severity: high
created_at: 2026-07-10
updated_at: 2026-07-10
applies_to:
- GLPI 11.0.8 dev (container devportal_glpi)
- plugin mindscrum (Kanban unificado + Gantt de recursos)
related_records:
- KB-PLUGIN-028
- KB-PLUGIN-029
- KB-PLUGIN-031
- KB-PLUGIN-036
---
# GLPI 11 — Substrato nativo de gestão de projetos/chamados reutilizável por plugin
Mapa do que o **core do GLPI 11 já entrega** para gestão de projetos, chamados,
tarefas, técnicos, precedência e agenda — levantado por leitura do código-fonte
em `/var/www/glpi/src/` (não é suposição; cada item foi verificado no fonte).
Base de decisão do plugin **mindscrum** (Kanban unificado + Gantt de recursos):
**herdar o motor, construir só as superfícies que faltam.**
## Kanban nativo — trait + interface, single-itemtype
- `Glpi\Features\Kanban` (trait) + `Glpi\Features\KanbanInterface` (contrato).
- **Quem implementa:** `Project` e `CommonITILObject` (`use Glpi\Features\Kanban;
implements KanbanInterface, TeamworkInterface`) → logo **Ticket, Change e Problem
já têm Kanban nativo**, além de Projeto.
- Cada board é de **um único itemtype**. Não há board multi-itemtype nativo.
**Este é o gap que o mindscrum preenche** (juntar Ticket + ProjectTask numa tela).
- **Coluna = `column_field`:** `status` para ITIL (`getAllKanbanColumns('status')`
em `CommonITILObject`), `projectstates_id` para `Project`/`ProjectTask`.
Mover card grava o status/estado nativo — a regra de transição é do GLPI.
- Métodos-chave do contrato (`KanbanInterface`): `getDataToDisplayOnKanban`,
`getKanbanColumns`, `getAllKanbanColumns`, `showKanban`, `getAllForKanban`,
`canModifyGlobalState`, `prepareKanbanStateForUpdate` (hook para vetar/alterar
save), `canOrderKanbanCard`, e o ponto de extensão de plugin **`getKanbanPluginFilters($itemtype)`**.
- **Persistência do board:** `Item_Kanban::saveStateForItem($itemtype,$items_id,$state)`
/ `loadStateForItem()` → tabela `glpi_items_kanbans` (state em JSON, por usuário
ou global). Passa por `prepareKanbanStateForUpdate()` antes de gravar.
- **UI reutilizável:** componente Twig `templates/components/kanban/kanban.html.twig`
+ componente JS do Kanban do core.
## Estados / colunas customizáveis
- `ProjectState` (dropdown) é a lista de estados de projeto/task — **customizável**,
serve de coluna. Status de chamado é fixo (enum 1..6: novo, atrib., planejado,
pendente, resolvido, fechado). Reconciliar esses dois modelos numa coluna única é
o **miolo da regra** do board unificado.
## Precedência entre tarefas (base de Gantt) — JÁ EXISTE
- `ProjectTaskLink` → tabela `glpi_projecttasklinks`, campos
`projecttasks_id_source`, `projecttasks_id_target`, `type`.
- **4 tipos clássicos:** `finish_to_start=0`, `start_to_start=1`,
`finish_to_finish=2`, `start_to_finish=3`. É exatamente o modelo de dependência
de um Gantt — não precisa criar tabela nova para precedência.
## Elo Projeto ↔ Chamado — JÁ EXISTE
- `ProjectTask_Ticket` → tabela `glpi_projecttasks_tickets`, liga
`projecttasks_id``tickets_id`. O relacionamento que o board unificado quer
representar já é modelado (e a classe já cruza `ProjectState`).
## Planning / agenda / alocação — JÁ EXISTE
- `ProjectTask` **é plannable:** `use Glpi\Features\PlanningEvent`, campos
`plan_start_date`/`plan_end_date` e `real_start_date`/`real_end_date`; implementa
`CalDAVCompatibleItemInterface` e `TeamworkInterface`.
- **Detecção de conflito de recurso:** `Planning::checkAlreadyPlanned($users_id,
$begin, $end)` já avisa quando um técnico é agendado em dobro — espinha dorsal da
visão "capacidade por técnico" do Gantt de recursos.
- Também plannable e alimentando o Planning: `TicketTask`, `ChangeTask`,
`ProblemTask`, `PlanningExternalEvent`, `Reminder`.
## Equipe / técnicos — TeamworkInterface
- `Glpi\Features\TeamworkInterface`: `getTeamRoles()`, `getTeamRoleName()`,
`getTeamItemtypes()`, `addTeamMember()`, `deleteTeamMember()`, `getTeam()`.
- Papéis via `Team::ROLE_*`: Projeto usa `ROLE_OWNER`/`ROLE_MEMBER`; ITIL usa
`ROLE_REQUESTER`/`ROLE_OBSERVER`/`ROLE_ASSIGNED`. Vínculo técnico↔tarefa via
`ProjectTaskTeam` / `ProjectTeam`.
## Gantt nativo é PLUGIN, não core
- O core apenas condiciona: `$plugin->isActivated('gantt')` e expõe o campo
`show_on_global_gantt`. O Gantt em si vem do plugin `gantt`. Ou seja, **estender
a gestão de projeto por plugin é o caminho oficial** — o mindscrum segue o mesmo
padrão, com foco em Gantt de *recursos* (por técnico), que o nativo não cobre.
## Implicações para o mindscrum
| Necessidade | Veredito | O que usar |
|---|---|---|
| Mover card muda status | herdar | `update()` nativo do itemtype (Ticket/ProjectTask) |
| Colunas = estados nativos | herdar | `status` (ITIL) / `ProjectState` |
| Precedência de tarefas | herdar | `ProjectTaskLink` (4 tipos) |
| Projeto ↔ chamado | herdar | `ProjectTask_Ticket` |
| Conflito de alocação | herdar | `Planning::checkAlreadyPlanned()` |
| Técnicos por tarefa | herdar | `TeamworkInterface` / `ProjectTaskTeam` |
| **Board multi-itemtype (Ticket+ProjectTask)** | **construir** | página full-screen do plugin (nativo é single-itemtype) |
| **Timeline de capacidade por técnico** | **construir** | consome Planning; render próprio |
| Chat/notas de execução no card | construir | tickets têm `ITILFollowup`; ProjectTask exige tabela auxiliar leve |
## Regra para agentes
Antes de recriar qualquer coisa de projeto/chamado/agenda no mindscrum, checar
esta tabela: quase tudo é **herança do core**, não desenvolvimento novo. Escrever
de volta sempre pelos models nativos (`->update()`), nunca `UPDATE` direto — assim
transição de status, histórico (`Log`) e regras do GLPI continuam válidos.