# Эндпоинты, с которыми взаимодействует documentation-frontend Документ описывает все HTTP-эндпоинты внешних сервисов, к которым обращается модуль (микрофронтенд `documentation-frontend`, образ `documentation-frontend-app`, деплой `frontend`). Модуль публикуется как remote для Module Federation (`webpack.config.js`, имя `srx_documentations`). ## Как устроено взаимодействие Все запросы описаны декларативно в реестре `module/api/endpoints.ts` (объект `endpoints`). Каждый эндпоинт задаётся структурой `Endpoint`: - `service` — логическое имя сервиса (см. таблицу хостов ниже); - `method` — HTTP-метод (`GET`/`POST`/`PUT`/`PATCH`/`DELETE`); - `path(args)` — функция, возвращающая путь запроса (с подстановкой параметров/query); - `body(args)` — опционально, формирование тела запроса; - `responseType` — опционально, тип ответа (напр. `blob`); - `accessToken(args)` — опционально, явная передача access-токена в заголовки; - `cache`, `queryOptions` — опции кеширования/повторов; - `showErrorNotification` — показывать ли уведомление об ошибке (по умолчанию `true`). Запрос выполняется единой функцией `fetch(endpoint, params, controller)` (`module/api/endpoints.ts`), которая через `httpService` (`module/api/http-service.ts`, обёртка `createHttpService` из `@sarex-team/sdk-js` поверх `axios`) отправляет запрос на базовый хост сервиса. Базовый хост выбирается по паре «`service` + окружение»: `httpService` создаётся с картой хостов `apiHosts` и текущим `buildEnv`, и разрешает хост внутри себя. Тот же алгоритм продублирован в экспортируемом хелпере `resolveHost(service)` из `module/api/hosts.ts`. Итоговый URL = `<базовый хост сервиса>` + `path` эндпоинта. Окружение определяется глобальной константой `BUILD_ENV`, которую webpack подставляет в бандл через `DefinePlugin` (`webpack.config.js`) из переменной сборки `process.env.BUILD_ENV`. Допустимые значения проверяются в `env.js`: `local`/`stage`/`preprod`/`prod`/`contour`. В режиме `local` тип http-сервиса переключается на `"original"` (`module/api/http-service.ts`). Ошибки маппируются в человекочитаемые сообщения в `module/api/errors.ts` (`resolveNetworkErrorByCode`, `resolveNetworkError`). ## Базовые хосты по сервисам и окружениям Значения из `module/api/hosts.ts` (объект `apiHosts`). Итоговый URL = `<базовый хост сервиса>` + `path` эндпоинта. | Сервис (`service`) | Назначение | `local` | `stage` | `preprod` | `prod` | `contour` | | --- | --- | --- | --- | --- | --- | --- | | `sarex` | Локальный сервис данных (`/api/core`, `/api/client`) | `/sarex-backend` | `/` | `/` | `/` | `/` | | `documentations` | Сервис документации (документы, бандлы, файлы) | `https://stage-api.sarex.io/documentations` | `https://stage-api.sarex.io/documentations` | `https://api.preprod.sarex.io/documentations` | `https://api.sarex.io/documentations` | `/documentations` | | `sarexApi` | Gateway/API Sarex (`/gateway`, `/eav`, `/cde`, `/transmittals`, `/flows`, `/issues`) | `https://stage-api.sarex.io` | `https://stage-api.sarex.io` | `https://api.preprod.sarex.io` | `https://api.sarex.io` | `/` | | `workspaces` | Сервис рабочих областей | `https://stage-api.sarex.io/workspaces` | `https://stage-api.sarex.io/workspaces` | `https://api.preprod.sarex.io/workspaces` | `https://api.sarex.io/workspaces` | `/workspaces` | | `workflows` | Сервис обработки документов | `https://stage-api.sarex.io/workflows` | `https://stage-api.sarex.io/workflows` | `https://api.preprod.sarex.io/workflows` | `https://api.sarex.io/workflows` | `/workflows` | | `processes` | Сервис рабочих процессов (flows, reviews) | `https://stage-api.sarex.io/flows` | `https://stage-api.sarex.io/flows` | `https://api.preprod.sarex.io/flows` | `https://api.sarex.io/flows` | `/flows` | | `remarks` | Сервис замечаний | `https://stage-api.sarex.io/remarks` | `https://stage-api.sarex.io/remarks` | `https://api.preprod.sarex.io/remarks` | `https://api.sarex.io/remarks` | `/remarks` | | `files` | Сервис файлов | `https://stage-api.sarex.io/files` | `https://stage-api.sarex.io/files` | `https://api.preprod.sarex.io/files` | `https://api.sarex.io/files` | `/files` | | `google` | Временное хранилище (GCS) | `https://storage.googleapis.com/srx-tmp` | `https://storage.googleapis.com/srx-tmp` | `https://storage.googleapis.com/srx-tmp` | `https://storage.googleapis.com/srx-tmp` | `https://storage.googleapis.com/srx-tmp` | | `bim` | BIM-API | `https://stage-bim-api.sarex.io` | `https://stage-bim-api.sarex.io` | `https://bim-api.preprod.sarex.io` | `https://bim-api.sarex.io` | `""` | | `zitadel` | IdP (аутентификация) | `https://idp.dev.stage.sarex.io` | `https://idp.dev.stage.sarex.io` | `https://login.preprod.sarex.io` | `https://login.sarex.io` | `""` | > Хосты `google`, `bim` и `zitadel` заданы в карте хостов, но напрямую в реестре `endpoints` не используются — они задействованы через SDK/вьюер (`@sarex-team/sdk-js`) и механизм аутентификации. В окружении `local` сервис `sarex` проксируется на `/sarex-backend`, в `stage`/`preprod`/`prod` — на `/` (относительные пути), в `contour` все сервисы работают по относительным путям изолированного контура. Отдельного `module-hosts.ts` (карты хостов удалённых модулей) в репозитории нет. ## Эндпоинты по сервисам ### `sarex` — Локальный сервис данных | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getSettings` | GET | `/api/client/settings/` | Клиентские настройки (кешируется, `stateTime: 5`) | | `getUser` | GET | `/api/core/users/{userId}/` | Пользователь по id | | `getUsersByCompanyId` | GET | `/api/core/users/?company={companyId}&limit={limit}&offset={offset}` | Пользователи компании (пагинация) | | `getTargets` | GET | `/api/core/targets/` | Список таргетов | | `getCompanies` | GET | `/api/core/companies/` | Список компаний | | `getDepartmentById` | GET | `/api/core/admin/departments?company={companyId}` | Отделы компании | | `getUsersPositionById` | GET | `/api/core/admin/positions/?company={companyId}` | Должности компании | | `getMrpaList` | POST | `/api/core/mrpa/list/` | Список МЧД (фильтр по пользователю/компании) | | `getByFullUrl` | GET | `{url}` | Запрос по произвольному URL | ### `documentations` — Сервис документации | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getDisks` | GET | `/api/v1/disks` | Список дисков | | `getDocumentTypes` | GET | `/api/v1/documents/types` | Справочник типов документов | | `getAllPermmission` | GET | `/api/v1/permissions` | Все права доступа | | `getDocPermission` | GET | `/api/v1/documents/{id}/permissions` | Права доступа документа | | `postPermission` | POST | `/api/v1/documents/{id}/permissions` | Выдать права сервисному аккаунту | | `postBundle` | POST | `/api/v1/bundles` | Создать бандл | | `postFile` | POST | `/api/v1/bundles/{bundleId}/{fileKey}?single_upload=1` | Загрузить файл (single upload) | | `uploadFileStart` | POST | `/api/v1/bundles/{bundleId}/{key}/upload_multipart` | Начать multipart-загрузку файла | | `uploadFolderStart` | POST | `/api/v1/bundles/{bundleId}/{key}/upload_multipart?upload_path={folderPath}` | Начать multipart-загрузку с указанием пути | | `uploadPart` | PUT | `/api/v1/bundles/{bundleId}/{bundleKey}?part_number={partNumber}` | Загрузить часть файла | | `bundleComplite` | POST | `/api/v1/bundles/{bundleId}/upload_finish` | Завершить загрузку бандла | | `bundleCompleteUpload` | POST | `/api/v1/bundles/{bundleId}/upload_finish` | Завершить загрузку бандла (дубль ключа) | | `getFile` | GET | `/api/v1/bundles/{bundleId}/{bundleKey}` | Получить файл бандла | | `updateComment` | PATCH | `/api/v1/bundles/{bundleId}/comment` | Обновить комментарий бандла | | `getBundles` | GET | `/api/v1/documents/{id}/bundles` | Бандлы документа | | `addBundle` | POST | `/api/v1/documents/{documentId}/add_bundle` | Привязать бандл к документу | | `moveBundles` | PATCH | `/api/v1/documents/{documentId}/move_bundles` | Переместить бандлы | | `removeBundle` | DELETE | `/api/v1/bundles/{id}` | Удалить бандл | | `postWorkspace` | POST | `/api/v1/workspaces` | Создать рабочую область | | `getDocumentById` | GET | `/api/v1/documents/{id}` | Документ по id | | `getDocumentWithBundles` | GET | `/api/v1/documents/{id}?extend=bundles` | Документ с бандлами | | `changeDocument` | PATCH | `/api/v1/documents/{documentId}` | Переименовать документ | | `changeDocumentName` | PATCH | `/api/v1/documents/{id}` | Переименовать документ | | `updatePath` | PATCH | `/api/v1/documents/{id}/update-path` | Сменить родителя документа | | `updateDocumentsPaths` | PATCH | `/api/v1/documents/update-path` | Массовая смена родителя | | `deleteDocument` | DELETE | `/api/v1/documents/{id}` | Удалить документ | | `deleteDocuments` | DELETE | `/api/v1/documents?document_ids={ids}` | Удалить несколько документов | | `getFolderChildrenWithActiveProcesses` | POST | `/api/v1/documents/flows` | Дети папки с активными процессами | | `downloadFile` | GET | `/api/v1/bundles/{lastBundleId}/{key}/download` | Скачать файл (с флагами `include_original_pdf`/`include_printable_pdf`) | | `downloadFiles` | GET | `/api/v1/download_url/documents?document_ids={documentIds}` | Получить ссылку на скачивание документов | | `downloadAllFiles` | GET | `/api/v1/bundles/{lastBundleId}/download` | Скачать все файлы бандла | | `downloadFolder` | GET | `/api/v1/documents/{docId}/download?depth={depth}` | Скачать папку | | `getFoldersDownloadUrl` | GET | `/api/v1/documents/get_folders_download_url?document_ids={ids}` | Ссылка на скачивание папок | | `conversionFile` | POST | `/api/v1/conversion` | Конвертация документа (в IFC) | | `addMarks` | PUT | `/api/v1/bundles/{bundleId}/marks` | Добавить штампы/QR/подписи | | `sign` | POST | `/api/v1/bundles/{bundleId}/sign` | Подписать бандл | | `cancelQrCode` | PATCH | `/api/v1/bundles/{bundleId}/cancel_qr` | Отменить QR-код | | `restartWorkflow` | POST | `/api/v1/bundles/{bundleId}/restart` | Перезапустить workflow бандла | | `getPublicLink` | GET | `/api/v1/public/documents/public_link/{public_link_id}` | Получить публичную ссылку | | `createPublicLink` | POST | `/api/v1/documents/public_link` | Создать публичную ссылку | | `updatePublicLink` | PATCH | `/api/v1/documents/public_link/{public_link_id}` | Обновить публичную ссылку | | `deletePublicLink` | DELETE | `/api/v1/documents/public_link/{public_link_id}` | Удалить публичную ссылку | | `removeDoc` | DELETE | `/api/v1/documents/bin?parent_id={id}` | Переместить в корзину | | `recoveryDocument` | PATCH | `/api/v1/documents/bin/restore?parent_id={id}` | Восстановить из корзины | | `copyFolderStructure` | POST | `/api/v1/documents/copy_structure` | Копировать структуру папок | | `getTemplateJSON` | GET | `/api/v1/templates/{bundleId}` | JSON-шаблон бандла | | `uploadSingleTemplate` | POST | `/api/v1/bundles/{bundleId}/{key}/upload_single` | Загрузить файл шаблона | | `createReport` | POST | `/api/v1/documents/create_report` | Сформировать отчёт по документам | | `updateChangelog` | PATCH | `api/v1/changelogs/{bundleId}` | Обновить запись журнала изменений | | `createChangelog` | POST | `api/v1/changelogs/create` | Создать запись журнала изменений | | `getFavorites` | GET | `/api/v1/favorite_documents?company_id={companyId}` | Избранные документы | | `createFavoriteDocument` | POST | `/api/v1/favorite_documents` | Добавить документ в избранное | | `deleteFavoriteDocument` | DELETE | `/api/v1/favorite_documents/{documentId}` | Убрать документ из избранного | | `getNearestNameTemplate` | GET | `/api/v1/documents/{documentId}/name_template` | Ближайший шаблон именования (без уведомления об ошибке) | | `getDocumentNameTemplate` | GET | `/api/v1/name_templates/{documentId}` | Шаблон именования документа (без уведомления об ошибке) | | `createNameTemplate` | POST | `/api/v1/name_templates/create` | Создать шаблон именования | | `updateNameTemplate` | PATCH | `/api/v1/name_templates/{documentId}` | Обновить шаблон именования | | `deleteNameTemplate` | DELETE | `/api/v1/name_templates/{documentId}` | Удалить шаблон именования | | `createLink` | POST | `/api/v1/links` | Создать ярлык (ссылку на документ) | | `getBundleMrpas` | GET | `/api/v1/bundles/{bundleId}/mrpas` | МЧД бандла | ### `sarexApi` — Gateway/API Sarex Через этот сервис проходят запросы к `/gateway`, `/eav`, `/cde`, а также к сабпутям других доменов, доступным через общий шлюз: `/transmittals`, `/flows`, `/issues`. | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getDocuments` | GET | `/gateway/api/v1/disks/{id}/documents?parent_id={parentId}&child_id={childId}` | Документы диска (по родителю/потомку) | | `getFolderChildren` | GET | `/gateway/api/v1/disks/{diskId}/documents?parent_id={documentId}` | Дети папки | | `getSearch` | GET | `/gateway/api/v4/disks/{diskId}/documents?...` | Поиск/фильтрация документов (root_document, limit, filters, bookmark) | | `createDocument` | POST | `/gateway/api/v1/documents` | Создать документ/папку/проект | | `fetchDocumentPaths` | POST | `/gateway/api/v1/documents/ancestors` | Предки документов | | `getAttributesByDocument` | GET | `/gateway/api/v1/documents/{id}/attributes` | Атрибуты документа | | `updateAttributes` | PUT | `/gateway/api/v1/documents/{id}/attributes` | Обновить атрибуты документа | | `addAttributes` | POST | `/gateway/eav/api/v0/entity/` | Создать сущность атрибутов (EAV) | | `getDefaultAttributes` | GET | `/eav/api/v0/schema/?model=document&company_id={companyId}&type_identifier={docType}` | Схема атрибутов по типу | | `getAttributes` | GET | `/eav/api/v0/attribute/?company_id={params}` | Атрибуты компании | | `getAttributesWithParams` | GET | `/eav/api/v0/schema/?model=document&{params}` | Схема атрибутов с параметрами | | `updateSubscription` | POST | `/gateway/api/v1/subscription/` | Создать/обновить подписку | | `deleteSubscription` | DELETE | `/gateway/api/v1/documents/{documentId}/subscription/` | Удалить подписку | | `getActivityLog` | GET | `/gateway/api/v1/system_log/?model_names=document&...` | Журнал активности документа | | `fetchResourceByDocumentId` | GET | `/gateway/api/v1/resources-rpc/resource-by-document-id/{id}/` | Ресурс по id документа | | `getUsersWithTransmittalProjectPermissions` | GET | `/gateway/api/v2/users/?limit=5000&offset=0&resource_id={projectId}&permissions={permissions}` | Пользователи с правами в проекте | | `getRemovedDocuments` | GET | `/gateway/api/v1/documents/bin?parent_id={id}{params}` | Удалённые документы в папке | | `getRemovedFilteredDocuments` | GET | `/gateway/api/v1/documents/bin{params}` | Удалённые документы (фильтр) | | `getTemplates` | GET | `/gateway/api/v1/disks/{diskId}/flat_documents?type={type}` | Плоский список документов по типу | | `getFileSize` | GET | `/gateway/api/v1/documents/size?disk_id={diskId}&document_id={documentId}` | Размер документа | | `completeUpload` | POST | `{uploadUrl}/complete` | Завершение загрузки (по переданному URL) | | `createTransmittal` | POST | `/transmittals/api/v1/transmittals/create` | Создать трансмиттал | | `getTransmittalById` | GET | `/transmittals/api/v1/transmittals/{transmittalId}` | Трансмиттал по id | | `getTransmittalsByBundleId` | POST | `/transmittals/internal/v1/transmittals/by_bundle_ids` | Трансмитталы по id бандлов | | `getTemplateListForSelect` | GET | `/transmittals/api/v1/transmittal_templates/select?resource={resourceId}` | Список шаблонов трансмитталов для выбора | | `getSingleTemplate` | GET | `/transmittals/api/v1/transmittal_templates/{templateId}?resource={resourceId}` | Шаблон трансмиттала по id | | `createPrescriptionDocument` | POST | `/issues/api/prescriptions/{prescriptionId}/generate/` | Сгенерировать документ по предписанию | | `loadReviewData` | GET | `/flows/api/v1/documents/?bundle_ids={ids}&limit=10000&full=true` | Данные согласований по бандлам (с явным access-токеном) | | `searchAssets` | POST | `eav/api/v4/assets/search/` | Поиск активов по id | | `getProjectAssets` | GET | `eav/api/v4/assets/?linkable_to_project={resourceId}&parentId=null` | Активы проекта | | `getAssetsList` | GET | `eav/api/v4/assets/?tenant_id={tenantId}&linkable_to_project={resourceId}&depth=0&...` | Список активов (поиск/пагинация) | | `getAssets` | GET | `eav/api/v4/assets/?{params}` | Активы по произвольным параметрам | | `getAssetLevels` | GET | `eav/api/v4/assets/?tenant_id={tenantId}&parent_id={parentAssetId}&path_contains={id}` | Уровни активов | | `getBindings` | GET | `/cde/app/v1/bundles/{bundleId}/bindings` | Привязки бандла | | `createSession` | POST | `/cde/app/v1/s32d/sessions/` | Создать S32D-сессию | | `getSessionList` | GET | `/cde/app/v1/s32d/sessions/` | Список S32D-сессий | | `uploadS32DSingle` | PUT | `/cde/app/v1/s32d/sessions/{sessionId}/archive` | Загрузить архив S32D (single) | | `s32dMultipartInit` | POST | `/cde/app/v1/s32d/sessions/{sessionId}/archive/multipart` | Начать multipart-загрузку архива S32D | | `s32dMultipartUploadPart` | PUT | `/cde/app/v1/s32d/sessions/{sessionId}/archive/multipart/{uploadId}/parts/{partNumber}` | Загрузить часть архива S32D | | `s32dMultipartComplete` | POST | `/cde/app/v1/s32d/sessions/{sessionId}/archive/multipart/{uploadId}/complete` | Завершить multipart-загрузку S32D | | `startS32DProcess` | POST | `/cde/app/v1/s32d/sessions/{sessionId}/process` | Запустить обработку S32D | ### `processes` — Сервис рабочих процессов (flows) | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getProcesses` | GET | `/api/v1/flows/?{query}` | Список процессов (flows) | | `createReview` | POST | `/api/v1/reviews/` | Создать review | | `deleteReview` | DELETE | `/api/v1/reviews/{id}/` | Удалить review | | `activateReview` | PATCH | `/api/v1/reviews/{id}/approve/` | Активировать/утвердить review | | `createReviewDocuments` | POST | `/api/v1/documents/` | Добавить документы в review | ### `workflows` — Сервис обработки документов | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getWorkflow` | GET | `/api/v1/workflows/{workflowId}` | Workflow по id | | `getWorkflows` | POST | `/api/v1/workflows/batch` | Пакетное получение workflow | ### `workspaces` — Сервис рабочих областей | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getWorkspaces` | GET | `/api/v1/workspaces/{uuid}` | Рабочая область по uuid | ### `remarks` — Сервис замечаний | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getRemarksTotalCount` | GET | `/api/v1/total_count` | Общее число замечаний | ### `files` — Сервис файлов | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `downloadBundlesMrpas` | POST | `/api/v1/bundles_mrpas/` | Скачать МЧД бандлов (ответ `blob`) | ## Обработка ошибок Маппинг ошибок выполняется в `module/api/errors.ts`. Функция `fetch` (`module/api/endpoints.ts`) перехватывает `AxiosError` и вызывает: - `resolveNetworkErrorByCode(service, code, endpoint, method, data)` — при HTTP-ответе с кодом ≥ 400 и при отмене запроса (`CanceledError`/`ERR_CANCELED`, внутренний код `-1` → «Запрос был отменен»); - `resolveNetworkError(service, error)` — при сетевой ошибке без ответа сервера. Базовый маппинг кодов (`httpCodeToError`): `400` — «некорректный формат запроса», `401` — «ошибка авторизации», `403` — «доступ запрещен», `404` — «ресурс не найден», `500` — «ошибка сервера». Для неизвестного кода подбирается ближайший (`4xx` → `400`, иначе → `500`). К сообщению добавляется человекочитаемое имя сервиса из `getServiceToName()` (напр. `documentations`/`sarexApi` → «Сервис документации», `sarex` → «Локальный сервис данных», `processes` → «Сервис рабочих процессов», `workflows` → «Сервис обработки документов», `remarks` → «Сервис замечаний», `workspaces` → «Сервис рабочих областей», `files` → «Сервис файлов»). Для части кодов сообщение уточняется по эндпоинту и методу: - `401` — набор сообщений `error401Messages` (истёкшая/невалидная сессия, завершённая сессия); по умолчанию — «Ваш токен невалиден, обновите страницу». - `403` — тип определяется `determine403ErrorType(endpoint, method)` (напр. чтение/создание/редактирование/удаление/перемещение документа, скачивание, загрузка файла, управление доступом, изменение атрибутов, создание review/трансмиттала, доступ к диску/проекту), сообщения — `error403Messages`. - `400` — тип определяется `determine400ErrorType(endpoint, method, data)` с анализом текста `data.message` (конфликт имени, дубликат, отсутствие/некорректность расширения, некорректный формат), сообщения — `error400Messages`. - `409` — тип определяется `determine409ErrorType(endpoint, method, data)` (дубликаты имён документов/папок/ярлыков, конфликт при `copy_structure`), сообщения — `error409Messages`. По умолчанию у запросов включён показ уведомления об ошибке (`showErrorNotification !== false`); отдельные эндпоинты отключают его (`getNearestNameTemplate`, `getDocumentNameTemplate`). Типы кодов ошибок описаны в `module/api/types.ts`.