# Установка и настройка superset-tools ## Содержание - [Требования](#требования) - [Архитектура](#архитектура) - [Технологический стек](#технологический-стек) - [Docker (рекомендуется)](#docker-рекомендуется) - [Локальная разработка](#локальная-разработка) - [Конфигурация](#конфигурация) - [Система сборки](#система-сборки) - [Тестирование](#тестирование) - [Покрытие кода](#покрытие-кода) - [SSL/TLS конфигурация](#ssltls-конфигурация) - [Enterprise Clean Deployment](#enterprise-clean-deployment) - [Спецификации](#спецификации) - [Утилиты](#утилиты) - [Исследования](#исследования) ## Требования - **Docker (рекомендуется):** Docker Engine 24+, Docker Compose v2, 4 GB RAM - **Локальная разработка:** Python 3.9+, Node.js 18+, npm, 2 GB RAM, 5 GB диска ## Архитектура Проект состоит из двух сервисов (внешние ассистенты подключаются через MCP — spec 050): | Сервис | Технологии | Назначение | |---|---|---| | **backend/** | Python FastAPI, SQLAlchemy 2.0, APScheduler, PostgreSQL | REST API, бизнес-логика, плагины, MCP-сервер | | **frontend/** | Svelte 5 (Runes), SvelteKit, Vite, Tailwind CSS | SPA-клиент | ``` superset-tools/ ├── backend/ # REST API (FastAPI) │ ├── src/ │ │ ├── api/routes/ # 30+ роутов (admin, auth, translate, git, agent...) │ │ ├── core/ │ │ │ ├── auth/ # JWT, OAuth, API Keys, RBAC │ │ │ ├── migration/ # Dry-run, risk assessment │ │ │ ├── task_manager/ # Async jobs, event bus, persistence │ │ │ ├── superset_client/ │ │ │ ├── logger/ # Structured logging, belief state │ │ │ └── ... │ │ ├── models/ # SQLAlchemy модели │ │ ├── plugins/ # Реализации плагинов │ │ ├── schemas/ # Pydantic схемы │ │ ├── services/ # Бизнес-логика │ │ └── scripts/ # CLI/TUI админ-скрипты │ └── tests/ ├── frontend/ # SvelteKit SPA │ ├── src/ │ │ ├── routes/ # 20+ групп страниц │ │ ├── lib/ │ │ │ ├── api/ # API клиент │ │ │ ├── auth/ # Auth store, permissions │ │ │ ├── components/ # UI компоненты │ │ │ ├── stores/ # Svelte stores │ │ │ ├── i18n/ # Мультиязычность │ │ │ └── ... │ │ └── ... │ └── tests/ ├── docker/ # Dockerfile, entrypoint, nginx ├── docs/ # Документация, ADR ├── specs/ # 40+ feature specifications ├── scripts/ # Утилиты (coverage, security, build) ├── research/ # Исследования (mcp-superset) ├── semantics/ # Семантическая карта кода ├── dist/ # Релизные бандлы ├── storage/ # Runtime данные (backups, repos) ├── certs/ # SSL-сертификаты └── examples/ # Примеры интеграции ``` ## Технологический стек **Backend:** Python 3.9+ (FastAPI 0.126, SQLAlchemy 2.0, APScheduler 3.11), PostgreSQL 16, Authlib, JWT, OpenAI API, GitPython, Playwright, lingua-language-detector **Frontend:** Svelte 5 (Runes), SvelteKit 2.49, Vite 7, Tailwind CSS 3, Vitest 4.1, Playwright 1.60 **DevOps:** Docker & Docker Compose (3 профиля + E2E), GitHub Actions (CI), Nginx (опциональный SSL) ## Docker (рекомендуется) ### Профили окружения Система поддерживает несколько профилей через `.env` файлы: | Профиль | Файл | Команда | |---|---|---| | **current** | `.env.current` | `docker compose --profile current up --build` | | **master** | `.env.master` | `docker compose --profile master up --build` | | **enterprise-clean** | `.env` | `docker compose -f docker-compose.enterprise-clean.yml up --build` | | **e2e** | `.env.e2e` | `docker compose -f docker-compose.e2e.yml up --build` | ```bash git clone cd superset-tools cp .env.example .env docker compose --profile current up --build ``` После запуска: - Frontend: http://localhost:8000 - Backend API: http://localhost:8001 - PostgreSQL: localhost:5432 ### Offline-бандл ```bash xz -dc dist/docker/superset-tools.20260517.tar.xz | docker load export POSTGRES_PASSWORD="my-strong-password" docker compose -f dist/docker/docker-compose.light.yml up -d ``` ## Локальная разработка ### Backend ```bash cd backend python3 -m venv .venv source .venv/bin/activate pip install -r requirements-backend.txt python3 -m uvicorn src.app:app --reload --port 8000 ``` ### Frontend ```bash cd frontend npm install npm run dev -- --port 5173 ``` ### Начальная настройка ```bash # Переменные окружения cp .env.example backend/.env # Инициализация БД cd backend && source .venv/bin/activate python src/scripts/init_auth_db.py # Создание администратора python src/scripts/create_admin.py --username admin --password '' ``` ## Конфигурация Полный список переменных — в каждом `.env.*.example` файле. ### Основные категории | Категория | Переменные | Описание | |---|---|---| | **Security** | `AUTH_SECRET_KEY`, `ENCRYPTION_KEY`, `SERVICE_JWT` | JWT-подпись, шифрование данных, сервисный токен для сервисных принципалов | | **Database** | `DATABASE_URL` | Единственное PostgreSQL подключение | | **Admin bootstrap** | `INITIAL_ADMIN_CREATE`, `INITIAL_ADMIN_USERNAME`, `INITIAL_ADMIN_PASSWORD`, `INITIAL_ADMIN_EMAIL` | Автосоздание admin при первом запуске | | **LLM** | `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `LLM_BASE_URL`, `LLM_MODEL` | Провайдеры и модели | | **Features** | `FEATURES__DATASET_REVIEW`, `FEATURES__HEALTH_MONITOR` | Включение фич | | **SSO** | `ADFS_CLIENT_ID`, `ADFS_CLIENT_SECRET`, `ADFS_METADATA_URL` | Active Directory Federation Services | | **Certificates** | `CERTS_PATH`, `SSL_KEY_PASSPHRASE`, `LLM_CA_CERT_URLS` | PKI для корпоративных сетей | | **CORS** | `ALLOWED_ORIGINS`, `FORCE_HTTPS`, `APP_TIMEZONE` | Безопасность и регион | | **Logging** | `ENABLE_BELIEF_STATE_LOGGING`, `TASK_LOG_LEVEL` | Структурированное логирование | | **Ports** | `BACKEND_HOST_PORT`, `FRONTEND_HOST_PORT`, `POSTGRES_HOST_PORT` | Проброс портов Docker | ## MCP клиент (внешние ассистенты) Единая точка подключения внешних MCP-клиентов — Streamable HTTP `/mcp` внутри backend (spec 050). Каталог из 47 инструментов фильтруется по live-RBAC; мутирующие операции проходят через durable approval-гейты. ```bash # 1. Discovery (RFC 9728) — метаданные защищённого ресурса и authorization server curl http://:8001/.well-known/oauth-protected-resource/mcp curl http://:8001/.well-known/oauth-authorization-server # 2. Dynamic Client Registration (нужен Bearer веб-сессии пользователя-владельца) # public-клиент (browser PKCE) или confidential (machine, выдаётся client_secret одноразово) curl -X POST http://:8001/oauth/register \ -H "Authorization: Bearer " -H "Content-Type: application/json" \ -d '{"client_name":"my-mcp","redirect_uris":["http://localhost:9999/cb"],"scope":"mcp:read","client_type":"confidential"}' # 3a. Machine-клиент: client_credentials → сервисный токен (только read-поверхность каталога) curl -X POST http://:8001/oauth/token \ -d "grant_type=client_credentials&client_id=&client_secret=" # 3b. Пользовательский клиент: authorization code + PKCE (S256) # GET /oauth/authorize?... с Bearer веб-сессии (SPA-mediated consent) → 302 code # POST /oauth/token grant_type=authorization_code + code_verifier # 4. MCP сессия: POST /mcp с Authorization: Bearer # initialize → notifications/initialized → tools/list → tools/call ``` Альтернатива для доверенных машинных интеграций внутри периметра — `SERVICE_JWT` (задаётся в `.env`; композ намеренно падает без него). Gated-инструменты (`deploy_dashboard`, `execute_migration`, `run_backup`, superset-writes, `consume_baseline_approval`) возвращают `approval_required` и исполняются только после `decide_approval` тем же принципалом через серверный поллер. PRODUCTION SQL (`superset_execute_sql` на PROD-окружении) отклоняется терминально. ## Локальный периметр (LLM/VLM/MCP endpoints) Spec 050 (MCPX-FR-020, T008b): MCP-клиенты и все LLM/VLM-провайдеры по умолчанию расположены внутри enterprise-периметра. PII (дашборды, сэмплы датасетов, маскированные скриншоты) допускается только к локальным провайдерам; credentials/cookies/токены/секреты и raw-пути хранения отвергаются везде (typed secret-exposure rejection, E13). **Deny-by-default на конфигурации провайдера** (Admin → LLM Settings): `base_url`, не являющийся локальным, отклоняется типизированной ошибкой `400 endpoint_not_local:` ДО сохранения. Локальными считаются: - host-литералы `localhost`, `127.*`, `[::1]`, `0.0.0.0`, `host.docker.internal`; - IP из private/loopback/link-local диапазонов (RFC1918 `10/8`, `172.16/12`, `192.168/16`, ULA/loopback IPv6); - DNS-имена с enterprise-суффиксами `.local`, `.internal`, `.lan`, `.corp`, `.intranet` (split-horizon DNS не требует резолва); - DNS-имена, у которых ВСЕ резолвимые адреса приватные; - пустой `base_url` отклоняется (SDK-дефолт указывает на публичное облако). Нерезолвимое имя = отказ (fail closed). Substring-эвристики не используются: `https://api.openai.com/localhost` отклоняется по hostname. Escape hatches (явные, задокументированные, по умолчанию закрыты): ```bash # Полный opt-out периметровой проверки (только для непод perimeter-развёртываний!): LLM_ALLOW_NONLOCAL_ENDPOINTS=true # Точечный allowlist публичных хостов (через запятую): LLM_NONLOCAL_ENDPOINT_ALLOWED_HOSTS=llm.partner.example # Дополнительные enterprise-суффиксы: LLM_LOCAL_HOST_SUFFIXES=.enterprise ``` MCP-транспорт держит свой локальный контур independently: DNS-rebinding protection с локальными дефолтами `MCP_ALLOWED_HOSTS`/`MCP_ALLOWED_ORIGINS`, server-owned лимиты тела запроса (4 MiB), JSON-глубины (`json_depth_limit=32`, typed `400 json_depth_exceeded` до dispatch) и per-session rate limit (`120 req/60s`, typed `429 rate_limited` + стандартный `Retry-After`). Исполнимые пины: `tests/test_endpoint_locality.py`, `tests/test_mcp_transport_limits.py`. ## Система сборки `build.sh` — унифицированная CLI-утилита: ```bash # Сборка и запуск ./build.sh compose # docker compose up --build (current profile) ./build.sh compose:master # docker compose up (master profile) # Индивидуальные сборки ./build.sh backend # backend image only ./build.sh frontend # frontend image only # Offline-бандлы ./build.sh bundle v1.0.0 # полный бандл (все сервисы) ./build.sh bundle:light v1.0.0 # light (backend + frontend) ``` Артефакты: `dist/docker/superset-tools..tar.xz` + sha256sum + manifest. ## Тестирование ### Makefile (tiered test system) ```bash make test # Tier 1: быстрые unit-тесты backend + frontend (<30с) make test-unit # Backend unit-тесты с SQLite (без Docker) make test-frontend # Frontend vitest-тесты make test-related F=path # Tier 2: умный выбор тестов для изменённого файла make test-integration # Tier 3: backend integration с testcontainers make test-e2e # Tier 3: Playwright E2E (требуется запущенное приложение) make test-all # Все тесты (без установки зависимостей) make lint # Все линтеры make lint-backend # ruff check make lint-frontend # eslint make coverage # coverage обоих стеков ``` ### Самостоятельный запуск ```bash # Backend тесты cd backend && source .venv/bin/activate && pytest # Frontend тесты cd frontend && npm run test # Конкретный тест pytest backend/tests/test_auth.py::test_create_user ``` ### E2E тестирование ```bash docker compose -f docker-compose.e2e.yml up --build cd frontend && npm run test:e2e ``` ## Покрытие кода Сводный отчёт — `scripts/coverage-summary.sh`: ```bash ./scripts/coverage-summary.sh # Полный запуск (integration + frontend) ./scripts/coverage-summary.sh --unit # Backend unit (SQLite) + frontend ./scripts/coverage-summary.sh --frontend-only # Только frontend ./scripts/coverage-summary.sh --backend-only --unit # Только backend ./scripts/coverage-summary.sh --output-dir ./reports/coverage ``` Результат: `coverage-summary/index.html`. ### Текущие показатели | Стек | Тип тестов | Процент | Покрытие (Stmts) | |---|---|---|---| | Backend (unit) | 1723 | 1721/2 ✅ | 48% | | Backend (integration) | 167 | 167/0 ✅ | 12% | | Frontend | 2443 | 2442/1 ✅ | 99.25% | ## SSL/TLS конфигурация ### Сертификаты для HTTPS (nginx) Поместите файлы в `./certs/`: **Вариант A — отдельные файлы:** ``` ./certs/server.crt # SSL сертификат ./certs/server.key # Приватный ключ ``` **Вариант B — зашифрованный ключ + пароль:** ``` ./certs/server.crt # SSL сертификат ./certs/server.key # Приватный ключ (зашифрован, с DEK-Info) SSL_KEY_PASSPHRASE=my-passphrase ``` **Вариант C — PKCS#12 контейнер:** ``` ./certs/server.p12 # Контейнер с сертификатом + ключом SSL_KEY_PASSPHRASE=my-passphrase ``` Entrypoint автоматически извлекает `.crt` и `.key` из `.p12`, расшифровывает ключ и передаёт nginx (ключ остаётся в tmpfs контейнера). ### Корпоративные CA-сертификаты Положите `.crt`/`.pem` в `./certs/` — entrypoint установит их в системное хранилище Alpine и NSS (Chromium/Playwright). Поддерживаются цепочки (Root → Intermediate). ### LLM CA-сертификаты ```bash LLM_CA_CERT_URLS="http://pki.company.com/root-ca.crt http://pki.company.com/intermediate-ca.crt" ``` Сертификаты скачиваются на старте контейнеров, конвертируются из DER в PEM при необходимости, устанавливаются в системное хранилище. ### Диагностика SSL ```bash scripts/check_llm_certs.py # Полная проверка цепочки доверия scripts/diag_container.py --target your-llm-provider.com:443 # Контейнерная диагностика ``` Подробнее — [ADR-0009](docs/adr/ADR-0009-ssl-certificate-management.md). `LLM_SSL_VERIFY` удалён в 0.2.x — TLS verify всегда включён. ## Enterprise Clean Deployment Разворот в корпоративной сети с очищенным дистрибутивом (без тестовых данных, запрет внешних источников, compliance-проверка): ```bash cp .env.example .env docker compose --profile enterprise-clean up --build ``` Поддерживаются CLI, API и TUI flows. Подробнее — [docs/enterprise-clean.md](docs/enterprise-clean.md). ## Авторизация Два метода аутентификации: 1. **Локальная** (username/password) — JWT-токены, RBAC (admin/analyst/viewer) 2. **ADFS SSO** — Active Directory Federation Services Управление: `POST /api/admin/users`, `POST /api/admin/roles`. ## Мониторинг - **Dashboard Hub** — управление дашбордами с Git-статусом - **Dataset Hub** — управление датасетами с прогрессом маппинга - **Task Drawer** — мониторинг фоновых задач (WebSocket real-time) - **Unified Reports** — `GET /api/reports?page=1&page_size=20` (фильтры по статусу, типу, дате) - **Health Monitor** — мониторинг здоровья системы (через `FEATURES__HEALTH_MONITOR`) - **Semantic Map** — автоматически генерируемая семантическая карта кода (`semantics/semantic_map.json`) ## Спецификации В `specs/` ведётся 40+ feature specifications. Каждая включает: `spec.md`, `research.md`, `plan.md`, `contracts/modules.md`, `data-model.md`, `checklists/requirements.md`, `tasks.md`. | # | Название | Описание | |---|---|---| | 011 | `git-integration-dashboard` | Git-интеграция дашбордов | | 017 | `llm-analysis-plugin` | LLM-аналитика и валидация | | 022 | `sync-id-cross-filters` | Sync ID cross-filters | | 023 | `clean-repo-enterprise` | Чистый репозиторий для enterprise | | 033 | `gradio-agent-chat` | Gradio/LangGraph AI-агент | | 034 | `task-status-center` | Центр статуса задач | | 038 | `dashboard-scenario-model` | Сценарная модель дашбордов | | 041 | `dataset-lineage-blast-radius` | Lineage и blast radius датасетов | ## Примеры скриптов Примеры интеграции с внешними системами (Airflow, CI/CD, cron) — в [`examples/`](./examples/): - [Python](examples/maintenance-api-python.py) - [Bash](examples/maintenance-api-bash.sh) Аутентификация через API Key (`X-API-Key`), запуск и завершение maintenance-событий. ## Утилиты | Скрипт | Назначение | |---|---| | `coverage-summary.sh` | Сводный отчёт покрытия | | `scan_secrets.sh` | Сканирование секретов | | `check_llm_certs.py` | Проверка SSL-сертификатов LLM | | `diag_container.py` | SSL-диагностика | | `find-related-tests.py` | Поиск тестов по изменённому файлу | | `pretty_cot.py` | Форматирование CoT-логов | | `gen_semantics.py` | Семантическая карта кода | | `build_offline_docker_bundle.sh` | Сборка offline-бандлов | ## Исследования - **mcp-superset** — MCP-сервер для Apache Superset (137 инструментов, PyPI). Streamable HTTP, SSE, stdio транспорты. Подробнее — [`research/mcp-superset/`](research/mcp-superset/).