Initial project import

This commit is contained in:
2026-08-14 09:40:51 +03:00
parent 00040e5ce4
commit d7099bf80d
146 changed files with 30509 additions and 1055 deletions
+224
View File
@@ -0,0 +1,224 @@
# Аналитика адаптера 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. Нажать «Карточка»: открывается диалог с успешным статусом и читаемой длительностью.