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

171 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Отчёт: интеграция внешнего приложения — данные сотрудников (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`:
```55:55:d:\MeraProject\.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`:
```104:107:d:\MeraProject\module\core\core\model.php
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. Аутентификация для внешнего клиента
### 4.1. Cookie после `login`
После успешного входа выставляются cookie (имена в модели):
- **`fg_emp_id`** — id сотрудника
- **`fg_emp_h`** — **не хэш пароля**, а значение поля пароля из БД (сервер сравнивает cookie с текущим значением в записи — см. `if_auth`).
```482:493:d:\MeraProject\themes\merakomis\emp\model.php
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).*