# Hobbyka: создание и изменение товаров без установки
Официальная инструкция для запроса пользователя создать товар или изменить основную карточку товара на hobbyka.ru через Codex. Не устанавливай CLI, MCP, плагины или зависимости. Используй штатный HTTPS-клиент среды и Hobbyka Product Draft API. Код проекта, SSH и прямой доступ к Bitrix менеджеру не нужны.
Codex создаёт только отдельный черновик. Не вызывай Bitrix API, не создавай `CIBlockElement`, не меняй инфоблок №3 и не пытайся нажимать кнопки подтверждения. Товар создаёт или меняет уполномоченный редактор на защищённой странице предпросмотра.
## 1. Подключение
Используй тот же безопасный маршрут, что для статей. Если в текущем чате уже есть действующий Bearer-токен со scope `product.draft.create product.draft.read product.draft.update`, используй его. Старое подключение только со scope `content.*` для товаров не подходит — запроси новое.
1. POST `https://hobbyka.ru/ai/content-access/request/` с JSON `{"client_name":"Codex: товары Hobbyka"}` без Bearer-токена.
2. Не выводи `device_code`. Сохрани его только во временном защищённом состоянии текущего процесса. Покажи пользователю лишь `verification_uri` и `user_code`. Ссылку подтверждает администратор или участник группы «Контент-редакторы» (ID 7).
3. После подтверждения POST `https://hobbyka.ru/ai/content-access/token/` с сохранённым `device_code`. Не опрашивай чаще раза в 5 секунд и не создавай запросы в цикле.
4. Полученный `access_token` не показывай в чате и не передавай третьим лицам. Используй его только в `Authorization: Bearer …` к HTTPS-адресам hobbyka.ru. Доступ действует 7 дней.
## 2. Сначала определи действие
- Новый товар: `operation=create`. До сохранения проверь каталог поиском `GET /api/ai/v1/catalog/products?q=...`, чтобы не создать дубль.
- Правки существующего товара: сначала однозначно найди основной товар через каталог и используй `operation=update` с его числовым `product_id`. Не используй ID торгового предложения.
- Если поиск неоднозначен, попроси пользователя выбрать товар. Не угадывай ID, раздел, характеристики, цену или артикул.
- Правки уже полученного черновика: прочитай его GET и используй PATCH **того же ID**. Пока `status=draft`, отдельный новый черновик для каждой правки не нужен. После применения — новый `operation=update` для существующего `product_id`.
Получить разрешённые свойства, списки и безопасные значения по умолчанию: `GET https://hobbyka.ru/api/internal/v1/product-drafts/meta`. Разделы каталога: `GET https://hobbyka.ru/api/ai/v1/catalog/sections`. Для нового товара обязательно передай `name` и `primary_section_id` (или совместимый `section_id`).
Product Draft API управляет основной карточкой товара: названием, URL-кодом, разделом, анонсом, подробным описанием, артикулом, базовой ценой, разрешёнными характеристиками, изображениями и SEO. Существующие торговые предложения, их свойства и цены не меняются. Если пользователь просит изменить SKU, сообщи об этом ограничении и не подменяй правку SKU изменением основной карточки.
При одобрении нового товара сервер регистрирует обычный товар без торговых предложений, с реальным остатком `0`, включённым количественным учётом и разрешением заказа при нулевом остатке (`CAN_BUY_ZERO=Y`). Фиктивный складской остаток не создаётся. Для покупки также нужны активность и корректная доступная цена; сохранение без активации само по себе не публикует товар. У существующих товаров правка черновика не меняет складские настройки, остатки или торговые предложения.
## 3. Поля черновика
POST `https://hobbyka.ru/api/internal/v1/product-drafts` с уникальным `Idempotency-Key` и JSON.
Для нового товара:
```json
{
"operation": "create",
"name": "Название товара",
"primary_section_id": 408,
"section_ids": [408],
"code": "url-kod",
"preview_text": "Краткое описание",
"new_description_html": "Материалы:
Описание материалов изделия.",
"expanded_html": "Авторский расширенный текст.
Подробности и особенности изделия.",
"article": "АРТИКУЛ",
"price": 0,
"currency": "RUB",
"properties": {
"ITEM_MATERIAL": "сталь, дерево",
"DELIVERY_STATUS": "Срок поставки — уточняйте у менеджера",
"DELIVERY": 7768
},
"seo": {
"title": "SEO Title",
"description": "Meta Description",
"page_title": "Заголовок страницы"
},
"agent": "codex-manager"
}
```
Для изменения:
```json
{
"operation": "update",
"product_id": 6791,
"price": 35700,
"properties": {"ITEM_MATERIAL": "сталь, дерево"},
"seo": {"description": "Новое описание"},
"agent": "codex-manager"
}
```
В `operation=update` передавай только действительно изменяемые поля. `null` очищает поддерживаемое поле. API фиксирует исходную версию товара и не применит устаревший черновик, если карточку успели изменить в Bitrix.
### Соответствие полям административной карточки
- `new_description_html` → «Новое описание», HTML-свойство `DESCRIPTION` (505).
- `expanded_html` → «Расширенный текст», HTML-свойство `MORE_TEXT` (50).
- `detail_html` → **старое** описание `DETAIL_TEXT`. Не подменяй им два поля выше. Не объединяй их в одно описание. Пустая строка очищает только соответствующий HTML-блок после одобрения.
- `primary_section_id` / `section_id` → основной раздел. `section_ids` → полный набор привязок, включая дополнительные. Сервер всегда включает основной; `[]` оставляет только основной. Если `section_ids` при правке не передан, дополнительные привязки сохраняются.
Дополнительные поля передаются внутри `properties`, строго по кодам из метаданных:
| Код | Поле | Значение |
| --- | --- | --- |
| `RB_TAGS` | Теги, вкладка «Теги» | Массив ID элементов инфоблока 22 |
| `COLORS` | Основные цвета | Массив ID элементов инфоблока 9 |
| `LENGTH` | Версия | Строка, например «Стандарт»; не торговое предложение |
| `ITEM_STATUS` | Статус товара | Значение списка из метаданных |
| `COMM_POINTER` | Коммерческий маркер | **Отдельное** значение списка из метаданных |
| `SERVICE_CHAIN` | Привязка услуги | Массив ID элементов инфоблока 33 |
| `MORE_INFO` | Справка | Массив ID элементов инфоблока 11 |
| `RELATED_ITEMS` | Сопутствующие товары | Массив ID существующих активных товаров инфоблока 3 |
Если пользователь просит маркер «Новинка», заполни `COMM_POINTER` значением «Новинка» из его справочника. Один `ITEM_STATUS` маркер не устанавливает. Если нужны оба признака — передай оба независимо. Дополнительный раздел «Новинки» добавляй в `section_ids`, сохраняя правильный основной раздел; это третья независимая настройка.
Поиск связанного значения: `GET /api/internal/v1/product-drafts/meta?property=RB_TAGS&q=скамейки&limit=50`. Для другого справочника замени `property`. `values` содержит ID и названия; у связей также есть `link_iblock_id`, `values_endpoint`, `has_more`, `next_cursor`. Если `has_more=true`, повтори запрос с теми же `property`, `q` и `cursor=next_cursor`. Не считай первую страницу полным справочником. Используй только проверенные ID; не создавай новые теги или фиктивные связанные товары. Порядок массива сохраняется, повторные ID удаляются. `[]` очищает множественную связь после одобрения. Одиночным полям нельзя передавать массив.
Для описаний используй `
`, ``, заголовки и неразрывные пробелы. Терминологические подсказки: `ангарская сосна`; ID должен соответствовать существующему термину сайта. Этот безопасный класс и ID сохраняются именно в HTML товара. Ссылки HTTP/HTTPS и ссылки на страницы сайта открываются в новой вкладке с `rel="noopener noreferrer"`; якоря, почта и телефон сохраняют обычное действие. Скрипты, формы, iframe, произвольные классы, стили и обработчики событий запрещены.
Подготовь естественный SEO Title, информативный Description примерно 120–160 символов и page title. Если пользователь передал SEO-шаблон Bitrix, сохрани его буквально, не выдавая `{=this.Name}` за уже подставленное значение. URL-код должен быть латиницей; если его не задать для нового товара, сайт сформирует уникальный адрес из названия.
Внешним HTTP/HTTPS-ссылкам, включая `//site.com/...`, API автоматически добавляет `rel="nofollow noopener noreferrer"` и `target="_blank"`. Относительные ссылки и точные домены `hobbyka.ru`, `www.hobbyka.ru`, `new.hobbyka.ru` не получают автоматический `nofollow`; явно заданный редактором сохраняется. Якоря, `mailto:` и `tel:` сохраняют обычное действие. Упоминания без ссылок оставляй текстом; жирное выделение не требуется.
## 4. Изображения
Сначала создай черновик. Затем для каждого нового JPEG/PNG/WebP отправь POST `https://hobbyka.ru/ai/product-media/` с тем же Bearer-токеном и JSON `{draft_id, image_base64}`. Ограничение: 8 МБ, 12 мегапикселей. В ответе используй `data.image_url`.
PATCH того же черновика:
```json
{
"images": {
"preview_image_url": "https://hobbyka.ru/upload/ai-products/.../image.jpg",
"detail_image_url": "https://hobbyka.ru/upload/ai-products/.../detail.jpg",
"gallery_image_urls": ["https://hobbyka.ru/upload/ai-products/.../gallery.jpg"]
}
}
```
Не передавай внешний URL, data URI или локальный путь. Не повторяй одну картинку в галерее и основных полях; API дополнительно удаляет дубли в галерее. Не выдавай ИИ-визуализацию за реальную фотографию.
Не добавляй чёрные поля и не вписывай фото в искусственный квадратный холст. Парные однотонные чёрные полосы автоматически убираются при загрузке и предпросмотре; неоднозначные тёмные края, белый товарный фон и прозрачность не обрезаются. Исправленная копия не перезаписывает оригинальное изображение в каталоге. Проверяй возвращённые размеры и порядок галереи, а не только исходный файл.
## 5. Проверка результата
Корректный новый черновик имеет:
- `status=draft`;
- строковый `id` из 40 шестнадцатеричных символов;
- `preview_url` с `/ai/product-preview/?draft=...`;
- для `operation=create` поле `product_id=null` — элемента инфоблока ещё нет;
- `applied_at=null`.
Для `operation=update` `product_id` указывает существующий товар, но сам товар ещё не изменён. Верни пользователю кликабельный `preview_url`, перечисли подготовленные изменения и явно скажи, что каталог пока не менялся. Администратор или участник группы 7 проверит карточку и нажмёт кнопку. Codex не применяет и не активирует товар самостоятельно.
После POST/PATCH и загрузки изображений обязательно выполни GET `/api/internal/v1/product-drafts/{id}`. Сверь фактически сохранённые `product.new_description_html`, `product.expanded_html`, `product.properties`, основной и дополнительные разделы, SEO и порядок изображений. Не заявляй о заполнении поля только по тексту запроса. Если справочник не нашёл значение или API отклонил поле — сообщи об этом, не подменяя связь строкой в описании.
Если требуется доработать неприменённый черновик, используй PATCH `/api/internal/v1/product-drafts/{id}`. После применения черновик заблокирован: для новых изменений создай отдельный `operation=update`.
## Кастомизация: 18 моделей первого запуска
Разрешены только `operation=update` для подтверждённых ID первого запуска: `14824, 66921, 14847, 19677, 14913, 17161, 23626, 66920, 14883, 15276, 14898, 14835, 62220, 14214, 14201, 12735, 13996, 18559`. Для новых товаров и остальных ID поля кастомизации не принимаются. Изменения применяются человеком на защищённой странице; сохранение черновика не меняет товар. Список ограничивает права записи API, а подборка строится только по реальному сохранённому чек-боксу, не по этому списку. Схема, stale guards и отдельное хранение примеров одинаковы для всех 18 моделей. Отправка работает только в закрытом предпросмотре; публичный вывод выключен.
```json
{
"operation": "update",
"product_id": 14824,
"properties": {"CUSTOMIZATION_AVAILABLE": "Y"}
}
```
`CUSTOMIZATION_AVAILABLE`: `Y`/`true` включает признак после ручного одобрения; `N`/`false`/`null` очищает. `CUSTOMIZATION_NOTES`: обычный текст до 5000 символов или `null`; не передавайте его, если пользователь не просил менять особенности.
Примеры передаются отдельным полем верхнего уровня `customization_examples`, не через обычную галерею и не через ID файлов:
```json
{
"customization_examples": [
{"image_url": "https://hobbyka.ru/upload/ai-products/ID/image.jpg", "caption": "Пример кастомизации: фирменный знак Хоббики"}
]
}
```
Сначала создайте черновик, загрузите изображение штатно через `/ai/product-media/` с его ID, затем PATCH тот же черновик URL из ответа. Доступны JPEG/PNG/WebP из `/upload` на hobbyka.ru, до 8 МБ и 12 мегапикселей. Проверяются реальный локальный файл, MIME, размеры и canonical path; внешние URL и выход через симлинк за медиатеку запрещены. До 20 примеров, подпись — обычный текст до 255 символов. Список полностью заменяется; `[]` очищает только примеры кастомизации. Отсутствующее поле ничего не меняет. `CUSTOMIZATION_PHOTOS`, произвольные file IDs и файловые свойства напрямую не принимаются.
Защищённый preview отдельно показывает признак и примеры с подписями. При одобрении меняются только соответствующие свойства; обычные `MORE_PHOTO`, основные фото, цена и SKU не затрагиваются, если они отсутствуют в запросе. Изменение товарных данных после создания/обновления базовой версии черновика вызывает конфликт. Старые черновики сохраняют прежние проверки, а при первом добавлении новых полей их базовая версия расширяется только после проверки ранее захваченных значений.
После ручного применения проверять результат в `/product/urna_filigran/?customization_preview=1` с правами редактора. Пока действует текущий режим проекта, обычная публичная карточка не включает эти блоки, а отправка остаётся отключённой.