diff --git a/1c-analyst/references/devprom-alm-api.md b/1c-analyst/references/devprom-alm-api.md index aaa4bda..420b258 100644 --- a/1c-analyst/references/devprom-alm-api.md +++ b/1c-analyst/references/devprom-alm-api.md @@ -36,6 +36,36 @@ - **PATCH не поддерживается** — HTTP 405. Обновление только через PUT. - **Успешный ответ на создание:** иногда возвращается как объект, иногда — как массив с одним элементом. Учитывать оба случая. +### ⚠ Критично: сервер молча отбрасывает незнакомые поля + +Devprom REST API **не возвращает ошибку**, если имя поля в теле POST +не соответствует схеме сущности. Поле просто игнорируется, запись +создаётся с остальными полями, HTTP 200, `UID` возвращается. + +**Следствие:** ответ POST нельзя считать подтверждением, что данные +сохранены. Успешный HTTP 200 + валидный JSON с `UID` означают только +что запись появилась, но часть полей может быть потеряна. + +**Правило:** после КАЖДОГО POST на `/issue/items` (и любой другой +сущности, где критично содержимое) делать контрольный GET и глазами +или ассертом проверять реально сохранённые значения. Минимум: + +```python +code, text = call("GET", f"issue/items/{new_id}") +g = json.loads(text) +assert g["UID"].startswith("U-"), "неверный префикс UID" +assert len(g.get("Description","")) > 100, "тело пожелания пустое" +# опционально: проверить Caption, Priority.Id, Function.Id, Company.Id +``` + +Известные «тихие ловушки»: +- `Content` вместо `Description` в теле POST на `/issue/items` → + поле игнорируется, запись создаётся с пустым телом. +- `Type: {"Id":""}` при POST на `/request/items` → игнорируется, + сервер ставит `Type=397` (Доработка). +- `Requirement` при POST на `/issue/items` → игнорируется + (привязку делать через PUT или в UI). + ## 1. Пожелания vs Заявки — КРИТИЧНО В официальной схеме Devprom это **две разные сущности** с разными @@ -74,14 +104,20 @@ _Проверено эмпирически:_ `/request/items` при POST **вс ```python post_body = { - "Caption": "<заголовок>", - "Content": "", # по документации; Description тоже принимается - "Priority": {"Id": "2"}, # 1=Критично, 2=Высокий, 3=Обычный - "Author": {"Id": ""}, - "Function": {"Id": ""}, # подсистема (группировка) - "Company": {"Id": ""}, # опционально: клиент-источник + "Caption": "<заголовок>", + "Description": "", # ← именно Description, НЕ Content + "Priority": {"Id": "2"}, # 1=Критично, 2=Высокий, 3=Обычный + "Author": {"Id": ""}, + "Function": {"Id": ""}, # подсистема (группировка) + "Company": {"Id": ""}, # опционально: клиент-источник } # POST {BASE}/issue/items → {UID: "U-xxxx", Id: "xxxx", ...} + +# ⚠ ОБЯЗАТЕЛЬНЫЙ контрольный GET — сервер может молча отбросить поля +code, text = call("GET", f"issue/items/{new_id}") +g = json.loads(text) +assert g["UID"].startswith("U-"), f"префикс не U-: {g['UID']}" +assert len(g.get("Description","")) > 100, "тело пожелания пустое" ``` Поля `Requirement` и `RequirementDocument` в теле **не передаются**: @@ -106,7 +142,7 @@ Egress-прокси периодически роняет запросы с HTTP | Поле | Тип / формат | Обязательность | Комментарий | |-----------------------|------------------------------|----------------|-------------| | `Caption` | string | обязательно | Заголовок пожелания | -| `Content` | HTML-string | обязательно | Описание. Разрешены: `