AACsearch
Коннекторы и виджет

Жизненный цикл API коннектора

Все 7 эндпоинтов Connector API, аутентификация, формы запросов/ответов, поток жизненного цикла и коды ошибок.

Connector API — это набор маршрутов Hono, смонтированных под /api, которые модули CMS вызывают для отправки данных о товарах и сообщения диагностической информации. Все эндпоинты требуют Bearer-токена ss_connector_*. Все данные валидируются с помощью Zod.

CMS-модули обязаны использовать этот API как единственный путь записи. Никогда не обращайтесь к Typesense, таблице SearchIngestBuffer или другим внутренним хранилищам напрямую. Connector API обеспечивает изоляцию арендатора, учёт квот и буферизацию ингеста — прямые записи обходят все три.

Аутентификация

Каждый запрос должен включать заголовок Authorization:

Authorization: Bearer ss_connector_<token>

Токен сопоставляется с хэшированными записями в SearchApiKey, где scopes включает connector_write, а revokedAt равен null. При успешном совпадении lastUsedAt токена обновляется (неблокирующим образом).

Ответы при ошибке аутентификации:

УсловиеСтатусТело
Нет заголовка Authorization401{ "error": "missing_bearer_token" }
Токен не найден или отозван403{ "error": "invalid_or_revoked_key" }

Эндпоинты

POST /api/connectors/handshake

Вызывайте однократно при запуске модуля CMS или когда продавец сохраняет конфигурацию. Валидирует токен и возвращает метаданные индекса.

Тело запроса:

{
	"moduleVersion": "1.0.0",
	"platform": "prestashop"
}

platform должен быть "prestashop" или "bitrix".

Ответ (200):

{
	"projectId": "org_abc123",
	"indexSlug": "products",
	"status": "active",
	"connector": {
		"id": "prestashop",
		"displayName": "PrestaShop",
		"syncModes": ["full", "delta"],
		"capabilities": ["upsert", "delete"],
		"minModuleVersion": "1.0.0"
	}
}

Используйте projectId как сегмент пути :projectId для всех последующих вызовов синхронизации и диагностики.


POST /api/connectors/:connectorId/heartbeat

Сигнал keepalive. Вызывайте периодически (рекомендуется: каждые 5 минут), чтобы панель управления могла показывать статус коннектора онлайн/оффлайн.

Тело запроса: не требуется

Ответ (200):

{
	"status": "ok",
	"timestamp": "2025-01-15T10:00:00.000Z"
}

Панель управления определяет работоспособность коннектора по lastUsedAt токена: онлайн — если использован в течение 5 минут, неизвестно — в течение 30 минут, оффлайн — в противном случае.


POST /api/projects/:projectId/sync/full

Отправьте все товары для полной синхронизации каталога. Товары помещаются в очередь SearchIngestBuffer и индексируются асинхронно.

Лимит пакета: 1–1000 товаров на запрос. Для больших каталогов отправляйте несколько запросов.

Тело запроса:

{
	"products": [
		{
			"external_id": "product-123",
			"title": "Blue Running Shoes",
			"description": "Lightweight running shoes",
			"sku": "BRS-42",
			"brand": "Acme Sport",
			"categories": ["Shoes", "Running"],
			"category_ids": ["cat-10", "cat-22"],
			"tags": ["sale", "new-arrival"],
			"price": 99.99,
			"sale_price": 79.99,
			"currency": "USD",
			"image_url": "https://example.com/img/brs-42.jpg",
			"product_url": "https://example.com/products/brs-42",
			"availability": "in_stock",
			"stock_quantity": 42,
			"attributes": { "color": "blue", "size": "42" },
			"locale": "en"
		}
	]
}

Все поля, кроме external_id и title, опциональны. availability принимает "in_stock", "out_of_stock" или "preorder".

Ответ (200):

{
	"status": "accepted",
	"itemsCount": 1,
	"jobId": "sync_42_1737000000000"
}

Используйте jobId для опроса статуса через GET /api/projects/:projectId/sync/jobs/:jobId.

Ошибка (502): { "error": "sync_failed" } — постановка в очередь SearchIngestBuffer не удалась. Повторите с экспоненциальной задержкой.


POST /api/projects/:projectId/sync/delta

Отправьте только изменённые товары. Используйте для обновлений в реальном времени, вызываемых событиями сохранения/удаления/изменения остатков товаров.

Лимит пакета: 1–100 товаров на запрос.

