127 lines
4.3 KiB
Markdown
127 lines
4.3 KiB
Markdown
|
|
# Portal de importação Excel → Clarizen WorkItem
|
||
|
|
|
||
|
|
Portal web MVP para enviar um arquivo `.xlsx` e criar ou atualizar **WorkItems** no Planview Adaptive Work (Clarizen), usando [@arco/clarizen-lib](https://gitea.rivuslab.com/leonardotoniolo/clarizen-lib).
|
||
|
|
|
||
|
|
## Pré-requisitos
|
||
|
|
|
||
|
|
- [Node.js](https://nodejs.org/) 18 ou superior
|
||
|
|
- Acesso ao Gitea da Rivus Lab (para instalar `clarizen-lib` via Git)
|
||
|
|
- Chave de API do Adaptive Work
|
||
|
|
|
||
|
|
## Instalação
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd update_xlsx
|
||
|
|
npm install
|
||
|
|
```
|
||
|
|
|
||
|
|
Se o repositório `clarizen-lib` for privado, configure autenticação Git (SSH ou token HTTPS) antes do `npm install`.
|
||
|
|
|
||
|
|
## Configuração
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cp .env.example .env
|
||
|
|
```
|
||
|
|
|
||
|
|
Edite `.env` na raiz do projeto:
|
||
|
|
|
||
|
|
```env
|
||
|
|
CLARIZEN_BASE_URL=https://api.clarizen.com
|
||
|
|
CLARIZEN_API_KEY=sua_chave_aqui
|
||
|
|
PORT=3000
|
||
|
|
```
|
||
|
|
|
||
|
|
Alternativa aceita: `API_KEY_AW` em vez de `CLARIZEN_API_KEY`.
|
||
|
|
|
||
|
|
O carregador também tenta `../clarizen-lib/.env` se existir (desenvolvimento local no monorepo ARCO).
|
||
|
|
|
||
|
|
## Executar
|
||
|
|
|
||
|
|
```bash
|
||
|
|
npm start
|
||
|
|
```
|
||
|
|
|
||
|
|
Abra [http://localhost:3000](http://localhost:3000).
|
||
|
|
|
||
|
|
| Comando | Descrição |
|
||
|
|
| -------- | --------- |
|
||
|
|
| `npm start` | Sobe o portal (Express + UI estática) |
|
||
|
|
| `npm run check:clarizen` | Verifica se a lib foi instalada e compilada (`OK Clarizen`) |
|
||
|
|
|
||
|
|
## Formato do Excel
|
||
|
|
|
||
|
|
- **Linha 1:** cabeçalhos — pode usar o **nome do campo** na API ou o **label** exibido no Adaptive Work (ex.: `ExternalID` ou `External ID`, `CreatedOn` ou `Created On`).
|
||
|
|
- **Linhas 2+:** um WorkItem por linha.
|
||
|
|
- Colunas vazias são ignoradas.
|
||
|
|
|
||
|
|
Na importação, o portal consulta o metadata de `WorkItem` no Clarizen e resolve cada cabeçalho para o nome técnico do campo. Colunas não reconhecidas retornam erro 400 antes de criar/atualizar registros.
|
||
|
|
|
||
|
|
### Cabeçalhos: nome vs label
|
||
|
|
|
||
|
|
| Cabeçalho no Excel | Campo enviado à API |
|
||
|
|
|--------------------|---------------------|
|
||
|
|
| `Name` | `Name` |
|
||
|
|
| `Name` (label) | `Name` |
|
||
|
|
| `ExternalID` | `ExternalID` |
|
||
|
|
| `External ID` | `ExternalID` |
|
||
|
|
| `Created On` | `CreatedOn` |
|
||
|
|
|
||
|
|
Após a importação, a UI mostra o mapeamento **Excel → API** (`headerMapping`).
|
||
|
|
|
||
|
|
### Create vs update
|
||
|
|
|
||
|
|
| Situação | Ação |
|
||
|
|
| -------- | ---- |
|
||
|
|
| Linha **sem** valor em `ExternalID` (ou coluna mapeada para ele) | **Criar** novo WorkItem |
|
||
|
|
| Linha **com** `ExternalID` preenchido | **Atualizar** WorkItem existente com esse ID externo |
|
||
|
|
|
||
|
|
Aliases de cabeçalho aceitos: `ExternalId`, `External ID`, `externalId` → `ExternalID`.
|
||
|
|
|
||
|
|
### Exemplo (labels)
|
||
|
|
|
||
|
|
| Name | External ID | Description | Start Date |
|
||
|
|
|------|-------------|-------------|------------|
|
||
|
|
| Tarefa nova | | Descrição da tarefa | 2026-06-01 |
|
||
|
|
| Tarefa existente | EXT-001 | Descrição atualizada | 2026-06-15 |
|
||
|
|
|
||
|
|
### Exemplo (nomes API)
|
||
|
|
|
||
|
|
| Name | ExternalID | Description | StartDate |
|
||
|
|
|------|------------|-------------|-----------|
|
||
|
|
| Tarefa nova | | Descrição da tarefa | 2026-06-01 |
|
||
|
|
| Tarefa existente | EXT-001 | Descrição atualizada | 2026-06-15 |
|
||
|
|
|
||
|
|
A lógica de create/update está em `src/import/config.ts` e `src/import/processor.ts` para facilitar alterações futuras.
|
||
|
|
|
||
|
|
## Estrutura
|
||
|
|
|
||
|
|
```text
|
||
|
|
update_xlsx/
|
||
|
|
├── .env.example
|
||
|
|
├── public/ # UI (HTML, CSS, JS)
|
||
|
|
├── src/
|
||
|
|
│ ├── server.ts
|
||
|
|
│ ├── clarizen/ # cliente e auth
|
||
|
|
│ ├── excel/ # leitura xlsx
|
||
|
|
│ ├── import/ # create/update, field-headers (name/label)
|
||
|
|
│ └── routes/ # POST /api/import
|
||
|
|
└── README.md
|
||
|
|
```
|
||
|
|
|
||
|
|
## Limitações (MVP)
|
||
|
|
|
||
|
|
- Apenas entidade **WorkItem** (sem seleção na UI).
|
||
|
|
- Campos de referência (`Manager`, `Parent`, etc.) podem exigir formato específico da API; o MVP envia valores escalares simples do Excel.
|
||
|
|
- Processamento sequencial linha a linha (sem bulk API).
|
||
|
|
|
||
|
|
## Problemas comuns
|
||
|
|
|
||
|
|
| Sintoma | O que fazer |
|
||
|
|
| -------- | ------------ |
|
||
|
|
| Erro ao clonar `clarizen-lib` no `npm install` | Verificar login SSH/HTTPS no Gitea |
|
||
|
|
| Banner amarelo na página | Conferir `.env` e `npm run check:clarizen` |
|
||
|
|
| `WorkItem não encontrado para ExternalID=...` | O ID externo não existe no tenant; use create (linha sem ExternalID) ou corrija o valor |
|
||
|
|
| Erro 400 no upload | Arquivo deve ser `.xlsx` / `.xls` com cabeçalho e ao menos uma linha de dados |
|
||
|
|
| `Colunas não reconhecidas: ...` | Cabeçalho não bate com nome nem label de campo WorkItem no seu tenant |
|
||
|
|
| `Label ambíguo` | Dois campos distintos compartilham o mesmo label — use o nome técnico do campo |
|