34 lines
4.2 KiB
Markdown
34 lines
4.2 KiB
Markdown
# Общие правила API v1
|
||
|
||
Это проектируемые публичные контракты Invest Harness. Базовый путь /v1; JSON UTF-8; HTTPS обязателен. Внутренние API движка не являются публичным контрактом.
|
||
|
||
## Типы и ошибки
|
||
|
||
Id — непрозрачная строка 1–128 символов; Timestamp — RFC3339 UTC; Digest — sha256: и 64 hex-символа; Revision — положительное целое. Денежные суммы задаются integer minor units + currency; CPU в millicores, память и файлы в bytes, интервалы в seconds. Дата расписания содержит отдельно IANA timezone.
|
||
|
||
Ошибка: {"error":{"code":"CONFIG_INVALID","message":"Настройки не соответствуют схеме","details":[{"path":"/lookbackDays","code":"maximum"}],"requestId":"req_example"}}. Никаких секретов или stack trace в ответе.
|
||
|
||
| HTTP | Значение |
|
||
|---|---|
|
||
| 400 | Невалидный синтаксис запроса |
|
||
| 401 | Нет действительной идентичности |
|
||
| 403 | Нет прав на известную разрешённую к раскрытию операцию |
|
||
| 404 | Ресурс отсутствует или скрыт от вызывающего |
|
||
| 409 | Конфликт состояния, digest, lease или idempotency payload |
|
||
| 412 | Устаревший If-Match |
|
||
| 422 | Валидный JSON нарушает контракт, зависимости или policy |
|
||
| 429 | Квота / rate limit, Retry-After |
|
||
| 503 | Временная недоступность зависимости |
|
||
|
||
## Доступ и повторные запросы
|
||
|
||
Сессия пользователя или сервисный bearer token. Membership и ресурсный tenant проверяются на каждой операции. Публичное чтение каталога не даёт доступ к приватным зависимостям. Cookie-мутации требуют CSRF-защиты. Запросы публикации, запуска, retry и resume требуют Idempotency-Key; область ключа tenant + principal + method + path. Hash тела связывается с ключом; другое тело → 409. Результат хранится минимум 7 дней, а уникальность attemptId и schedule occurrence действует независимо от TTL ключа.
|
||
|
||
PATCH/PUT изменяемых ресурсов требуют If-Match, ответ содержит ETag. Списки: limit 1..100, непрозрачный cursor, ответ {items:[], nextCursor:null}. Cursor фиксирует сортировку createdAt,id и фильтры, не заменяет авторизацию. DELETE с асинхронной очисткой возвращает 202 и operationId.
|
||
|
||
## События и файлы
|
||
|
||
SSE endpoint принимает Last-Event-ID; SSE cursor монотонен в пределах Run и назначается сервером, отдельно от runner eventId. После retention слишком старый cursor возвращает 410 с указанием получить snapshot. Повторные runner events дедуплицируются по attemptId + eventId. SSE data содержит RunEvent, а transport id — серверный cursor; клиент хранит cursor для reconnect. SSE не является источником истины о состоянии: GET Run возвращает канонический snapshot.
|
||
|
||
Binary upload выполняется по scoped grant. Он содержит uploadId, url, expiresAt, maxBytes, requiredHeaders; постоянные записи хранят artifactId, не подписанный URL. Grant не считается подтверждением загрузки: finalize проверяет размер, digest и объект. По умолчанию ошибки не повторяются автоматически, кроме явных transient ошибок с ограниченным backoff и jitter.
|