# Эндпоинты, с которыми взаимодействует pm-frontend Документ описывает все HTTP-эндпоинты внешних сервисов, к которым обращается модуль (микрофронтенд `pm-frontend`). ## Как устроено взаимодействие Все REST-запросы идут через единый `httpService` (`src/services/api/http-service.ts`, поверх `@sarex-team/sdk-js` + axios). API-модули объявлены декларативно в `src/store/api/*` и `src/services/api/*` и вызывают `httpService.Request({ service, url, data?, axiosConfig?, errorMessage? })`, где: - `service` — логическое имя сервиса (см. таблицу хостов ниже); - `url` — путь запроса (обычно уже включает свой префикс, напр. `/api/pm/msp/...`); - `data` — тело запроса; `errorMessage` — сообщение при ошибке. Базовый хост подставляется SDK-функцией `resolveHost(service)` по значению `hosts[ENDPOINT].hosts[service]` из `src/services/api/hosts.ts`. Итоговый URL = `<базовый хост сервиса>` + `url`. Прямых вызовов `axios.*`/`fetch()` в `src/` нет. Выбор окружения — сборочная переменная `process.env.ENDPOINT` (инъектируется webpack через `DefinePlugin`). Допустимые значения: `local`, `stage`, `prod`, `preprod`, `contour`; значение по умолчанию — `prod`. Для `local`/`stage` dev-сервер webpack (`configWebpack/buildDevServer.ts`) проксирует относительные префиксы (`/sarex-backend`, `/pm`, `/sarex-eav-v1`, `/sarex-gateway`, `/sarex-api` …) на stage-бэкенды. ## Базовые хосты по сервисам и окружениям Значения из `src/services/api/hosts.ts`. Для сервиса `sarex` в удалённых окружениях хост пустой (`""`) — запросы идут относительно текущего origin (маршрутизируются ingress/gateway перед SPA). | Сервис (`service`) | Назначение | `stage` | `prod` | | --- | --- | --- | --- | | `sarex` | Монолит / PM REST (`/api/pm/...`, `/api/core/...`) | `""` (same-origin) | `""` (same-origin) | | `pm` | PM-микросервис (`/api/v1/...`: интегрированные задачи, комментарии) | `https://stage-api.sarex.io/pm` | `https://api.sarex.io/pm` | | `sarexApi` | API-шлюз для flows (reviews, документы, процессы) | `https://stage-api.sarex.io` | `https://api.sarex.io` | | `eavV1` | Сервис атрибутов EAV (`/api/v2`, `/api/v4`) | `https://stage-api.sarex.io/eav` | `https://api.sarex.io/eav` | | `gateway` | Шлюз ресурсов (`/api/v1/resources`) | `https://stage-api.sarex.io/gateway` | `https://api.sarex.io/gateway` | | `notifications` | Лямбда уведомлений | `https://stage-api.sarex.io/lambdas/notification` | `https://api.sarex.io/lambdas/notification` | | `bimv2` | BIM v2 | `https://stage-api.sarex.io/bimv2` | `https://api.sarex.io/bimv2` | | `bim` | BIM v1 | `https://stage-api.sarex.io/bim` | `https://api.sarex.io/bim` | | `analyticsV2` | Аналитика v2 | `https://stage-api.sarex.io/analytics-v2` | `https://api.sarex.io/analytics-v2` | | `workspaces` | Сервис рабочих областей | `https://stage-api.sarex.io/workspaces` | `https://api.sarex.io/workspaces` | | `documentations` | Сервис документаций | `https://stage-api.sarex.io/documentations` | `https://api.sarex.io/documentations` | | `workflows` | Сервис обработки документов | `https://stage-api.sarex.io/workflows` | `https://api.sarex.io/workflows` | | `comparisons` | Сервис сравнений | `https://stage-api.sarex.io/comparisons` | `https://api.sarex.io/comparisons` | | `remarks` | Сервис замечаний | `https://stage-api.sarex.io/remarks` | `https://api.sarex.io/remarks` | | `projects` | Сервис проектов | `https://stage-api.sarex.io/projects` | `https://api.sarex.io/projects` | | `zitadel` | IdP (аутентификация) | `https://idp.dev.stage.sarex.io` | `https://login.sarex.io` | | `google` | Временное хранилище (GCS) | `https://storage.googleapis.com/srx-tmp` | `https://storage.googleapis.com/srx-tmp` | > Также определены окружения `local` (относительные прокси-префиксы) и `preprod`/`contour`. Реально используются в коде только `sarex`, `pm`, `sarexApi`, `eavV1`, `gateway`; остальные сервисы объявлены в hosts, но REST-вызовов к ним в этом модуле нет. Кроме REST есть WebSocket (`src/store/stores/gantt/ganttWebsocket.ts`): `io(`${url}/project`, { path: "/message-hub/socket.io" })`, где `url` — `https://stage-api.sarex.io` (stage) / `https://api.sarex.io` (prod). ## Эндпоинты по модулям ### `store/api/api.ts` — ProjectsAPI (сервис `sarex`, если не указано иное) | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getFolderById` | GET | `/api/pm/msp/folders/{folderId}` | Папка по id | | `getProjectsAndFolders` | GET | `/api/pm/msp/projects/?{query}` | Список проектов и папок | | `getProjectTemplates` | GET | `/api/pm/msp/projects/?{query}` | Список шаблонов проектов | | `getAllProjects` | GET | `/api/pm/msp/projects/` | Все проекты | | `getAllProjectsWithNotFolders` | GET | `/api/pm/msp/projects/?schema=tiny&is_folder=false&company_id={companyId}` | Проекты (без папок) по компании | | `getProject` | GET | `/api/pm/msp/projects/{projectId}/?extend=true` | Проект (расширенный) | | `getKeyMilestones` | GET | `/api/pm/msp/projects/{projectId}/key_milestones/` | Ключевые вехи проекта | | `getResourcePlanning` | GET | `/api/pm/msp/resources/resource_planning/?projects={projects}&start={start}&end={end}&resource_type=human&scale={scale}` | Ресурсное планирование | | `changeResourceForTask` | PATCH | `/api/pm/msp/resources-tasks/assign/` | Назначить ресурс на задачу | | `getIntegratedProjects` | GET | `/api/v1/projects/{projectId}/integrated-tasks/` (сервис `pm`) | Интегрированные задачи проекта | | `createProject` | POST | `/api/pm/msp/projects/` | Создать проект | | `importProject` / `importProjectV2` | POST | `/api/pm/msp/projects/import/` | Импорт проекта | | `updateProjectV2` | PATCH | `/api/pm/msp/projects/{projectId}/` | Обновить проект | | `updateFolders` | GET | `/api/pm/msp/projects/?{idsQuery}` | Папки по id | | `deleteProject` | DELETE | `/api/pm/msp/projects/{id}` | Удалить проект | | `createProjectTemplate` | POST | `/api/pm/msp/projects/{projectId}/create_template/` | Создать шаблон из проекта | | `getProjectStates` | GET | `/api/pm/msp/projects/{id}/states/` | Базовые планы проекта | | `createProjectState` | POST | `/api/pm/msp/project-states/` | Создать базовый план | | `updateProjectState` | PUT | `/api/pm/msp/project-states/{id}/` | Обновить базовый план | | `deleteProjectState` | DELETE | `/api/pm/msp/project-states/{id}/` | Удалить базовый план | | `patchProjectStateDifferenceData` | PATCH | `/api/pm/msp/project-states/{stateId}/edit_state/` | Изменить данные базового плана | | `getProjectState` | GET | `/api/pm/msp/project-states/{id}/` | Базовый план по id | | `getProjectStateData` | GET | `/api/pm/msp/project-states/{id}/data/` | Данные базового плана | | `addTasksToBasicPlan` | POST | `/api/pm/msp/project-states/{planId}/data/` | Добавить задачи в базовый план | | `getStatusImport` | GET | `/api/pm/msp/external-task-info/?task_id={uuid}` | Статус фоновой задачи импорта | | `getTasks` | GET | `/api/pm/msp/projects/{id}/tasks/` | Задачи проекта | | `taskIndex` | PATCH | `/api/pm/msp/tasks/task_index/` | Переиндексация задач | | `bulkCreateTasks` | POST | `/api/pm/msp/projects/{project}/create_tasks/` | Массовое создание задач | | `bulkUpdateTasks` | PATCH | `/api/pm/msp/projects/{project}/update_tasks/` | Массовое обновление задач | | `bulkDeleteTasks` | DELETE | `/api/pm/msp/projects/{project}/delete_tasks/` | Массовое удаление задач | | `copyPasteTasks` | POST | `/api/pm/msp/tasks/copy/` | Копирование задач | | `getTaskDescription` | GET | `/api/pm/msp/tasks/{taskId}/descriptions/` | Описание задачи | | `updateTaskDescription` | PATCH | `/api/pm/msp/tasks/{taskId}/descriptions/` | Обновить описание задачи | | `createComment` | POST | `/api/v1/comments/` (сервис `pm`) | Создать комментарий к задаче | | `getActualValues` | GET | `/api/pm/msp/values/?task={task}` | Фактические значения по задаче | | `createActualValue` | POST | `/api/pm/msp/values/` | Создать фактическое значение | | `updateActualValue` | PUT | `/api/pm/msp/values/{id}/` | Обновить фактическое значение | | `deleteActualValues` | DELETE | `/api/pm/msp/values/{id}/` | Удалить фактическое значение | | `getAllGanttLinks` | GET | `/api/pm/msp/task-relations/{params}` | Связи задач (Ганта) | | `createGanttLinks` | POST | `/api/pm/msp/task-relations/` | Создать связи задач | | `updateGanttLink` | PUT | `/api/pm/msp/task-relations/{id}/` | Обновить связь задач | | `bulkDeleteRelation` | DELETE | `/api/pm/msp/task-relations/bulk_delete/` | Массовое удаление связей | | `getResourcesTable` | GET | `/api/pm/msp/resources/?{query}` | Таблица ресурсов | | `updateResources` | PUT | `/api/pm/msp/resources/{id}/` | Обновить ресурс | | `deleteResource` | DELETE | `/api/pm/msp/resources/{id}/` | Удалить ресурс | | `createVisualProfile` | POST | `/api/pm/msp/visual-profiles/` | Создать визуальный профиль | | `editVisualProfile` | PATCH | `/api/pm/msp/visual-profiles/{id}` | Изменить визуальный профиль | | `getVisualProfiles` | GET | `/api/pm/msp/projects/{projectId}/profiles/` | Визуальные профили проекта | | `getMyTasks` | GET | `/api/pm/msp/tasks/?responsible=true&executors=true&{query}` | Мои задачи | | `copyProject` | POST | `/api/pm/msp/projects/{projectId}/copy_project/` | Копировать проект | | `createProjectDocument` | POST | `/api/pm/msp/projects/{projectId}/ksg_docs_sync/` | Синхронизация КСГ-документов | | `getUsersByCompanyId` | GET | `/api/core/v2/users/?company={companyId}&{query}` | Пользователи компании | | `getDepartmentsV2` | GET | `/api/core/admin/departments/?company={companyId}` | Отделы компании | | `getPositionsV2` | GET | `/api/core/admin/positions/?company={companyId}` | Должности компании | | `getDocumentStatus` | GET | `/flows/api/v1/documents/?full=true&document_ids={ids}` (сервис `sarexApi`) | Статус документов | | `exportTasksPDF` | POST | `/api/pm/msp/projects/{id}/export_project_to_pdf/` | Экспорт проекта в PDF (+опрос `external-task-info`) | | `projectExport` | POST | `/api/pm/msp/projects/{id}/project_export/` | Экспорт проекта (xlsx/xml) | ### `store/api/attributes-api-v2.ts` — AttributesApiV2 | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getProjectAttributes` | GET | `/api/pm/msp/project-attribute/?project={projectId}` (сервис `sarex`) | Атрибуты проекта | | `updateProjectAttribute` | PUT | `/api/pm/msp/project-attribute/{id}/` (сервис `sarex`) | Обновить атрибут проекта | | `deleteProjectAttribute` | DELETE | `/api/pm/msp/project-attribute/{id}/` (сервис `sarex`) | Удалить атрибут проекта | | `addAttributesToProject` | POST | `/api/pm/msp/project-attribute/` (сервис `sarex`) | Привязать атрибуты к проекту | | `getTimeMarkersData` | GET | `/api/pm/msp/projects/{projectID}/time_markers_data/?attributes={ids}&with_hierarchy={flag}` (сервис `sarex`) | Данные временных маркеров | | `getAttributesList` | GET | `/api/v4/attribute/?model_name=gantt-task&company_id={companyId}` (сервис `eavV1`) | Список атрибутов (EAV) | | `getAssetsByAttribute` | GET | `/api/v4/assets/?path_contains={assetsId}` (сервис `eavV1`) | Ассеты по атрибуту | | `getAttributesByAssetsParent` | GET | `/api/v4/assets/?tenant_id={companyId}&depth=0` (сервис `eavV1`) | Корневые ассеты компании | | `createNewAttribute` | POST | `/api/v2/attribute/` (сервис `eavV1`) | Создать атрибут (EAV) | | `updateAttribute` | PATCH | `/api/v2/attribute/{id}/` (сервис `eavV1`) | Обновить атрибут (EAV) | ### `store/api/calculate-api.ts` — CalculatesAPI (сервис `sarex`) | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `postFormula` | POST | `/api/pm/msp/projects/{id}/formula/` | Пересчёт по формуле | ### `store/api/calendarsApi.ts` — CalendarsApi (сервис `sarex`) | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getAllCalendars` | GET | `/api/pm/msp/calendars/` | Все календари | | `getCalendarById` | GET | `/api/pm/msp/calendars/{id}/` | Календарь по id | | `createCalendar` | POST | `/api/pm/msp/calendars/` | Создать календарь | | `editCalendar` | PATCH | `/api/pm/msp/calendars/{id}/` | Изменить календарь | | `deleteCalendar` | DELETE | `/api/pm/msp/calendars/{id}/` | Удалить календарь | ### `store/api/issuesApi.ts` — IssuesApi (сервис `sarex`) | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getIssueTypes` | GET | `/api/pm/msp/entity-relations/?project_id={projectId}` | Типы связей/проблем проекта | | `patchIssueType` | PATCH | `/api/pm/msp/entity-relations/{issueTypeId}/` | Обновить тип связи | | `getIssueData` | GET | `/api/pm/msp/projects/{projectId}/issues_data/` | Данные проблем проекта | ### `store/api/ksgStatesApi.ts` — KsgStatesApi (сервис `sarex`) | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getProjestStates` | GET | `/api/pm/msp/project-settings/?{query}` | Настройки/состояния КСГ | | `createProjectState` | POST | `/api/pm/msp/project-settings/` | Создать состояние КСГ | | `editProjectState` | PATCH | `/api/pm/msp/project-settings/{id}/` | Изменить состояние КСГ | | `deleteProjectAttribute` | DELETE | `/api/pm/msp/project-settings/{id}/` | Удалить состояние КСГ | | `checkApplyState` | POST | `/api/pm/msp/project-settings/{id}/apply/` | Применить состояние КСГ | ### `store/api/permissionsApi.ts` — PermissionsApi (сервис `sarex`) | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getPermissions` | GET | `/api/pm/msp/projects/{projectId}/permissions/` | Права проекта | | `getTaskPermissions` | GET | `/api/pm/msp/tasks/{taskId}/permissions/` | Права задачи | | `getAllTaskPermissions` | GET | `/api/pm/msp/projects/{projectId}/all_permissions/` | Все права задач проекта | | `savePermission` | POST | `/api/pm/msp/projects/{projectId}/permissions/` | Сохранить права проекта | | `saveTaskPermission` | POST | `/api/pm/msp/tasks/{taskId}/permissions/` | Сохранить права задачи | ### `store/api/relationApi.ts` — RelationsApi (сервис `sarex`) | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getProjectRelations` | GET | `/api/pm/msp/projects/{projectId}/relations/` | Связи/интеграции проекта | | `postProjectIntegrations` | POST | `/api/pm/msp/projects/{id}/bulk_integration/` | Массовое создание интеграций | | `updateProjectIntegration` | PATCH | `/api/pm/msp/project-relations/{id}/` | Обновить интеграцию | | `deleteProjectIntegration` | DELETE | `/api/pm/msp/project-relations/{id}/` | Удалить интеграцию | ### `store/api/reviewsApi.ts` — ReviewAPI (сервис `sarexApi`) | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `createReview` | POST | `/flows/api/v1/reviews/` | Создать ревью/согласование | | `getProcesses` | GET | `/flows/api/v1/flows/?{query}` | Процессы/потоки согласования | ### `store/api/systemLogApi.ts` — SystemLogApi (сервис `sarex`) | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getNewSystemLogs` | GET | `/api/pm/msp/projects/{projectId}/system-logs/?{query}` | Системные логи проекта | | `getDetailsSystemLog` | GET | `/api/pm/msp/projects/{projectId}/system-log-detail/?log_id={logId}` | Детали записи лога | | `rollBack` | POST | `/api/pm/msp/projects/{projectId}/rollback-to-record/` | Откат к записи лога | ### `store/api/taskDetailingApi.ts` — TaskDetailingApi (сервис `sarex`) | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getRole` | GET | `/api/pm/msp/projects/{projectId}/rule/` | Правило детализации проекта | | `createRule` | POST | `/api/pm/msp/projects/{projectId}/rule/` | Создать правило детализации | | `getDetailTasks` | GET | `/api/pm/msp/detailed-tasks/?task={taskId}` | Детализированные задачи | | `patchDetailTasks` | PATCH | `/api/pm/msp/detailed-tasks/{detailingTaskId}/` | Обновить детализированную задачу | ### `store/api/workspaceApi.ts` — WorkspaceAPI (сервис `sarex`) | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `getResourcesByTaskId` | GET | `/api/pm/msp/resources-tasks/?tasks={task}` | Ресурсы по задаче | | `getResourcesByIds` | GET | `/api/pm/msp/resources/?ids={resourcesIds}` | Ресурсы по id | | `loadElementsByResourceIds` | GET | `/api/pm/msp/resources-elements/?resources={ids}` | Элементы ресурсов | | `connectResourcesTasks` | POST | `/api/pm/msp/resources-tasks/` | Привязать ресурс к задаче | | `editResourcesTasks` | PATCH | `/api/pm/msp/resources-tasks/bulk_update/` | Массово изменить связи ресурс-задача | | `deleteResource` | DELETE | `/api/pm/msp/resources-tasks/bulk_delete/` | Массово удалить связи ресурс-задача | ### `services/api/fetch/gateway.ts` — GatewayAPI (сервис `gateway`) | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `fetchResources` | GET | `/api/v1/resources` | Ресурсы шлюза (доступы/фичи) | ### Gantt-репозитории (`src/pages/TasksNew/GanttWorkspace/repositories/*`, сервис `sarex`) | Ключ | Метод | Путь | Назначение | | --- | --- | --- | --- | | `WorkspaceSelectedKSGProjectRepository` | GET | `/api/pm/msp/projects/?bundle_id={bundleID}&schema=tiny` | Проекты выбранного бандла КСГ | | `TaskResourceConnectionBaseRepository` | GET | `/api/pm/msp/projects/{id}/profiles/` | Профили ресурсов проекта | | `TaskResourcesConnectionsRepository` | GET | `/api/pm/msp/resources-tasks/?projects={project}` | Связи ресурс-задача по проекту | | `TasksRepository` (список) | GET | `/api/pm/msp/tasks/?project={project}&{query}` | Задачи проекта | | `TasksRepository` (одна) | GET | `/api/pm/msp/tasks/{id}/` | Одна задача | | `uploadFileToServer` | POST (multipart) | `/api/pm/msp/descriptions/upload_file/` | Загрузка файла/изображения в описание | ## Обработка ошибок Централизованного middleware (RTK Query `createApi`/`fetchBaseQuery` не используется) нет — API-модули оборачивают axios-based `httpService`. Типичные паттерны: большинство вызовов `.then(r => r.data)` и пробрасывают ошибку выше; часть — `try/catch` с `isAxiosError(error)`, где `403` даёт «Нет доступа»/«Доступ запрещён», а прочие ошибки — общее сообщение (напр. «Не удалось сохранить данные, попробуйте ещё раз»), нередко показываемое через `createToast(...)` и повторно выбрасываемое как `new Error(...)`. Некоторые читают `error.response.data.detail`. `getStatusImport` при ошибке возвращает `{ request_failed: true }`; `exportTasksPDF` опрашивает `external-task-info` каждые 2 с до `is_ready`. Часть вызовов передаёт в SDK опцию `errorMessage` (напр. «Некорректные данные»).