Жизненный цикл коннектора
Шесть операций коннектора — handshake, heartbeat, full-sync, delta-sync, delete, диагностика — и их соответствие поверхности Connector API.
CMS-коннектор (PrestaShop, Bitrix, WordPress, Shopify) общается с AACsearch только
через Connector API, смонтированный по /api/connectors/** и
/api/projects/:projectId/**. Он никогда не обращается к Typesense напрямую.
Каждый вызов гейтится токеном ss_connector_* со scope connector_write.
Жизненный цикл
Описание
Диаграмма проходит шесть фаз CMS-коннектора — handshake, heartbeat, full-sync, delta-sync, delete, диагностика — каждая гейтится токеном ss_connector_*. Sync-вызовы создают строку SearchConnectorSyncJob плюс N строк SearchSyncOutbox; воркер сливает outbox в alias Typesense, а CMS-модуль поллит jobId до завершения.
sequenceDiagram
autonumber
participant Mod as CMS module (PrestaShop / Bitrix / WP / Shopify)
participant API as packages/api/modules/search/connector-public.ts
participant Auth as gateConnectorRequest (scope=connector_write)
participant DB as PostgreSQL (SearchConnectorSyncJob + SearchSyncOutbox)
participant W as Sync worker
participant TS as Typesense alias
rect rgb(220, 252, 231)
note over Mod,API: Phase 1 — handshake (once per install)
Mod->>API: POST /api/connectors/handshake { moduleVersion, platform }
API->>Auth: verify ss_connector_* + connector_write
API-->>Mod: { projectId, indexSlug, capabilities, syncModes }
end
rect rgb(219, 234, 254)
note over Mod,API: Phase 2 — heartbeat (periodic, every ~5 min)
Mod->>API: POST /api/connectors/:connectorId/heartbeat
API-->>Mod: { status: "ok", timestamp }
end
rect rgb(254, 243, 199)
note over Mod,DB: Phase 3 — full sync (initial / on-demand)
Mod->>API: POST /api/projects/:projectId/sync/full { products[1..1000] }
API->>DB: createSyncJob(type=full)
API->>DB: executeSyncJob -> enqueue doc_upsert per product (outbox)
API-->>Mod: { jobId, total, queued }
W->>DB: drain outbox doc_upsert rows
W->>TS: bulkUpsert(batch, action=upsert)
W->>DB: completeSyncJob(jobId)
end
rect rgb(245, 243, 255)
note over Mod,DB: Phase 4 — delta sync (per change webhook)
Mod->>API: POST /api/projects/:projectId/sync/delta { products[1..100] }
API->>DB: createSyncJob(type=delta)
API->>DB: executeSyncJob -> outbox rows
API-->>Mod: { jobId, total, queued }
W->>TS: bulkUpsert(batch)
end
rect rgb(254, 226, 226)
note over Mod,TS: Phase 5 — delete (single or batch)
Mod->>API: DELETE /api/projects/:projectId/products/:externalId
API->>DB: enqueue doc_delete
W->>TS: delete_by_query(externalId)
Mod->>API: DELETE /api/connector/documents { externalIds[1..500] }
API->>DB: enqueue doc_delete (batch)
W->>TS: batch delete
end
rect rgb(241, 245, 249)
note over Mod,DB: Phase 6 — diagnostics (on demand / on error)
Mod->>API: POST /api/projects/:projectId/diagnostics { moduleVersion, lastFullSync, errors[] }
API->>DB: recordDiagnostics() (in-memory store + log)
API-->>Mod: { received: true }
endШесть операций
| Фаза | HTTP | Лимит тела | Назначение | Сохраняет |
|---|---|---|---|---|
| handshake | POST /api/connectors/handshake | малый | Подтвердить токен, обменяться capabilities + modes | Обновляет lastUsedAt |
| heartbeat | POST /api/connectors/:connectorId/heartbeat | пусто | Пинг живости модуля, обмен серверным временем | Обновляет lastUsedAt |
| full-sync | POST /api/projects/:projectId/sync/full | 1000 | Первичная загрузка или сброс; bulk-upsert каталога | SearchConnectorSyncJob + строки outbox |
| delta-sync | POST /api/projects/:projectId/sync/delta | 100 | Webhook на изменение из CMS | SearchConnectorSyncJob + строки outbox |
| delete | DELETE /api/projects/:projectId/products/:externalIdDELETE /api/connector/documents | 1 / 500 | Удалить один продукт / партию | Строка(и) outbox doc_delete |
| диагностика | POST /api/projects/:projectId/diagnostics | 4 КБ | Самоотчёт о версии PHP, последнем sync, ошибках | In-memory хранилище диагностики + структурный лог |
Что гейтит каждый вызов
gateConnectorRequest выполняется до любой логики handler-а:
- Заголовок Authorization должен нести
Bearer ss_connector_*. verifySearchApiKey(rawKey, "connector_write")— admin-scope является надмножеством.- Возвращает
{ keyId, organizationId, indexId, indexSlug }для handler-а. - Sync-handler-ы дополнительно проверяют, что
:projectIdсовпадает сorganizationId— иначе возвращается 404, если токен используется против другого проекта.
Зачем job + outbox
Connector API никогда не блокируется на Typesense. executeSyncJob пишет строку
SearchConnectorSyncJob для сквозной видимости плюс N строк в SearchSyncOutbox,
которые сливает воркер. CMS-модуль получает jobId, который можно опрашивать; а
воркер согласует каждую строку независимо, поэтому одна плохая SKU не ломает
весь batch.
См. также
- Путь записи — сторона воркера для outbox.
- Типы ключей и модель безопасности
— форма и правила scope-ов токена
ss_connector_*.
Типы ключей и модель безопасности
Четыре категории ключей AACsearch — search, connector, scoped и admin — их префиксы ss_*, хранение только хешей, HMAC + TTL + фильтр scoped-токена и порядок проверки каждой категории во время запроса.
Аналитический контур обратной связи
Как поисковый запрос становится SearchUsageEvent, как фиксируются клики и конверсии и как агрегация питает дашборд для настройки релевантности.