diff --git a/docs/API.md b/docs/API.md index d0b90e8..f0d7097 100644 --- a/docs/API.md +++ b/docs/API.md @@ -97,11 +97,12 @@ Sem vínculo (nem projeto nem entidade) → **nada é enviado** (log e retorno). | GET | `/roles.json` | papéis (para auto-membership) | | GET | `/users.json?limit=100&offset=N` | usuários (cache p/ mapeamento; paginado) | | GET | `/projects/{id}/issue_categories.json` | categorias (por projeto) | +| GET | `/custom_fields.json` | definições de campos personalizados (filtra `customized_type=project`) | ### Escrita | Método | Endpoint | Uso | |---|---|---| -| POST | `/projects.json` | criar projeto Redmine (aba Projeto/Entidade) | +| POST | `/projects.json` | criar projeto Redmine (aba Projeto/Entidade) — inclui `custom_field_values` | | POST | `/issues.json` | **criar a issue** a partir do chamado | | PUT | `/issues/{id}.json` | sincronizar **status** da issue | | POST | `/time_entries.json` | **lançar tempo** da TicketTask | @@ -138,10 +139,35 @@ Sem vínculo (nem projeto nem entidade) → **nada é enviado** (log e retorno). |---|---| | `status_id` | `config.status_map[Ticket.status]` (no `item_update` do Ticket) | +### Criação de projeto (`POST /projects.json` — abas Redmine de Projeto/Entidade) +| Campo Redmine (`project.*`) | Origem | +|---|---| +| `name`, `description`, `is_public` | formulário da aba | +| `identifier` | formulário, **normalizado para minúsculas** (regra do Redmine) | +| `parent_id` | dropdown "Subprojeto de" | +| `enabled_module_names` | multiselect "Módulos" | +| `custom_field_values` | `{ "": "", ... }` — campos personalizados de projeto | + +Os campos personalizados são renderizados **dinamicamente** a partir de +`metadata_cache.project_custom_fields` (populado pelo "Sincronizar Metadados" via +`GET /custom_fields.json`). Em instâncias onde eles são **obrigatórios** (ex.: +produção Mindtek: "Tipo de Projeto" e "Tipo de Faturamento"), a criação falha com +422 se não forem enviados. + ### Conversões importantes - **Tempo:** GLPI grava `actiontime` em **segundos** (int); Redmine espera **horas decimais**. `5400 → 1.5`. - **Subject:** limite de 255 chars no Redmine → truncado. - **HTML:** descrições do GLPI (TinyMCE) passam por `RichText::getTextFromHtml`. +- **Identificador de projeto:** minúsculas/números/traços — normalizado em `createProjectFull()`. + +### Regras que variam por instância/projeto do Redmine (validar em produção) +- **Custom fields de projeto** podem ser obrigatórios na criação (ver acima). +- **Atividade do time entry é por projeto**: a `default_activity_id` precisa estar + habilitada no projeto de destino (senão 422 "não está incluso na lista"). +- **Comentário do time entry** pode ser obrigatório: task sem descrição usa o + fallback "Tempo lançado via GLPI (chamado #N)". +- **Tracker é por projeto**: default global vazio = Redmine usa o default do projeto. +- Issues só podem ser criadas em projetos **ativos** (o dropdown de vínculo já filtra). ---