На пути /request/items/{id} DELETE действительно заблокирован
(возвращает Unable access entity), но тот же Id можно убрать
через DELETE /issue/items/{id} — он универсален и работает как
для U-записей (созданных через /issue/items), так и для I-записей
(созданных через /request/items). Эмпирически подтверждено чисткой
33 зомби-записей I-6122..I-6176 в test-api-claude за один проход.
Поправлены разделы:
- devprom-alm-api.md §4 «Удаление» — таблица расширена комментарием
про универсальность /issue/items DELETE
- devprom-alm-api.md §6 «Что НЕ работает» — DELETE request/items
отмечен как «не препятствие»
- SKILL.md §«Критически важно» — корректное правило про DELETE
- meeting-wishes-extraction.md антипаттерн №7 — UI больше не нужен
20 KiB
Devprom ALM REST API — рабочая шпаргалка
Справочник для загрузки Пожеланий, Заявок, Требований и вложений в Devprom ALM
через REST API. Имена сущностей сверены с официальной таблицей справочника
разработчика: /pm/all/apidocs/list (например,
artsaterra.myalm.ru/pm/all/apidocs/list),
где каждая строка — одна сущность с её ReferenceName (используется в REST API)
и русским именем. Ключевые строки, участвующие в режиме Пожеланий из совещания:
| № | ReferenceName | Сущность |
|---|---|---|
| 45 | issue |
Пожелание |
| 18 | request |
Доработка (заявка с типом) |
| 81 | requesttype |
Тип пожелания |
| 92 | requirement |
Требование |
| 57 | attachment |
Приложение (файл) |
| 33 | company |
Компания |
| 46 | user |
Пользователь |
Дополнительные эмпирические детали (поведение, которое в публичной
документации не раскрыто явно) проверены на инстансе artsaterra.myalm.ru
и отмечаются в тексте курсивом (проверено эмпирически).
Связанные ресурсы:
- Публичная документация Devprom: docs.myalm.ru
- Раздел про управление пожеланиями: artsaterra.myalm.ru/docs/8835.html
0. Базовое
- Хост:
https://<host>/pm/<project-slug>/api/latest - Аутентификация: заголовок
Devprom-Auth-Key: <hex>(личный API-ключ пользователя) - Content-Type:
application/json - Ответ: HTTP 200 всегда, ошибки валидации приходят в теле как
{"error":"…"} - PATCH не поддерживается — HTTP 405. Обновление только через PUT.
- Успешный ответ на создание: иногда возвращается как объект, иногда — как массив с одним элементом. Учитывать оба случая.
1. Пожелания vs Заявки — КРИТИЧНО
В официальной схеме Devprom это две разные сущности с разными
ReferenceName (см. таблицу выше):
issue(Пожелание) — сущность из строки 45. Создаётся без типа, UID с префиксомU-. В UI живёт в разделе «Пожелания» (/module/requirements/issues).request(Доработка) — сущность из строки 18. Создаётся с обязательным типом (Доработка / Ошибка), UID с префиксомI-. В UI живёт на доске заявок (/issues/board).
| Логический класс | Эндпоинт | Префикс UID | Поле Type | UI-раздел |
|---|---|---|---|---|
Пожелание (issue) |
/issue/items |
U- |
пусто | /module/requirements/issues |
Доработка (request) |
/request/items |
I- |
397 (Доработка) / 398 (Ошибка) | /issues/board |
Проверено эмпирически: GET на /issue/items/{id} и /request/items/{id}
возвращает одну и ту же запись (разные виды на один ресурс — внутренне
это один класс pm_ChangeRequest). Разница проявляется при POST — сервер
применяет разную логику автозаполнения в зависимости от эндпоинта.
Почему попасть в «Доску пожеланий» можно только через /issue/items
Проверено эмпирически: /request/items при POST всегда принудительно
проставляет Type=397 (Доработка), даже если передать Type: null,
Type: {} или Type: {"Id":""}. Все варианты PUT тоже бессильны — сервер
восстанавливает 397. Подтверждено на 8 вариантах тела.
Поэтому для создания «чистого» Пожелания (с пустым Type и префиксом U-)
используется эндпоинт именно сущности issue — POST на /issue/items.
2. Алгоритм создания Пожелания (рабочий рецепт)
Один POST на одно Пожелание. Без PUT, без привязки к требованиям.
post_body = {
"Caption": "<заголовок>",
"Content": "<html-описание>", # по документации; Description тоже принимается
"Priority": {"Id": "2"}, # 1=Критично, 2=Высокий, 3=Обычный
"Author": {"Id": "<issueauthor.id>"},
"Function": {"Id": "<feature.id>"}, # подсистема (группировка)
"Company": {"Id": "<company.id>"}, # опционально: клиент-источник
}
# POST {BASE}/issue/items → {UID: "U-xxxx", Id: "xxxx", ...}
Поля Requirement и RequirementDocument в теле не передаются:
привязка к документу требований — задача пользователя в UI, не API.
На этапе создания Пожелания она и не нужна — заказчик подтверждает
пожелания, формализует требования и уже потом вручную связывает одно
с другим.
Примечание для других сценариев. Если всё-таки нужно привязать Пожелание к существующему требованию из API (например, массовая миграция из внешней системы), это делается вторым шагом через
PUT /issue/items/{id}с тем же телом +Requirement.Id— в одном POST эти поля молча игнорируются. Для режима «Пожелания из совещания» этот путь не нужен.
Retry-политика
Egress-прокси периодически роняет запросы с HTTP 502/503/504 («DNS cache overflow»). Всегда оборачивать вызов в цикл retries=3 с sleep(2..3). Это не связано с Devprom — лечится только ретраями.
3. Поля Пожелания — полный справочник
| Поле | Тип / формат | Обязательность | Комментарий |
|---|---|---|---|
Caption |
string | обязательно | Заголовок пожелания |
Content |
HTML-string | обязательно | Описание. Разрешены: <p> <b> <ul> <ol> <li> <a> <blockquote> <code>. Поле Description на входе тоже принимается как алиас. |
Priority.Id |
"1" / "2" / "3" | по смыслу | 1=Критично, 2=Высокий, 3=Обычный |
Author.Id |
issueauthor.id | обязательно | Автор пожелания. Справочник инстанс-уровня. |
Function.Id |
feature.id | рекомендовано | Группировка по подсистемам (создаются через /feature/items) |
Company.Id |
company.id | опционально | Клиент-источник пожелания. Принимается в POST напрямую. |
Requirement.Id |
requirement.id | не передавать в режиме Пожелания из совещания | Привязка к документу требований — задача пользователя в UI. Для других сценариев (миграция) — только через отдельный PUT после POST. |
RequirementDocument |
— | — | Не передавать, заполняется сервером автоматически по родителю Requirement |
Type.Id |
requesttype.id / пусто | НЕ передавать для пожелания | Любая попытка обнулить через API бесполезна; если передать — получится «Заявка» с префиксом I- |
4. Удаление
| Эндпоинт | DELETE работает? | Поведение |
|---|---|---|
DELETE /issue/items/{id} |
ДА — универсальный | HTTP 200, запись пропадает. Работает для ЛЮБОЙ записи — и для U- (созданных через /issue/items), и для I- (созданных через /request/items). Сущности issue и request указывают на один класс pm_ChangeRequest в БД, но DELETE разрешён только на пути issue/items. |
DELETE /request/items/{id} |
НЕТ | HTTP 200 с {"error":"Unable access entity"}, запись не удаляется. Сервер возвращает эту ошибку даже для записей, созданных через /request/items. |
DELETE /requirement/items/{id} |
Не гарантировано | Возвращает HTTP 200 с {"error":"Unable access entity"}, но GET после этого иногда показывает запись пустой (UID='', Caption=''). Эффект — неявное удаление / повреждение записи. Использовать с осторожностью. |
Практический вывод: для удаления любой записи Request/Issue —
всегда DELETE /issue/items/{id}, независимо от того, как она была создана.
5. Справочные эндпоинты (read-only для нашего ключа)
| Эндпоинт | Назначение |
|---|---|
/requesttype/items |
Типы заявок: Доработка, Ошибка |
/priority/items |
Приоритеты |
/feature/items |
Подсистемы/функции (имя "feature", не "function"!) |
/issueauthor/items |
Авторы пожеланий (инстанс-справочник) |
/user/items |
Пользователи проекта |
/company/items |
Компании-клиенты |
/requirement/items |
Требования и документы требований |
/state/items |
Состояния |
6. Что НЕ работает через API (заблокировано политикой прав)
| Операция | Ответ API | Обход |
|---|---|---|
POST /issueauthor/items |
HTTP 200 + {"error":"Lack of permissions to create object of IssueAuthor"} |
Только UI: /pm/<project>/issueauthor или inline-форма в карточке пожелания |
POST /user/items |
То же | Только UI |
DELETE /request/items/{id} |
{"error":"Unable access entity"} |
Не препятствие: удалять через DELETE /issue/items/{id} — он работает для любой записи Request (см. раздел 4). |
Пытаться обойти через write-only ключ проекта, api/v1, api/v2, инстанс-путь без /pm/<project>/ — бесполезно, все варианты дают тот же отказ.
7. Создание документа требований
⚠️ В режиме «Пожелания из совещания» этот путь НЕ используется. Структуру документов требований (
requirement, строка 92 таблицы сущностей) выстраивает владелец проекта/аналитик вручную через UI Devprom — постепенно, по мере формализации требований, согласованных с заказчиком. Привязку Пожеланий (issue) к требованиям пользователь тоже делает вручную в UI. Режим извлечения пожеланий в эту структуру не вмешивается. Раздел оставлен для справки — на случай других задач (миграция требований, импорт из внешней системы и т.п.).
POST /requirement/items
body = {
"Caption": "Корневой документ",
"Content": "<p>описание</p>",
# "ParentPage": {"Id": "..."} # если создаём подстраницу
}
Корневой документ — без ParentPage. Подстраница — с ParentPage.Id = <id_корня>. UID корневых документов присваивается по правилам шаблона проекта (например, О-1, R-35).
8. Attachment (приложить файл)
POST /attachment/items
body = {
"FileExt": "transcript.txt",
"ObjectId": "<request.id>",
"ObjectClass": "Request", # именно Request — общий класс для issue и request
"File": "<base64 содержимого>",
}
9. Альтернативные и несуществующие эндпоинты
Тестировались, но возвращают {"error":"Unknown entity: ..."}:
/userwish/items,/wish/items,/userrequest/items,/suggestion/items/admin/request/items,/api/latest/admin/request/items/pmcustomclass/items,/customclass/items,/class/items
Существующие служебные варианты:
/api/v1/request/items,/api/v2/request/items— принимают POST, но принудительная логикаType=397та же, что на/api/latest/request/items; использовать не нужно.
Примечание: эндпоинт
/issue/items— не алиас/request/items, а отдельная сущностьissue(Пожелание) из таблицы сущностей Devprom, строка 45. Под капотом они указывают на один и тот же классpm_ChangeRequest, но серверная логика автозаполнения при POST у них разная (см. раздел 1).
10. Порядок подготовки проекта для загрузки пожеланий
Граница ответственности: структуру проекта готовит человек через UI, пожелания загружает скрипт через API. Скрипт не создаёт Company, Feature, документы требований, IssueAuthor — только читает их.
Делается вручную через UI (один раз на проект, силами аналитика)
- Company для каждого клиента, который генерирует пожелания.
- Пример: «АРД» с доменом
alreadycom.ru.
- Пример: «АРД» с доменом
- Feature (подсистемы) — 3–5 на проект по подсистемам целевой
конфигурации. Можно создать и скриптом (
POST /feature/items) — наfeatureограничений API нет, но обычно удобнее через UI.- Пример для КА 2.5: «НСИ и администрирование», «Продажи», «Склад», «Казначейство», «Производство».
- IssueAuthor для представителей заказчика — если нужно, чтобы автором пожелания был сам клиент, а не аналитик. Только через UI.
- Документы требований — структуру требований клиент/аналитик выстраивает постепенно, по мере работы над проектом. Режим извлечения Пожеланий в неё не вмешивается.
Делается скриптом через API (каждое новое совещание)
- Цикл по Пожеланиям — для каждого: один POST
/issue/itemsс полями Caption, Content, Priority, Author, Function и опционально Company.Requirementне передаётся. - GET
/issue/items/{id}— верификация, что UID начинается наU-. - Привязка Пожеланий к требованиям — вне скрипта, это ручная работа пользователя в UI, когда требования появятся и согласованы с заказчиком.
Appendix — примеры curl
Создание пожелания (как в документации, с Type=Доработка)
curl -X POST \
-H "Devprom-Auth-Key: <KEY>" -H "Content-Type: application/json" \
https://<host>/pm/<proj>/api/latest/request/items \
-d '{"Caption":"Новая доработка","Content":"<p>Описание</p>","Type":{"Id":"397"}}'
# → UID=I-xxxx, Type=Доработка
Создание пожелания без типа (рекомендуемый путь)
curl -X POST \
-H "Devprom-Auth-Key: <KEY>" -H "Content-Type: application/json" \
https://<host>/pm/<proj>/api/latest/issue/items \
-d '{"Caption":"Пожелание","Content":"<p>Описание</p>","Priority":{"Id":"2"},"Author":{"Id":"1"},"Function":{"Id":"190"},"Company":{"Id":"146"}}'
# → UID=U-xxxx, Type=пусто
Привязка к документу требований (не нужна в режиме «Пожелания из совещания»)
Используется только для миграционных сценариев:
curl -X PUT \
-H "Devprom-Auth-Key: <KEY>" -H "Content-Type: application/json" \
https://<host>/pm/<proj>/api/latest/issue/items/6179 \
-d '{"Caption":"Пожелание","Content":"<p>Описание</p>","Priority":{"Id":"2"},"Author":{"Id":"1"},"Function":{"Id":"190"},"Requirement":{"Id":"4378"}}'
Удаление
curl -X DELETE \
-H "Devprom-Auth-Key: <KEY>" \
https://<host>/pm/<proj>/api/latest/issue/items/6179
# → HTTP 200, []