KB-024 (silent-success do delete): ambas correções implementadas — makeRequest propaga 4xx/5xx (commit 09ce92c) e glpi_projecttask_delete via ORM (0ca94fc). KB-023 (InputValidation): arquivos agora realmente implementados; corrige itens do rascunho que não foram feitos (buildInputFromArgs, project_update estendido). KB-026 (snapshot): atualizado para v1.2.0 — 19 tools, ProjectTask CRUD, métricas. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
98 lines
4.9 KiB
Markdown
98 lines
4.9 KiB
Markdown
---
|
|
id: KB-PLUGIN-023
|
|
title: mcprotocol — InputValidation extraída como classe utilitária compartilhada
|
|
domain: plugin-dev
|
|
tags:
|
|
- mcp
|
|
- tools
|
|
- validation
|
|
- refactor
|
|
- patterns
|
|
status: active
|
|
severity: medium
|
|
created_at: 2026-05-26
|
|
updated_at: 2026-06-22
|
|
applies_to:
|
|
- glpi-11
|
|
- mcprotocol-plugin
|
|
related_records:
|
|
- KB-PLUGIN-022
|
|
- KB-PLUGIN-019
|
|
---
|
|
|
|
# mcprotocol — InputValidation extraída como classe utilitária compartilhada
|
|
|
|
## Contexto
|
|
|
|
KB-PLUGIN-022 documentou os padrões `resolveReference`, `normalizeDate`, validação agregada e response com `applied` como métodos privados em `ProjectTools`. Esse KB previu que **na introdução do segundo handler** os helpers seriam extraídos para uma classe utilitária. Esse momento chegou ao implementar `glpi_projecttask_create`.
|
|
|
|
## Decisão
|
|
|
|
Extraído `src/InputValidation.php` (namespace `GlpiPlugin\Mcprotocol`) com métodos **estáticos públicos** reutilizáveis em qualquer handler de tool:
|
|
|
|
| Método | Responsabilidade |
|
|
|---|---|
|
|
| `resolveReference($table, $value, $field, &$errors, $nameCol='name')` | Aceita int ou string e devolve ID validado. Suporta coluna de busca customizada (ex: `name` em `glpi_users`). |
|
|
| `normalizeDate($value, $field, &$errors)` | Aceita `YYYY-MM-DD` ou `YYYY-MM-DD HH:MM:SS`, normaliza pro formato GLPI. |
|
|
| `validateDateRange($start, $end, $startField, $endField, &$errors)` | Garante `end >= start` quando ambos informados. |
|
|
| `validateIntRange($value, $field, $min, $max, &$errors)` | Valida inteiro em intervalo (ex: `percent_done` 0-100). |
|
|
|
|
## Mudanças realizadas
|
|
|
|
> ⚠️ **Reconciliação 2026-06-22.** A versão original deste KB (26/05) era aspiracional —
|
|
> os arquivos só foram **realmente implementados em 2026-06-22** (plugin v1.2.0, repo dev
|
|
> `origin`). A lista abaixo reflete o que de fato entrou; alguns itens previstos no
|
|
> rascunho original NÃO foram feitos e estão marcados como 🔲 planejado.
|
|
|
|
- ✅ **Novo arquivo:** `src/InputValidation.php` (commit `e588556`) — métodos
|
|
`resolveReference`, `normalizeDate`, `validateDateRange`, `validateIntRange`.
|
|
- ✅ **Refatorado:** `src/ProjectTools.php` (commit `2e4cdf7`) — `resolveStateId` delega a
|
|
`InputValidation::resolveReference`, eliminando a duplicação. Mantém fallback de 0.
|
|
- 🔲 **Planejado (não feito):** método `buildInputFromArgs($args, $isUpdate)` em
|
|
`ProjectTools` — `handleCreate` ainda monta o input inline.
|
|
- 🔲 **Planejado (não feito):** estender `glpi_project_update` com datas/estado/tipo —
|
|
hoje ainda aceita só `name`/`content`/`percent_done`.
|
|
- ✅ **Novo arquivo:** `src/ProjectTaskTools.php` (commit `0ca94fc`) — usa `InputValidation`
|
|
desde o início, com **4 tools**: `glpi_projecttask_get/create/update/delete` (mais do
|
|
que as 2 previstas). O `buildInput($args, $isUpdate)` ali implementa o padrão DRY de
|
|
montagem de input que era previsto para o ProjectTools.
|
|
- ✅ **Atualizado:** `src/ToolRegistry.php` (commit `0ca94fc`) — registra `ProjectTaskTools::getTools()` no merge.
|
|
|
|
## Convenções de uso
|
|
|
|
1. **Acumular erros** — qualquer handler que valida múltiplos campos deve usar a assinatura `&$errors` e lançar UMA exception ao final. Nunca múltiplas.
|
|
|
|
2. **Coluna de busca por nome** — `resolveReference` aceita `$nameCol`. Para tabelas onde o campo descritivo não se chama `name`, passar explicitamente:
|
|
```php
|
|
InputValidation::resolveReference('glpi_users', $args['users_id'], 'users_id', $errors, 'name');
|
|
```
|
|
|
|
3. **Validação prévia ao ORM** — todos os helpers rodam ANTES de `$obj->add()` ou `$obj->update()`. Se houver erro, exception é lançada e o ORM nunca é chamado. Evita erros de SQL/ORM crípticos.
|
|
|
|
4. **Response com `applied`** — handlers devem sempre retornar o input efetivamente aplicado:
|
|
```php
|
|
return ['status'=>'success', 'id'=>$newId, 'message'=>'...', 'applied'=>$input];
|
|
```
|
|
|
|
## Tabelas comuns para `resolveReference`
|
|
|
|
| Tabela | Coluna de nome | Uso típico |
|
|
|---|---|---|
|
|
| `glpi_projectstates` | `name` | Estado de projeto/tarefa |
|
|
| `glpi_projecttypes` | `name` | Tipo de projeto |
|
|
| `glpi_projecttasktypes` | `name` | Tipo de tarefa |
|
|
| `glpi_users` | `name` (login) | Responsável |
|
|
| `glpi_groups` | `name` | Grupo |
|
|
| `glpi_entities` | `name` | Entidade |
|
|
| `glpi_itilcategories` | `name` | Categoria de chamado |
|
|
| `glpi_locations` | `name` | Localização |
|
|
|
|
## Próximos handlers candidatos a usar `InputValidation`
|
|
|
|
- `glpi_ticket_create` — `users_id_recipient`, `users_id_lastupdater`, `itilcategories_id`, datas
|
|
- `glpi_ticket_update` — idem + estados (1=New, 2=Processing, etc. já são enums numéricos GLPI)
|
|
- Futuras tools de Computer/Asset (`glpi_computer_create`, etc.)
|
|
|
|
## Validação end-to-end
|
|
|
|
Padrão validado em produção criando o projeto VALGROUP (28 tarefas em hierarquia) através das tools. Erros de validação retornados claramente, datas normalizadas, estados resolvidos por nome ("New" → 1, "Processing" → 2). Aplicado conforme esperado.
|