Конфигурация
Simmetric Chat имеет два уровня конфигурации: переменные окружения, проверяемые с помощью Zod при запуске процесса, и уровень конфигурации времени выполнения, хранящийся в базе данных, который администраторы могут редактировать через интерфейс без переза…
Simmetric Chat имеет два уровня конфигурации: переменные окружения, проверяемые с помощью Zod при запуске процесса, и уровень конфигурации времени выполнения, хранящийся в базе данных, который администраторы могут редактировать через интерфейс без перезапуска какого- либо сервиса.
- Переменные окружения (запуск процесса) - проверяются с помощью Zod в
packages/<pkg>/src/config/env.ts;process.exit(1)при невалидности. - Конфигурация времени выполнения (DB `SystemConfig`) - редактируется через UI администратора без перезапуска.
Разрешение:
- Ключи
ALWAYS_READONLY(JWT_SECRET,DATABASE_URL,SERVER_PORT,COLLECTOR_PORT,SERVER_URL,COLLECTOR_URL,LICENSE_SECRET):ENV > Default, не редактируются через UI. - Все остальные:
DB > ENV > Default, редактируются черезPUT /api/system/settings.
Все три пакета читают .env через path.resolve(__dirname, "../../.env") (независимо от рабочей директории). Эталонный документ — .env.example в корне репозитория.
Переменные окружения - server
Схема: packages/server/src/config/env.ts. Показаны значения по умолчанию; ОБЯЗ = обязательно.
Core / инфраструктура
| Переменная | Default | Обязат. | Описание |
|---|---|---|---|
NODE_ENV | development | opt | development/production/test |
SERVER_PORT | 3000 | opt | Порт API сервера |
COLLECTOR_PORT | 3210 | opt | Порт collector (для URL по умолчанию) |
SERVER_URL | http://localhost:3000 | opt | Публичный URL сервера |
COLLECTOR_URL | http://localhost:3210 | opt | URL collector |
WIDGET_SERVICE_URL | http://localhost:3211 | opt | URL сервиса виджета (push cache-bust) |
WIDGET_API_KEY | — | opt | Общий секрет push виджета; при отсутствии cache-bust — no-op (TTL 5 мин) |
DATABASE_URL | postgresql://simmetricchat:[email protected]:5432/simmetricchat | opt | URL PostgreSQL |
JWT_SECRET | — | ОБЯЗ | Секрет JWT |
ENCRYPTION_KEY | — | opt | Base64 32 байт для AES-256-GCM (data-at-rest). Не задан → fallback scryptSync(JWT_SECRET, salt) |
SESSION_EXPIRY | 86400000 (24ч мс) | opt | Срок действия JWT |
ALLOWED_ORIGINS | http://localhost:5173,127.0.0.1:5173,localhost:3000 | opt | Глобальный allowlist CORS (CSV). /api/internal/widget исключён |
LOG_LEVEL | info | opt | debug/info/warn/error |
ALLOW_REGISTRATION | false | opt | Переключатель саморегистрации |
DISABLE_TELEMETRY | true | opt | Отключает телеметрию |
Bootstrap-админ (seed)
| Переменная | Default | Описание |
|---|---|---|
SEED_BOOTSTRAP_ADMIN | true | Авто-сид админа при первом запуске (custom transform: false/0/no/off/"" = отключено) |
SEED_ADMIN_USERNAME | admin | Имя пользователя bootstrap-админа |
SEED_ADMIN_PASSWORD | admin123 | Пароль (мин 8); аккаунт mustChangePassword=true |
SEED_ADMIN_EMAIL | [email protected] | Email bootstrap-админа |
LLM
| Переменная | Default | Описание |
|---|---|---|
LLM_PROVIDER | ollama | openai/anthropic/ollama/openrouter |
LLM_MODEL | gemma4:latest | Модель по умолчанию |
LLM_TEMPERATURE | 0.7 | 0–2 |
LLM_MAX_TOKENS | 4096 | Лимит токенов завершения |
LLM_TIMEOUT | 0 | Таймаут Axios в мс (0 = нет, для медленных локальных LLM) |
LLM_API_KEY / LLM_API_BASE_URL | — | Общие переопределения |
OPENAI_API_KEY / OPENAI_MODEL | — | OpenAI |
ANTHROPIC_API_KEY / ANTHROPIC_MODEL | — | Anthropic |
OLLAMA_BASE_URL | http://ollama:11434 | Эндпоинт Ollama |
OLLAMA_MODEL / OLLAMA_API_KEY | — | Ollama override |
OPENROUTER_API_KEY / OPENROUTER_BASE_URL / OPENROUTER_MODEL | https://openrouter.ai/api / — | OpenRouter |
Watchdog агента (предотвращение циклов/зависаний)
| Переменная | Default | Описание |
|---|---|---|
AGENT_WALLCLOCK_TIMEOUT_MS | 600000 (10 мин) | Абсолютный верхний предел для ReAct-запроса |
AGENT_MAX_TOTAL_TOKENS | 200000 | Итого prompt+completion на запрос |
AGENT_MAX_CONTEXT_BYTES | 500000 (500 КБ) | Лимит размера массива контекста |
AGENT_MAX_TOOL_OUTPUT_LENGTH | 5000 | Усечение вывода на навык |
AGENT_MAX_SKILL_EXECUTION_MS | 60000 | Таймаут на навык |
AGENT_LOOP_DETECTION_WINDOW | 3 | Прерывание после N одинаковых подряд tool+input |
CHAT_MAX_CONCURRENT_PER_USER | 5 | Лимит одновременных чатов на пользователя |
Embedding / Vector DB / OCR / Synthesis
| Переменная | Default | Описание |
|---|---|---|
EMBEDDING_PROVIDER | local | local/openai/ollama |
EMBEDDING_MODEL | Xenova/all-MiniLM-L6-v2 | Модель эмбеддингов |
EMBEDDING_API_KEY | — | API-ключ эмбеддингов |
VECTOR_DB_PROVIDER | lancedb | lancedb/qdrant |
VECTOR_DB_URL / VECTOR_DB_API_KEY | — | Для удалённого Qdrant |
OCR_MODEL | glm-ocr:latest | Модель зрения OCR (формат model:version) |
OCR_TIMEOUT | 600000 | Таймаут зрения OCR |
SYNTHESIS_LLM_MODEL | gemma4:latest | Модель конвейера синтеза |
PUPPETEER_EXECUTABLE_PATH | — | Chromium для экспорта PDF архивов |
Лицензия, push, email, collector
| Переменная | Default | Описание |
|---|---|---|
LICENSE_KEY | — | JWT лицензии Enterprise (HS256). Отсутствует → Community |
LICENSE_SECRET | — | Секрет проверки JWT (рекомендуется); fallback на LICENSE_KEY |
COLLECTOR_SECRET | — | ОБЯЗ — общий секрет server↔collector |
VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECT | — | Web Push; не заданы → эфемерные ключи в dev |
SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASS / SMTP_FROM | — | SMTP для сброса пароля + уведомлений о сбое бэкапа |
LEGACY_PREVIOUS_ENCRYPTION_KEYS | — | CSV base64 32-байтные ключи для ротации |
Переменные в.env.example, но управляемые как DB settings (не вenvSchema):OCR_ENABLED,OCR_PRECHECK_CHARS,STORAGE_PATH(collector),RESET_PASSWORD_STRATEGY.
Переменные окружения - collector
Схема: packages/collector/src/config/env.ts.
| Переменная | Default | Обязат. | Описание |
|---|---|---|---|
COLLECTOR_PORT | 3210 | opt | HTTP-порт |
COLLECTOR_URL | http://localhost:3210 | opt | Собственный URL |
SERVER_URL | http://localhost:3000 | opt | URL сервера (callback) |
EMBEDDING_PROVIDER | local | opt | local/openai/ollama |
EMBEDDING_MODEL | — | opt | Модель эмбеддингов |
EMBEDDING_API_KEY | — | opt | API-ключ |
VECTOR_DB_PROVIDER | lancedb | opt | lancedb/qdrant |
VECTOR_DB_URL / VECTOR_DB_API_KEY | — | opt | Qdrant |
OLLAMA_BASE_URL | http://ollama:11434 | opt | Ollama |
STORAGE_PATH | ./storage | opt | Файловое хранилище |
COLLECTOR_SECRET | — | ОБЯЗ | Должен совпадать с сервером |
Переменные окружения - widget
Схема: packages/widget/src/config/env.ts.
| Переменная | Default | Обязат. | Описание |
|---|---|---|---|
NODE_ENV | development | opt | Окружение |
WIDGET_PORT | 3211 | opt | HTTP-порт |
SERVER_URL | http://localhost:3000 | opt | URL сервера |
WIDGET_API_KEY | — | ОБЯЗ | Общий секрет widget↔server (должен совпадать) |
LOG_LEVEL | info | opt | Уровень логов |
Frontend: нет переменныхVITE_*и файла.env. Фронтенд читает брендинг/конфиг с сервера (GET /api/system/settings,GET /api/license/info).
Feature flags и лицензия
Определены в packages/shared/src/constants/license.ts (FEATURE_FLAGS + defaults). Проверка в packages/server/src/services/licenseService.ts.
Как перейти с Community на Enterprise
- Задайте
LICENSE_KEY(JWT HS256) и, рекомендуется,LICENSE_SECRET. jwt.verify→ payload валидируется противlicensePayloadSchema(tier,iss,sub,iat,exp,features).tier=enterprise→ стартует сENTERPRISE_FEATURE_DEFAULTS+ overridefeaturesиз JWT.- Истёкшая/невалидная → fallback Community с предупреждением.
Graceful degradation: getLicenseInfo() проверяет срок действия в рантайме; если Enterprise истекает во время работы, она деградирует до Community без перезапуска. requireFeature(flag) → HTTP 402, если отключено; requireFeatureLimit(flag, model) → 402, когда count >= limit (Enterprise = Infinity).
Всегда включённые commodity-флаги: после удаления EPA-02 8 commodity-флагов больше не существуют в FEATURE_FLAGS - webhooks, push_notifications, web search, memory, lead_export, widget_analytics, auto_title, synthesis_rate_limit всегда включены в Community (commodity-маршруты работают без гейтинга). priority_support — не флаг: это коммерческий/SLA-контракт (EPA-08). Осталось 11 enterprise-флагов, включая widget_credits_editing (редактирование кредитов виджета, Community false / Enterprise true) и custom_agents как числовой лимит (Community 3, Enterprise Infinity).
Таблица флагов (11)
| Флаг | Тип | Community | Enterprise | Что гейтит |
|---|---|---|---|---|
sso_enabled | bool | false | true | SSO Enterprise |
audit_log_immutable | bool | false | true | Неизменяемость audit-лога |
white_label | bool | false | true | Брендинг BRANDING_* |
max_workspaces | num | 3 | Infinity | Создание рабочих пространств |
max_projects | num | 3 | Infinity | Создание проектов |
custom_agents | num | 3 | Infinity | Кастомные агенты (лимит) |
widget_enabled | bool | false | true | Встраиваемый виджет |
max_widgets | num | 1 | Infinity | Создание виджетов |
backup_enabled | bool | false | true | Система бэкапов |
max_backup_destinations | num | 1 | Infinity | Назначения бэкапов |
widget_credits_editing | bool | false | true | Редактирование кредитов виджета |
Конфигурация времени выполнения (DB SystemConfig)
Редактируется через GET/PUT /api/system/settings (bulk) и PUT /api/system/chat-retention (специфичный, аудируемый). Defaults живут в CONFIG_DEFAULTS (packages/shared/src/constants/permissions.ts).
Группы ключей: LLM (LLM_PROVIDER, LLM_MODEL, LLM_TEMPERATURE, ...), Embedding/Vector, Порты/URL сервера, Auth (SESSION_EXPIRY), Брендинг (BRANDING_APP_NAME, BRANDING_PRIMARY_COLOR, BRANDING_APP_SUBTITLE, BRANDING_APP_ICON_URL - gated white_label), Feature (DISABLE_TELEMETRY, ALLOW_REGISTRATION, DLP_ENABLED), OCR (OCR_DEFAULT_MODEL, OCR_DEFAULT_MODE, OCR_DEFAULT_CUSTOM_INSTRUCTIONS, OCR_ENABLED, OCR_PRECHECK_CHARS), Synthesis (SYNTHESIS_LLM_PROVIDER_ID, SYNTHESIS_LLM_MODEL), Retention (upload_draft_retention_days, ALLOW_NON_ADMIN_UPLOAD, chat_message_retention_days).
PUT /api/system/settings всегда возвращает 200 с { updated: [...], rejected: [...] } (readonly-ключи отклоняются, остальные применяются).
Хранение сообщений чата (reaper)
Сервис: packages/server/src/services/chatMessageReaperJob.ts. DB-ручка: chat_message_retention_days.
- Pass 1 (soft-delete): tombstone сообщений АКТИВНЫХ чатов за пределами
retentionDays. No-op, если значениеnull/""/<=0. - Pass 2 (hard-purge): удаляет tombstone-строки за пределами 7-дневной отсрочки (hardcoded). Запускается всегда, независимо от конфигурации хранения (анти-утечка PII).
- Каденция:
setInterval24ч, первый запуск в 03:00 по местному времени. МьютексisRunning. - Только
PUT /api/system/chat-retention(аудируемый,confirmDataLoss: true,retentionDays: integer|null, мин 1); bulk-settings эндпоинт отклоняет этот ключ.
Хранение бэкапов
По заданию (поле retentionDays на BackupJob, default 30). backupRetentionService.ts очищает логи/файлы за пределами cutoffDate. Не глобально.
Ротация ключей шифрования
packages/server/src/services/encryptionService.ts (AES-256-GCM, ключ 32 байта, IV 16 байт, соль simmetric-chat-encryption-salt).
- Текущий ключ:
ENCRYPTION_KEY(base64 32 байта), если задан; иначеscryptSync(JWT_SECRET, salt, 32). LEGACY_PREVIOUS_ENCRYPTION_KEYS(CSV base64 32 байта) → цепочка ключей дешифрования[current, ...previous, scryptLegacy?].encrypt()используетchain[0]. Автоматического re-encryption-задания нет: процедура ручная — расшифровать-старым → зашифровать-новым.
Cross-link
- Эндпоинты настроек: 04 - API Reference
- Внутренние функции: 05 - Feature Guide
- Env vars развёртывания: 09 - Deployment