# Аналитика адаптера 1С: передача проекта

Дата актуализации: 2026-08-07.

## Назначение

`adapter-observer` — независимый read-only веб-интерфейс аналитики для SQL-only адаптера 1С. Он читает журналы REST и MCP, получает разрешённые снимки метаданных через публичный API адаптера и не имеет прямого доступа к SQL-базе 1С.

Сервис не является зависимостью `adapter-1c-rest` или `adapter-1c-mcp`: остановка либо обновление observer не должна влиять на работу адаптера.

## Описание адаптера 1С

Адаптер 1С — SQL-only сервис для чтения метаданных и выполнения строго контролируемых операций с saved-state конфигурации 1С. Он работает через подтверждённые структуры SQL-хранилища; не запускает Configurator и не должен выдумывать метаданные, маршруты или двоичные payload.

Основные части:

- `adapter-1c-rest` — REST API адаптера;
- `adapter-1c-mcp` — MCP-шлюз, который вызывает REST API;
- `adapter-1c-audit` — аудит-контур REST;
- `adapter-observer` — независимая аналитика журналов и разрешённых read-only вызовов.

Код адаптера находится в текущем репозитории:

```text
plugins/1c/connector/adapter_1c_server.py   реализация REST/RPC методов
plugins/1c/connector/contracts/openapi.yaml публичный HTTP-контракт
plugins/1c/mcp/adapter_1c_mcp.py             MCP-шлюз
plugins/1c/observer/                         аналитика адаптера
```

### Где развёрнут адаптер

| Контур | REST | MCP | Docker-хост | Назначение |
| --- | --- | --- | --- | --- |
| Production / внешний | `http://docker.cin.su:8011` | `http://docker.cin.su:8021/mcp` | `docker.cin.su` | Основной внешний адаптер и observer. |
| Staging / тестовый | `http://docker-test.cin.su:8011` при наличии тестового стека | `http://docker-test.cin.su:8021/mcp` при наличии тестового стека | `test-docker` | Проверка перед production. |
| Изолированная тестовая база | `base_id=upo_test` | через соответствующий MCP | выбранный контур | Разрешены контролируемые тесты и rollback. |

Production-контейнеры на `docker.cin.su`:

```text
adapter-1c-rest     порт 8011
adapter-1c-mcp      порт 8021
adapter-1c-audit    внутренний аудит REST
adapter-observer    порт 8031
```

## Как проверять новые функции адаптера

### До развёртывания

1. Изменить реализацию в `plugins/1c/connector/adapter_1c_server.py` и зафиксировать публичный контракт в `plugins/1c/connector/contracts/openapi.yaml`.
2. Добавить либо обновить unit/smoke-тест в `tests/1c/` или `scripts/smoke_1c_*.py`.
3. Для новой метадаты или SQL-маршрута сначала получить доказательства из live SQL в `upo_test`; при неполном codec вернуть `unsupported`/`protocol_incomplete`, а не предполагать данные.
4. Прогнать тесты и smoke-проверку на `upo_test`.

### Staging-проверка

Развернуть обновлённые `adapter-1c-rest` и при необходимости `adapter-1c-mcp` на `test-docker`. Не использовать staging вместо external MCP production без явного запроса.

Проверять новый read-only метод через REST/RPC с явным `base_id=upo_test`. Проверка write-маршрута должна пройти обязательные plan/preflight/apply/rollback-gates и не даёт права заявлять, что Configurator принял или активировал изменение.

Полезные проверки:

```powershell
# Контейнеры и порты выбранного контура
docker --host ssh://test-docker ps --format '{{.Names}} {{.Image}} {{.Status}} {{.Ports}}'

# Контракт/доступные методы на REST
Invoke-WebRequest -UseBasicParsing http://docker-test.cin.su:8011/methods

# Health observer после тестового вызова
Invoke-WebRequest -UseBasicParsing http://docker-test.cin.su:8031/health
```

Пути и аргументы нового метода нельзя составлять по догадке: использовать только его документированный контракт и подтверждённые публичные селекторы.

## Как обновлять аналитику вместе с адаптером

Каждое изменение адаптера нужно оценивать как изменение наблюдаемого контракта.

| Изменение адаптера | Что изменить в observer |
| --- | --- |
| Новый метод аудита или новый статус | Проверить `event_view`, фильтр статусов, группировку summary и русские подписи. |
| Новый read-only метод для объекта | Добавить его в жёсткий allowlist `/api/object/action` только после проверки публичного селектора и безопасного ответа. |
| Новый тип метаданных | Добавить его в `treeGroups`, если он должен быть виден в дереве. |
| Новое поле длительности | Оставить в API машинское значение, а в UI провести через `duration()`. |
| Изменение схемы audit JSONL | Сохранить обратную совместимость: неизвестные поля показывать только в деталях, отсутствующие поля считать необязательными. |
| Новый write-маршрут | Не добавлять кнопку выполнения в observer. Допустимо отобразить только подтверждённую capability/статус после отдельного проектного решения. |

Обязательная последовательность релиза:

1. Сначала обновить адаптер и проверить его новый метод на `upo_test`.
2. Убедиться, что REST/MCP audit содержит безопасную запись вызова без SQL, BSL, payload и секретов.
3. Обновить observer в staging; открыть новый сценарий в UI и проверить, что метод не классифицируется как `exception` ошибочно.
4. Обновить observer на production вместе с совместимой версией адаптера.
5. Проверить `/health`, журнал, аналитику и конкретный объект в дереве.

Observer не должен требовать одновременный рестарт адаптера. При выпуске только frontend/observer достаточно пересоздать `adapter-observer`; REST и MCP остаются запущенными.

