meraproject/docs/integration-external-app-employees.md
keboss-m 5c21d25d45 Initial commit: Merakomis portal, Docker stack and user-reader API.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-24 11:04:05 +03:00

12 KiB
Raw Permalink Blame History

Отчёт: интеграция внешнего приложения — данные сотрудников (Merakomis)

Дата: 13.05.2026
Кодовая база: d:\MeraProject (PHP CMS, тема themes\merakomis).

1. Краткий вывод

  • Данные сотрудников хранятся в модуле themes\merakomis\Emp (таблица tMerakomisEmp, контроллер CMS themes.merakomis.emp).
  • Публичного REST API с API-ключом для выгрузки сотрудников в коде нет. Доступ к спискам и карточкам строится на сессии через cookie после входа (login), по тем же правилам, что и веб-интерфейс.
  • Для вызова из браузера с другого домена хост должен попадать в белый список CORS в module/engine.php (для продуктивного домена Merakomis указан merakomis.in).

2. Как устроен HTTP API движка

2.1. Маршрутизация

В корневом .htaccess:

RewriteRule ^api/([^/]+)?/?([^/]+)?/$ index.php?api=1&module=$1&action=$2&%{QUERY_STRING} [L]

Пример: https://<хост>/api/themes.merakomis.emp/login/api=1, module=themes.merakomis.emp, action=login.

Альтернатива — query-string: index.php?api=1&module=themes.merakomis.emp&action=login.

2.2. Вызов контроллера

В module/engine.php при api=1 создаётся класс:

  • Имя класса: controller\<module с точками как NS>\Api
  • Для сотрудников: controller\themes\merakomis\emp\Api (файл themes\merakomis\emp\controller.php).

Вызывается метод с именем из параметра action.

2.3. Тело запроса (JSON)