Формы запроса и ответа идентичны эндпоинту полной синхронизации. jobId в ответе имеет тип "delta".

Ответ (200):

{
	"status": "accepted",
	"itemsProcessed": 1,
	"jobId": "sync_43_1737000001000"
}

DELETE /api/projects/:projectId/products/:externalId

Удалить один документ из индекса по его внешнему ID.

Тело запроса не требуется.

Ответ (200):

{
	"status": "deleted",
	"externalId": "product-123"
}

Ошибка (502): { "error": "delete_failed" }


POST /api/projects/:projectId/diagnostics

Сообщить AACsearch информацию о работоспособности модуля. Панель управления использует эти данные для отображения последнего известного состояния синхронизации и любых ошибок со стороны CMS.

Предупреждение для ранних пользователей: Диагностические отчёты хранятся в памяти серверного процесса AACsearch. Они теряются при перезапуске сервера. Это приемлемо для MVP; для постоянного хранения потребуется изменение схемы БД.

Тело запроса:

{
	"moduleVersion": "1.0.0",
	"lastFullSync": "2025-01-15T09:00:00.000Z",
	"lastDeltaSync": "2025-01-15T09:55:00.000Z",
	"totalProducts": 4823,
	"phpVersion": "8.2.0",
	"shopUrl": "https://myshop.example.com",
	"errors": [
		{
			"code": "export_timeout",
			"message": "Product export timed out after 30s",
			"timestamp": "2025-01-15T09:54:30.000Z"
		}
	]
}

Ответ (200):

{
	"status": "ok",
	"receivedAt": "2025-01-15T09:55:01.000Z"
}

GET /api/projects/:projectId/sync/jobs/:jobId

Опросить статус задания синхронизации по его ID.

Предупреждение для ранних пользователей: История заданий синхронизации хранится в памяти серверного процесса AACsearch. In-memory хранилище держит последние 50 заданий на экземпляр сервера и теряется при перезапуске. Если сервер перезапустится между вызовом sync/full и опросом этого эндпоинта, вы получите 404. Модули CMS должны воспринимать 404 как приемлемый исход после перезапуска сервера и не повторять запросы бесконечно.

Ответ (200) — завершённое задание:

{
	"id": "sync_42_1737000000000",
	"type": "full",
	"status": "completed",
	"indexId": "idx_abc123",
	"organizationId": "org_abc123",
	"startedAt": "2025-01-15T09:00:00.000Z",
	"finishedAt": "2025-01-15T09:00:05.432Z",
	"duration": "5.4s",
	"itemsCount": 500,
	"failuresCount": 0,
	"events": [
		{ "timestamp": "...", "message": "Full sync started", "level": "info" },
		{ "timestamp": "...", "message": "Sync completed: 500 items processed", "level": "info" }
	]
}

status — одно из: "running", "completed", "failed".

Ошибка (404): { "error": "job_not_found" }

Поток жизненного цикла

Типичный модуль CMS следует такой последовательности:

1. Запуск / сохранение конфигурации
   └─ POST /api/connectors/handshake
      → сохранить projectId + indexSlug в конфигурацию модуля

2. Фоновый keepalive (каждые 5 мин)
   └─ POST /api/connectors/:connectorId/heartbeat

3. Начальная полная синхронизация (однократно или по расписанию)
   └─ POST /api/projects/:projectId/sync/full (пакетно)
      → опрос GET .../sync/jobs/:jobId до завершения/ошибки

4. Дельта в реальном времени (при событиях с товаром)
   └─ POST /api/projects/:projectId/sync/delta

5. Удаление товара
   └─ DELETE /api/projects/:projectId/products/:externalId

6. Периодический отчёт диагностики
   └─ POST /api/projects/:projectId/diagnostics

Справочник кодов ошибок

КодЗначение
missing_bearer_tokenНет заголовка Authorization: Bearer ...
invalid_or_revoked_keyТокен не найден, неверная область или отозван
invalid_jsonТело запроса не удалось разобрать
invalid_inputВалидация Zod не прошла; массив details содержит ошибки по полям
project_not_found:projectId не соответствует организации токена
unsupported_connectorПоле platform не является prestashop или bitrix
sync_failedПостановка в очередь SearchIngestBuffer не удалась — повторите
delete_failedПостановка удаления в очередь не удалась — повторите
job_not_foundID задания не найден (возможно, потерян при перезапуске)

Связанные страницы

On this page