## Что сделано

### Интерфейс

- Журнал REST-запросов с фильтрами по методу, базе, статусу, периоду и минимальной длительности.
- Аналитика p50/p95, медленных методов, исключений и ожидаемых безопасных отказов.
- Корреляция MCP ↔ REST по `request_id`.
- Дерево метаданных конфигурации с разделом «Справочники».
- Для каждого доступного справочника отображаются read-only действия:
  - Карточка;
  - Свойства;
  - Реквизиты;
  - Формы;
  - Команды;
  - Модули;
  - Макеты;
  - Связи.
- Результат действия открывается в диалоге с названием операции, объектом, статусом и длительностью.
- Поиск по уже загруженному списку справочников и счётчик `Показано: N из M`.

### Время выполнения

- Во всех пользовательских представлениях миллисекунды форматируются в секунды, минуты и часы.
- Фильтр минимальной длительности вводится в секундах.
- В технических API-полях сохраняется `duration_ms`: это контрактное машинное значение, не пользовательская подпись.

### Производительность

- Observer отдаёт до 1000 объектов за один запрос к `metadata.objects.list`.
- Для базы `upo` загружается 798 доступных справочников из 825 объектов одного типа одним запросом; 27 объектов скрыты адаптером как отсутствующие/нечитаемые.
- Проверенное время live-сканирования этого списка: около 18,7 секунды. Это время адаптера и SQL-чтения, а не рендеринга кнопок в браузере.

### Безопасность

- Observer вызывает только жёстко заданный allowlist read-only методов для строки справочника.
- Новые действия не выполняют запись, подготовку saved-state, активацию конфигурации или операции Configurator.
- В интерфейсе не восстанавливаются исторические запросы из audit JSONL.

## Что ещё нужно сделать

Приоритетный следующий этап:

1. Добавить быстрый серверный поиск справочника по имени, чтобы не ожидать полное live-сканирование при работе с одним объектом.
2. Добавить отображение прогресса при загрузке больших разделов: число прочитанных объектов, текущая страница и время ожидания.
3. Вынести перечень разрешённых действий и русские названия в отдельную конфигурацию/контракт, а не хранить в фронтенд-коде.
4. Добавить компактные пользовательские карточки результатов действий вместо показа полного JSON; JSON сохранить как диагностическую вкладку.
5. Добавить тесты UI/HTTP для сценария: открыть «Справочники» → загрузить → увидеть кнопки → выполнить «Карточка».
6. Добавить version/release marker в `/health` и UI, чтобы быстро отличать старую Docker-сборку от актуальной.
7. Добавить снимки и сравнение аналитики между релизами: список методов, покрытие метаданных, p50/p95 и изменения ошибок.
8. До публикации вне внутренней сети определить аутентификацию, роли, срок хранения audit-данных и экспортируемые поля.

Не реализовывать без отдельного разрешения:

- повтор исторических write/activation/repository-запросов;
- прямое подключение observer к SQL 1С;
- запуск или автоматизацию Configurator;
- вывод BSL-текста, SQL-полей, паролей или ключей из журналов.

## Исходные файлы

```text
plugins/1c/observer/
  observer_server.py          HTTP API и безопасный allowlist действий
  web/index.html              оболочка интерфейса
  web/assets/app.js           UI, форматирование времени, дерево, действия
  web/assets/style.css        стили
  Dockerfile                  образ observer

core/deploy/docker/adapter-observer/
  compose.yaml                отдельный Docker Compose стек
  .env.example                пример runtime-переменных

docs/runbooks/adapter-observer.md
  эксплуатационный контракт и ограничения
```

## Docker-развёртывание

### Текущий production-хост

- Docker host: `docker.cin.su`.
- Контейнер: `adapter-observer`.
- URL: `http://docker.cin.su:8031/`.
- Образ: `adapter-observer:latest`.
- Порт: `8031`.
- Внешняя сеть адаптера: `adapter-1c_default`.
- Read-only тома журналов:
  - `adapter-1c_adapter-1c-data` → `/audit:ro`;
  - `adapter-1c-mcp_adapter-1c-mcp-data` → `/mcp-audit:ro`.
- Собственный state-том: `adapter-observer_adapter-observer-state`.

### Команда обновления

Из корня текущего репозитория:

```powershell
$env:DOCKER_HOST = 'ssh://docker.cin.su'
docker compose `
  --project-directory 'Z:\codex\LLM\core\deploy\docker\adapter-observer' `
  -f 'Z:\codex\LLM\core\deploy\docker\adapter-observer\compose.yaml' `
  up -d --build adapter-observer
```

После обновления:

```powershell
Invoke-WebRequest -UseBasicParsing http://docker.cin.su:8031/health
docker --host ssh://docker.cin.su ps --filter 'name=^/adapter-observer$'
```

Команда пересоздаёт только `adapter-observer`. Не запускать `docker compose down` в проектах REST/MCP адаптера и не перезапускать `adapter-1c-rest` или `adapter-1c-mcp` ради обновления аналитики.

### Тестовый хост

Для staging используется тот же стек с `DOCKER_HOST='ssh://test-docker'` и URL `http://docker-test.cin.su:8031/`.

## Проверки после переноса

1. `GET /health` возвращает `status: ok` и показывает файлы REST/MCP audit.
2. Открыть «Дерево объектов» и загрузить `upo`.
3. Нажать «Читать» у «Справочники»: блок должен остаться раскрытым.
4. Убедиться, что видна строка вида `798 объектов · N с` без единицы `мс`.
5. У первой строки должны быть восемь кнопок действий.
6. Нажать «Карточка»: открывается диалог с успешным статусом и читаемой длительностью.
