Adwos CMS

Сценарии продуктов

Объявления, услуги, недвижимость, фриланс и товарные заказы

Маршруты ниже сверены с регистрациями и обработчиками CMS. Доступность зависит от версии установки, active preset, модулей и роли. Общий справочник пока содержит неполные вертикальные схемы; не подставляйте неизвестные поля по аналогии с другим продуктом. Перед записью проверьте контракт именно своей установки. Настройка продуктов описана также в базе знаний.

Доска объявлений и авто

Порядок: категория → схема полей → создание своего объявления → чтение собственного состояния → модерация → проверка публичной видимости. В этих вертикалях kind — ad. Для обеих используется общий /api/v1/listings; авто-поля выбираются по категории и схеме установки.

CreateListingInput требует category_id UUID и title длиной 5–200. Дополнительно есть description, price, currency, price_type, price_period, field_values, image_ids, images, kind, attrs и местоположение. attrs — JSON со схемой выбранного вида; обязательность вертикальных полей проверяется дополнительно. Не переносите эту схему в товарный checkout.

{"category_id":"<category UUID>","title":"Тестовое объявление","kind":"ad","price":100,"currency":"RUB"}

Пример показывает общий контейнер, а не полный payload конкретной категории. Операции и состояния собственных объявлений — в гайде каталога. Доступ к чужой записи, публикация сверх лимита и возобновление при неподходящем тарифе должны проверяться отдельно.

Услуги, задания и специалисты

Preset services поддерживает task, service, specialist_profile. Это виды сущностей общего listing API, а не три независимых CRUD-каталога. task описывает потребность заказчика, service — предложение исполнителя, specialist_profile — карточку специалиста.

  1. Выберите разрешённый kind, категорию и её поля.
  2. Создайте запись через POST /api/v1/listings от владельца профиля.
  3. Прочитайте её через собственный каталог и проверьте статус; затем публичную видимость.
  4. Для задания используйте /api/v1/listings/{id}/responses: создание отклика — POST, чтение — GET, решения — POST /{responseID}/accept, /reject, /withdraw.
  5. После принятия отклика отдельно проверьте договорённость, заказ или safe deal, если эти механизмы включены. Принятый отклик не подтверждает оплату и завершение работы.

Операции откликов требуют владельца профиля; доступ к конкретному заданию и отклику дополнительно проверяется сервисом. Создание safe deal из отклика зависит от платёжного механизма. Карточка специалиста и пользовательский аккаунт имеют разные идентификаторы: не заменяйте один другим.

Не используйте /admin/services для создания предложения специалиста: этот административный раздел относится к услугам продвижения. Для services обязательны поля выбранной категории и вида; одна только общая схема CreateListingInput их не перечисляет.

Недвижимость: профиль → организация → объект

ОперацияКто и что получает
GET /api/v1/users/me/realty-profileАвторизованный профиль: собственные настройки
PUT /api/v1/users/me/realty-profileВладелец профиля: изменить настройки риелтора
GET /api/v1/users/me/realty-agencyВладелец: контекст своей организации
PUT /api/v1/users/me/realty-agencyВладелец: сохранить агентство или застройщика
GET /api/v1/realty/realtorsКаталог доступных риелторов
GET /api/v1/realty/organizationsКаталог организаций
GET /api/v1/realty/agencies/{id}Публичная карточка организации

RealtyProfileInput содержит обязательный seller_type: owner, agent, agency, developer; cities, specializations, public_phone, whatsapp, directory_visible, description, languages, areas. Допустимые специализации: sale, rent, daily, commercial, new_build.

RealtyAgencyInput содержит обязательный name (2–100), kind (agency или developer), description, logo_url, public_phone, public_email, website. Ответ контекста содержит enabled и agency; сохранение не означает прохождение модерации. Публичный ответ исключает moderation_note. При выключенных агентствах — 403, неверных данных — 400, конфликте изменения при модерации — 409, отсутствующей публичной карточке — 404.

Членство управляется отдельно через /api/v1/users/me/realty-memberships; приглашение и его принятие не заменяются произвольным указанием agency ID в объекте. Представитель может состоять только в одной организации.

Объекты создаются общим listing API с видами listing, new_building, lease и схемой категории. Проверяйте права представителя, модерацию организации и объекта, поля сделки и публичную видимость. Сохранение профиля не публикует все принадлежащие ему объекты.

Фриланс: предложение → оплата → работа

Preset freelance поддерживает gig и project. Готовая услуга и проект с откликами начинают разные сценарии.

Для gig покупатель вызывает POST /api/v1/freelance/gigs/{id}/orders. CreateFreelanceGigOrderInput: package_key или совместимое package, extras (до 10 ключей), requirements (до 5000). Продавец, стоимость и условия выбираются сервером из услуги; нельзя передавать произвольные seller_id и цену покупателем. Успех — HTTP 201 и FreelanceOrder.

