# Типы полей

> Как поля приводятся из строки CLI и из JSON, примеры push и тексты ошибок 422.

## Как работает приведение

`POST /v1/integrations/{slug}/fields` принимает JSON-объект `{"ключ": значение}`.
Каждое значение приводится к типу поля, которое объявили в редакторе. Если хоть одно
не проходит проверку — отклоняется весь запрос (`422 invalid_fields`), с текстом
ошибки для каждого поля.

`sparku push` умеет два синтаксиса присваивания:

- `поле=значение` — отправляет **строку**, сервер сам приводит её к типу поля;
- `поле:=json` — отправляет значение **как есть**, распарсив как JSON
  (`items:='[{"title":"a"}]'`, `done:=true`, `state:=null`).

`null` (через `поле:=null`) очищает поле, не удаляя его из схемы.

## Таблица типов

| Тип | Значение в `push` | Приведение из строки CLI | Примечание |
|---|---|---|---|
| `text` | `"prod"` | берётся как есть | обрезается по лимиту длины (по умолчанию 120 символов), не отклоняется |
| `number` | `72` | `Double(строка)` | единица, `min`/`max` для шкал и кольца; копит историю для графика |
| `progress` | `0.7` | число 0…1, либо `"70%"` | строго 0…1 после приведения |
| `bool` | `true` | `true/false/yes/no/on/off/1/0` (без учёта регистра) | для тумблеров и эквалайзера |
| `state` | `"failed"` | строка, должна входить в список состояний поля | у каждого состояния — иконка, цвет, анимация, вспышка при переходе |
| `time` | ISO 8601 или `+5m` | `+5m`, `-1h30m`, ISO 8601 | таймеры тикают внутри SparkU — слать `push` каждую секунду не нужно |
| `image` | путь или base64 (≤ 256 КБ) | путь `/…` или `~/…`, либо base64 (можно с `data:...,`) | только PNG/JPEG |
| `url` | `"https://…"` | строка со схемой | для действий кнопок; `javascript:` и `data:` отклоняются |
| `list` | `[{"title": "…"}]` | только `поле:=json` | до 50 строк |

## Примеры push для каждого типа

```bash
sparku push deploy title="Деплой прода"
sparku push server cpu=37.5
sparku push build progress=70%          # эквивалент progress=0.7
sparku push server ready=true
sparku push build stage=failed          # значение должно быть объявлено в поле
sparku push timer ends=+5m              # через 5 минут от текущего момента
sparku push timer ends=2026-10-01T12:00:00Z   # ISO 8601
sparku push now cover=~/cover.png
sparku push deploy link=https://ci.example.com/builds/482
sparku push queue items:='[{"title": "Сборка"}, {"title": "Тесты", "state": "running"}]'
```

## Формат `time`

Принимается одно из:

- **Относительное смещение от текущего момента**: `+5m`, `-1h30m`, `+90s`, `+2d`.
  Единицы — `d`, `h`, `m`, `s`, можно комбинировать, но только в порядке убывания
  (`1h30m`, не `30m1h`). Одно поле `time` работает и таймером (`+5m` — обратный
  отсчёт), и секундомером (`-10m` — время, прошедшее с момента).
- **ISO 8601** с временем и часовым поясом (`2026-10-01T12:00:00Z`,
  с долями секунды тоже подходит).
- **UNIX-время** — только числом в `поле:=1699999999`, не строкой в `поле=…`.

## `list` — объекты строк

Каждый элемент — объект `{"title", "subtitle"?, "value"?, "state"?, "icon"?}` или
просто строка (тогда она становится `title`). Обязателен только `title`. Не больше
50 элементов на запись.

```bash
sparku push queue items:='[
  "Простая строка",
  {"title": "Сборка", "subtitle": "main", "state": "running"},
  {"title": "Тесты", "value": "42/50", "icon": "checkmark"}
]'
```

## `image`

- Абсолютный путь (`/Users/…`) или путь с `~` — файл должен существовать и быть
  PNG или JPEG.
- Или содержимое в base64 (можно с префиксом `data:image/png;base64,` — он
  отбрасывается). Ограничение — 256 КБ после декодирования; больше — отклоняется.

## Тексты ошибок 422 (из кода)

Ответ `422 invalid_fields` содержит `fields: [{field, message}]`, а объединённое
сообщение — `field: message; field2: message2`. Примеры реальных текстов:

```
progress: ожидалось 0…1, пришло 70
progress: ожидалось число 0…1, пришло «много»
cpu: ожидалось число, пришло «abc»
ready: ожидалось true или false, пришло «maybe»
stage: ожидалось одно из: queued, running, passed, failed; пришло «cancelled»
ends: ожидалось время (ISO 8601, +5m, -1h30m или UNIX-время), пришло «завтра»
cover: файла нет: /Users/me/cover.png
cover: поддерживаются только PNG и JPEG
cover: base64 не разобран или картинка больше 256 КБ
link: ожидалась ссылка со схемой (https://…), пришло «example.com»
link: схема «javascript» не поддерживается
items: ожидался массив, пришло объект
items: не больше 50 строк, пришло 63
items[0]: нет title
title: ожидалась строка, пришло массив
```

Ошибка не объявленного поля:

```
поле не объявлено в интеграции «deploy»; есть: title, progress, stage
поле не объявлено: у интеграции «deploy» пока нет полей
```

Оба текста одновременно попадают в ответ API и в журнал интеграции в Настройках.
