- Novo runbook KB-PLUGIN-031: nascimento do plugin ate validacao E2E no GLPI dev (scaffold, Forgejo local, deploy CT100, console, bootstrap Kernel para testes CLI). Validado de ponta a ponta com o assetinherit. - Registros KB-PLUGIN-021..030 existiam apenas no disco (drift) e foram incluidos no versionamento; index.json sincronizado via kb-fix. - Ignora lixo AppleDouble/.DS_Store do macOS. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
85 lines
4.1 KiB
Markdown
85 lines
4.1 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-05-26
|
|
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
|
|
|
|
- **Novo arquivo:** `src/InputValidation.php`
|
|
- **Refatorado:** `src/ProjectTools.php` — removeu helpers privados, agora chama `InputValidation::*`. Também ganhou método `buildInputFromArgs($args, $isUpdate)` que centraliza a montagem do input para create/update (DRY).
|
|
- **Estendido:** `glpi_project_update` agora aceita os mesmos campos do create (datas, estado, tipo) — antes só aceitava name/content/percent_done.
|
|
- **Novo arquivo:** `src/ProjectTaskTools.php` — usa `InputValidation` desde o início, com 2 tools: `glpi_projecttask_create` e `glpi_projecttask_get`.
|
|
- **Atualizado:** `src/ToolRegistry.php` — 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.
|