Проект создаётся через listing API с kind=project; отклики проходят через /listings/{id}/responses. Согласованное предложение с задачами может создавать заказ через контракт установленного chat-offer модуля. Этот модульный hook не является отдельным публичным CMS REST-методом: не вызывайте внутренний hook из клиентского приложения. Сверяйте endpoint и payload предложения с версией модуля.

Свой список: GET /api/v1/freelance/orders с role=buyer или freelancer, status, page, per_page. Чтение заказа — GET /{id}. Доступ имеют его стороны; административные операции требуют отдельных freelance-разрешений.

Все следующие пути начинаются с /api/v1/freelance/orders/{id}:

POST-путьКто действуетУсловие и результат
/payПокупательЗапуск оплаты; ответ {order, task?, deal?}, не подтверждение списания
/requirementsПокупательНепустой message, оплаченная сделка, awaiting_requirements
/startИсполнительawaiting_start, оплаченная сделка, не истёк срок начала → in_work
/submitИсполнительНепустой message, оплаченная сделка, in_work или revision → submitted
/revisionПокупательНепустой reason, submitted → revision; проверяются ограничения правок
/acceptПокупательПодтверждение результата с проверками safe deal; результат перечитать
/dispute, /cancelДопустимая сторонаПрава, состояние и платёжные условия проверяются отдельно

FreelanceOrderActionInput содержит message, reason, revision_kind (objective или subjective), attachment_ids (до 10 UUID). Для оплаты PayFreelanceOrderInput содержит необязательные return_url, fail_url; сервер проверяет разрешённость адресов. JSON строго проверяется, предел 64 KiB: повреждённое тело — 400 invalid_request_body, превышение — 413 request_body_too_large.

Для многоэтапного заказа оплачивается POST /tasks/{taskId}/pay, действие выполняется POST /tasks/{taskId}/{action}. Допустимые действия: requirements, start, submit, revision, accept, dispute, cancel. Состояние каждой задачи и сделки проверяется отдельно; готовность одной задачи не завершает остальные.

Отказ при неподходящем статусе — 409; недоступный safe deal — 503. provider_result_unknown означает 409 с необходимостью сверить сделку перед повтором. Вложения имеют отдельные проверки владельца, типа, размера и приватного хранилища. Не пересылайте их URL как общедоступные файлы.

Товары: предложение продавца → заказ → возврат

Маршруты /catalog, /seller/catalog, /me/catalog доступны при marketplace-capability preset; в другой вертикали они могут вернуть 404. Публичное чтение каталога допускает optional auth; покупатель и продавец используют авторизованные области. Административные финансовые операции дополнительно проверяют billing-разрешения.

  1. Читайте GET /api/v1/catalog/products и GET /api/v1/catalog/products/{slug}. Карточка ProductCard содержит product, variants, buy_box, offers, is_favorited.
  2. Выберите offer ID, вариант и количество. Product ID, variant ID и offer ID не взаимозаменяемы.
  3. Передайте POST /api/v1/me/catalog/checkout: items с offer_id UUID и quantity >= 1, необязательные promo_code, payment_method (card, sbp, cod), объект delivery.
  4. Сохраните заказ из HTTP 201. Прочитайте GET /api/v1/me/catalog/orders и состояние его отправлений.
  5. Для онлайн-оплаты POST /api/v1/me/catalog/orders/{id}/pay принимает return_url, fail_url и возвращает payments: массив {shipment_id, deal_id, payment_url?}. Заказ с несколькими отправлениями может иметь несколько сделок.
{
  "items":[{"offer_id":"<offer UUID>","quantity":1}],
  "payment_method":"card",
  "delivery":{"method":"<enabled delivery method>"}
}

Цена, доступный остаток, способ доставки и возможность платежа проверяются сервером. Неверные данные/невозможный checkout — 400; ненастроенная оплата — 503; запрещённый redirect — 400. Успешный checkout не означает, что заказ оплачен или отправлен. status, payment_status, состояние shipment и deal — отдельные поля.

Возврат создаёт покупатель: POST /api/v1/me/catalog/returns с обязательными shipment_id, reason (до 120) и необязательным comment (до 2000). Успех — 201 и MpReturn. Список — GET по тому же пути. Продавец принимает решение POST /api/v1/seller/catalog/returns/{id}/decision: decision=approve или reject, необязательный resolution. Хотя общая модель содержит также refund, обработчик решения продавца его не принимает. Фактический денежный возврат подтверждается отдельной операцией и состоянием сделки, а не решением approve.

Проверка каждого сценария

На тестовой установке каждого продукта проверьте создание → повторное чтение → доступ другого профиля → недопустимый переход → итог в UI. Для действий с неопределённым сетевым результатом сначала читайте состояние; общий Idempotency-Key не обещается всеми перечисленными операциями. Модуль, который включён в одной вертикали, может отсутствовать или быть несовместимым в другой.

Чат и сообщения описаны отдельно, пополнение и сверка оплаты — в денежных операциях. Это описания исходного контракта; успешный сценарий на одной демоустановке не подтверждает его работу на всех клиентских версиях.

On this page