При Content-Type: application/json тело подставляется в $_POST:

        if(substr($_SERVER["CONTENT_TYPE"],0,16) ==  'application/json') {
            $_POST = json_decode(file_get_contents('php://input'),true);

Имеет смысл отправлять JSON с клиента, как это делает фронтенд CMS.

2.4. CORS

Для ряда хостов, включая merakomis.in, при api=1 выставляются заголовки Access-Control-Allow-Origin: * и др. — см. module/engine.php (список HTTP_HOST).

3. Модель «сотрудник» (поля БД / сущности)

Основные константы полей в themes\merakomis\emp\model.php (фрагмент):

  • Идентификация и доступ: id, name, login, email, pass, type, active, accept, archive, portal, account, …
  • Контакты и профиль: phone, skype, discrod (поле Discord в коде), city, image, birthdate, date_hire, …
  • Орг. данные: org, org_type, staffing, status, is_freelancer, …
  • Прочее: salary, tg_acc (Telegram), группы group, и т.д.

Форматирование записи для API/карточек — методы Emp::format() и Emp::getPublicData($emp_id) (учёт прав через themes\merakomis\emp\Rules).

4. Аутентификация для внешнего клиента

После успешного входа выставляются cookie (имена в модели):

  • fg_emp_id — id сотрудника
  • fg_emp_hне хэш пароля, а значение поля пароля из БД (сервер сравнивает cookie с текущим значением в записи — см. if_auth).
    static function if_auth(){
        if($uid = intval($_COOKIE[ self::$cookieIDKey ]) and $hash = $_COOKIE[ self::$cookieHashKey ]) {
            $acc = self::getByID($uid);
            $res = ( strcmp($acc[self::$PASSWORD],$hash)==0
                    && boolval($acc[self::$ACTIVE])
                    && !boolval($acc[self::$ARCHIVE])
                    && !boolval($acc[self::$REMOVED])
                )

Внешнее приложение (сервер-сервер или мобильное) должно сохранять и передавать эти cookie на последующие запросы к /api/....

4.2. Двухфакторная цепочка через Telegram

Если у учётной записи включена схема «Telegram», login может вернуть e: 3 и key: тогда ожидается повторный запрос с полями key, code (код из Telegram). Это нужно заложить в сценарий интеграции.

5. Методы controller\themes\merakomis\emp\Api (по коду)

Модуль: themes.merakomis.emp. Базовый URL:
https://<хост>/api/themes.merakomis.emp/<action>/

action Назначение Авторизация
login Вход (login, pass; при Telegram — доп. key, code) Нет
reg Регистрация Нет
remind Восстановление пароля Нет
new_pass Установка пароля по ссылке восстановления Нет
exit Выход (сброс сессии) Ожидается cookie
getTableData Таблица сотрудников (разные «режимы» через data в теле запроса) Требуется (Emp::$IS_AUTH)
getForm Данные формы редактирования (как в CMS) Требуется
getData Карточка по id (POST) Требуется
getMyData Текущий авторизованный сотрудник (Emp::format) Требуется
getMyForm Публичная карточка / форма (Emp::getPublicData) Требуется
updateMe Обновление своих контактов (phone, skype, discord) Требуется
updatePassword Смена пароля Требуется
getBirthday Именинники на сегодня (для авторизованных) Требуется
isSummaryAnalysis Флаг доступа к сводному анализу (Rules::isAnalysisProjectsSummary) Требуется
qr / toTelegram / checkTelegram / removeTelegram Интеграция с Telegram Частично / полностью только с сессией

Наследованные из merakomisControllerTable (при наличии вызова с фронта): getForm, getTableData фильтруют данные только если Emp::$IS_AUTH.

5.1. Режимы getTableData (список сотрудников)

Реализация в themes\merakomis\emp\controller.php задаёт набор колонок и фильтры в зависимости от флагов в post['data']:

  • my_company — «Моя компания»: неархивные (archive = 0), контактные колонки (имя, staffing, роли, skype, discord, email, город и т.д.).
  • my — подчинённые/доступные id: если нет «superview», ограничение Emp::getSubEmps(Emp::$AUTH_ID).
  • archive — архив / не архив по data.archive.
  • mini — компактный админ-список.
  • all — расширенные колонки, включая ФОТ и др.

Фактические права на строки определяются логикой Emp / Rules и фильтрами запроса; при интеграции нужно повторить те же запросы, что и клиент CMS, либо задать новый контракт на бэкенде (см. раздел 7).

6. Выгрузка файла (Excel) по сотруднику

В карточке в Emp::format указывается ссылка:

  • /api/themes.merakomis.download/emp/?id=<id> — отдаёт XLSX с полями из Emp::getPublicData (набор колонок зависит от прав текущей сессии).

Класс в проекте: controller\themes\merakomis\download\API (themes\merakomis\download\controller.php, метод emp()). Требуется Emp::$IS_AUTH.

Замечание по именованию: в файле объявлен класс API (все буквы заглавные); при строгом автозагрузчике и регистрозависимой ФС путь .../Api должен совпадать с именем класса. На окружении разработки это уже работает или учтено конфигурацией сервера — при переносе интеграции стоит проверить фактический вызов этого URL в вашей среде.

7. Рекомендуемая стратегия интеграции

Вариант A — использовать текущий API «как веб-клиент» (быстрый старт)

  1. Реализовать HTTP-клиент с cookie jar.
  2. POST /api/themes.merakomis.emp/login/ с учётными данными сервисного пользователя (роль с нужными правами).
  3. Вызывать getTableData / getData / getMyData с JSON-телом, как в интерфейсе.
  4. Учесть CORS только если интеграция идёт из браузера; для server-to-server CORS не нужен.

Минусы: нет отдельного ограничения scope; компрометация учётной записи = полный доступ веб-пользователя; смена пароля ломает интеграцию; зависимость от внутреннего формата getTableData.

Вариант B — отдельный интеграционный endpoint (рекомендуется для продакшена)

Добавить узкий контроллер, например themes.merakomis.emp.integration.Api:

  • авторизация по секрету (заголовок или env), отдельно от cookie пользователя;
  • явные методы: «список сотрудников с полями X», «карточка по id», пагинация;
  • журналирование и ограничение по IP.

Этого нет в текущем репозитории — потребуется разработка и согласование полей (в т.ч. персональные данные, 152-ФЗ).

8. Связанные модули API (справочники и оргструктура)

Для полноценного отображения данных сотрудника используются справочники с собственными Api в themes\merakomis\dictionary\... (город, оргштат, департамент, статусы и т.д.) и модуль команды themes.merakomis.team.member и др. Их можно вызывать тем же шаблоном /api/<module>/<action>/, если есть права у той же сессии.

9. Итоговая таблица «что есть сейчас»

Возможность Есть?
Открытый API-ключ только для чтения сотрудников Нет
JSON API под cookie-сессией сотрудника/админа Да (themes.merakomis.emp)
CORS для стороннего фронта Да, для перечисленных в engine.php хостов
Экспорт карточки в XLSX Да (themes.merakomis.download/emp)

Документ составлен по статическому анализу кода; для точного контракта полей тела запросов к getTableData при необходимости следует снять примеры запросов с рабочего фронтенда (DevTools → Network).