Спецификация Gateway <-> gRPC сервисов¶
Внешний API:
gateway(REST/GraphQL).
Внутренний transport:gateway -> доменные сервисыпо gRPC.
1. Текущее состояние (as-is)¶
1.1 Gateway gRPC clients (реально подключены)¶
services/gateway/src/bff/grpc-bff.module.ts регистрирует клиентов:
AUTH_GRPC->fairflow.auth.v1(5001)CONTROL_GRPC->fairflow.control.v1(5002)CONTACT_GRPC->fairflow.contact.v1(5003)COMPANY_GRPC->fairflow.company.v1(5004)PIPE_GRPC->fairflow.pipe.v1(5005)ORDERS_GRPC->fairflow.orders.v1(5006)PRODUCT_GRPC->fairflow.product.v1(5007)ACTIVITY_GRPC->fairflow.activity.v1(5008)PLATFORM_GRPC->fairflow.platform.v1(5009)
1.2 Сервисы, подключённые в grpc-bff.module (новый пакет)¶
DOCUMENTS_GRPC->fairflow.documents.v1(5010)REPORTS_GRPC->fairflow.reports.v1(5011)AUTOMATION_GRPC->fairflow.automation.v1(5012)SEARCH_GRPC->fairflow.search.v1(5013)AUDIT_GRPC->fairflow.audit.v1(5014)NOTIFICATION_GRPC->fairflow.notification.v1(5015)BILLING_GRPC->fairflow.billing.v1(5016)
1.3 Политика ingress и trust¶
- Frontend проксирует только
/apiнаgateway. - JWT валидируется только в
gateway. - Доменные сервисы доверяют только metadata от
gateway+ валидный service API key. - Прямые frontend-вызовы в доменные сервисы запрещены.
2. Project context policy (D2)¶
2.1 Где хранится project context¶
- Канонический источник контекста проекта: store (host state), а не URL-prefix.
- Для CRM-портфеля используются пути без
/p/:pid(например/contacts,/deals,/orders). /p/:pid/*используется только для project-settings маршрутов.
2.2 Что обязан делать gateway¶
Для project-scoped RPC gateway обязан прокидывать:
x-project-idx-user-idx-request-idtraceparent/x-trace-idx-service-api-key+x-gateway-api-key-id
Если x-project-id отсутствует для project-scoped метода -> INVALID_ARGUMENT/PERMISSION_DENIED по контракту домена.
3. Внешние API-пути (as-is vs target)¶
3.1 As-is (фактическая совместимость с текущим frontend)¶
auth/control/CRM:/api/v1/*- GraphQL:
/api/graphql
3.2 Target¶
- Единый REST-префикс:
/api/v1/{entity} - Gateway-only граница
- gRPC как единственный внутренний синхронный transport
4. Матрица Gateway -> gRPC (канон)¶
| Gateway surface | gRPC сервис |
|---|---|
/api/v1/auth/* |
fairflow.auth.v1.AuthService |
/api/v1/workspaces, /api/v1/projects* |
fairflow.control.v1.* |
/api/v1/contacts* |
fairflow.contact.v1.ContactService |
/api/v1/companies* |
fairflow.company.v1.CompanyService |
/api/v1/deals*, /api/v1/pipelines* |
fairflow.pipe.v1.* |
/api/v1/orders*, /api/v1/order-types* |
fairflow.orders.v1.* |
/api/v1/products* |
fairflow.product.v1.ProductService |
/api/v1/activities* |
fairflow.activity.v1.ActivityService |
| platform endpoints | fairflow.platform.v1.PlatformService |
| documents endpoints | fairflow.documents.v1.DocumentsService |
| reports endpoints | fairflow.reports.v1.ReportsService |
| automation endpoints | fairflow.automation.v1.AutomationService |
| search endpoints | fairflow.search.v1.SearchService |
| audit endpoints | fairflow.audit.v1.AuditService |
| notification endpoints | fairflow.notification.v1.NotificationService |
| billing endpoints | fairflow.billing.v1.BillingService |
5. Error/timeout/idempotency conventions¶
- gRPC/HTTP mapping:
INVALID_ARGUMENT -> 400UNAUTHENTICATED -> 401PERMISSION_DENIED -> 403NOT_FOUND -> 404ALREADY_EXISTS -> 409RESOURCE_EXHAUSTED -> 429UNAVAILABLE -> 503- Каждый outbound RPC из gateway должен иметь deadline.
- Для create/update с риском дубликатов использовать
idempotency-key.
6. Связанные документы¶
7. Event contracts (RabbitMQ backbone)¶
Exchange: fairflow.events (topic)
- Producers:
automation.rule.created|updated|deleted|executedautomation.event.hooked- Consumers:
automation.triggers<-automation.trigger,automation.rule.triggersearch.indexer<-automation.rule.*,automation.event.*,audit.event.*,crm.*audit.events<-automation.rule.*,automation.event.*,crm.*,gateway.*
Recommended payload envelope:
{
"project_id": "string",
"event_name": "string",
"entity_type": "string",
"entity_id": "string",
"actor_id": "string",
"actor_type": "string",
"request_id": "string",
"trace_id": "string",
"payload": {}
}