knowledge-base/records/plugin-dev/KB-PLUGIN-023-mcprotocol-inputvalidation-extracted.md
Rodolpho Lopes f072b1cde7 docs: marca bugs do mcprotocol como resolvidos em v1.2.0
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>
2026-06-22 22:16:02 +00:00

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.