Справочник по конфигурации¶
Provisa настраивается через YAML-файл (по умолчанию: config/provisa.yaml). (REQ-528)
Включения (Includes) (REQ-1669)¶
Разделите конфигурацию на несколько файлов с помощью includes:. Включающий файл перечисляет пути к фрагментам под этим ключом; Provisa объединяет их перед валидацией, получая тот же результат, как если бы всё было написано в одном файле.
# provisa-with-sources.yaml — wrapper that adds a Neo4j source to the base config
includes:
- /path/to/config/provisa-install.yaml
- /path/to/demo/sources/neo4j/fragment.yaml
Файл-обёртка, содержащий только includes:, допустим. load_control_plane читает через включения, поэтому раздел control_plane: берётся из того включённого файла, который его задаёт. [tool-verified: provisa/core/config_loader.py:154-166]
Правила слияния [tool-verified: provisa/core/config_loader.py:104-146]
- Пути разрешаются относительно включающего файла. Абсолютные пути используются как есть.
- Секции-списки (
sources,tables,domains,relationships,roles, …) дополняются — записи фрагмента следуют за записями включающего файла. - Скалярный ключ или ключ-словарь, который включающий файл не задаёт, берётся из фрагмента.
- Ключ, заданный обоими файлами с разными значениями, — конфликт; загрузка завершается ошибкой с указанием ключа.
- Одинаковые значения в обоих файлах конфликтом не считаются.
- Включения вкладываются друг в друга. Файл, включающий сам себя — напрямую или через другой фрагмент, — отклоняется.
includesучитывается только при загрузке и никогда не появляется в проверенной конфигурации.
Источники¶
sources:
- id: sales-pg # unique identifier
type: postgresql
host: postgres
port: 5432
database: provisa
username: provisa
password: ${env:PG_PASSWORD} # secret resolution
pool_min: 1
pool_max: 5
use_pgbouncer: false
pgbouncer_port: 6432
У всех источников общий набор полей. [tool-verified: provisa/core/models.py:129-212]
| Поле | По умолчанию | Примечания |
|---|---|---|
id |
обязательно | Латинские буквы и цифры, дефисы, подчёркивания |
type |
обязательно | См. таблицу ниже |
host |
"" |
Имя хоста или IP-адрес |
port |
0 |
0 означает, что каждый коннектор подставляет собственное значение по умолчанию — центральной карты портов по умолчанию нет |
database |
"" |
|
username |
"" |
|
password |
"" |
Поддерживает ссылки на учётные данные ${env:VAR} и ${secret:NAME} — см. Секреты |
path |
null |
Путь к файлу или URI для файловых источников |
base_url |
null |
Базовый URL для API-источников |
pool_min / pool_max |
1 / 5 |
Границы пула соединений |
cache_enabled |
true |
Включает кэширование для всех таблиц этого источника |
cache_ttl |
null |
Секунды; null наследует глобальное значение по умолчанию |
federation_hints |
{} |
Расширенные параметры конкретного коннектора (dict[str,str]); см. справочник по типам ниже. REQ-281 |
mapping |
{} |
DSL сопоставления для redis, elasticsearch, prometheus. REQ-251 |
allowed_domains |
[] |
Ограничивает источник конкретными идентификаторами доменов; пусто = без ограничений |
description |
"" |
Поддерживаемые типы источников [tool-verified: provisa/core/models.py:36-101]¶
| Тип | Способ подключения | Примечания |
|---|---|---|
| RDBMS | ||
postgresql |
host/port | Пул asyncpg; PgBouncer включается через use_pgbouncer |
mysql |
host/port | |
mariadb |
host/port | |
singlestore |
host/port | |
sqlserver |
host/port | |
oracle |
host/port | |
firebird |
host + path (файл БД) |
Расширение DuckDB firebird community (REQ-899) |
duckdb |
host/port | |
cockroachdb |
host/port | Использует драйвер/диалект PostgreSQL (REQ-950) |
yugabytedb |
host/port | Использует драйвер/диалект PostgreSQL (REQ-950) |
greenplum |
host/port | Использует драйвер/диалект PostgreSQL (REQ-950) |
tidb |
host/port | Использует драйвер/диалект MySQL (REQ-950) |
| Облачное хранилище данных | ||
snowflake |
host/port + federation_hints |
В hints обязателен account |
bigquery |
federation_hints |
Обязателен project; аутентификация через GOOGLE_APPLICATION_CREDENTIALS |
databricks |
host + federation_hints |
В hints обязателен http_path |
fabric |
переменные окружения или PROVISA_ENGINE_URL |
T-SQL поверх TDS, аутентификация Azure AD |
synapse |
переменные окружения или PROVISA_ENGINE_URL |
T-SQL поверх TDS, аутентификация Azure AD |
redshift |
host/port | |
| OLAP | ||
clickhouse |
host/port + federation_hints |
Hint secure переключает TLS; порт по умолчанию 8123/8443 |
elasticsearch |
host/port + DSL mapping |
|
pinot |
host/port | REST-эндпоинт контроллера |
druid |
host/port | Avatica-эндпоинт брокера |
exasol |
host/port | |
| Data Lake | ||
delta_lake |
path (URI таблицы) |
delta_scan DuckDB; доступ к объектному хранилищу через federation_hints |
iceberg |
path (URI таблицы) |
iceberg_scan DuckDB; доступ к объектному хранилищу через federation_hints |
hudi |
path (URI таблицы) |
Движок Hudi в ClickHouse, без копирования (REQ-1178) |
hive |
host/port (metastore) + mapping.storage |
Бэкенд хранилища в mapping["storage"]: hadoop/hdfs/local/s3/azure/adls |
hive_s3 |
host/port (metastore) + ключи S3 в mapping |
Отдельный тип; всегда хранилище S3 (REQ-229) |
| NoSQL | ||
mongodb |
host/port | Обычные поля подключения; без DSL сопоставления |
cassandra |
host/port | Обычные поля подключения; без DSL сопоставления |
redis |
host/port + DSL mapping |
|
| Потоковая передача | ||
kafka |
только регистрация | Реальная конфигурация в kafka_sources[]; см. §Kafka ниже |
websocket |
host/port/path + federation_hints |
Внешний WebSocket-фид |
rss |
host/port/path + federation_hints |
Фид RSS 2.0 / Atom |
| Граф/Семантика | ||
neo4j |
[UNVERIFIED end-to-end mapping] | |
sparql |
[UNVERIFIED end-to-end mapping] | |
| Файлы | ||
sqlite |
path |
Всегда маршрутизируется через движок (без прямого пула) |
csv |
path |
|
parquet |
path |
|
files |
path (каталог) |
Обход по маске; представляет CSV/Parquet/XLSX/JSON как таблицы |
| API/Удалённые источники | ||
google_sheets |
federation_hints.spreadsheet_id |
|
prometheus |
host/port или mapping.url + DSL mapping |
|
graphql_remote |
base_url + опционально mapping |
Заголовки, forward-client-headers, таймаут в mapping |
openapi |
base_url |
|
grpc_remote |
[UNVERIFIED end-to-end mapping] | |
airport |
base_url (расположение Flight) |
Расширение DuckDB airport (REQ-899) |
ingest |
приёмник push-событий | Внешние сервисы отправляют JSON-события через POST |
| SaaS | ||
sharepoint |
base_url или host + mapping |
Аутентификация через mapping.auth_type |
splunk |
host/port или base_url + mapping |
|
| GovData | ||
govdata |
subject + domain_id |
Отдельная модель GovDataSource; см. §GovData ниже |
| Качество данных | ||
soda |
host/port, направленные на pgwire Provisa | Требует extra soda; Elastic License 2.0, только self-hosted (REQ-1443) |
great_expectations |
host/port, направленные на pgwire Provisa | Требует extra gx; Apache 2.0 (REQ-1443) |
Справочник по типам источников¶
Для типов, требующих неочевидной настройки, ниже приведена короткая справка. Типы RDBMS (postgresql, mysql и т. д.) используют только общие поля выше — дополнительный раздел не нужен.
GovData [tool-verified: provisa/core/models.py:953-983]¶
Источники govdata используют отдельную модель верхнего уровня, GovDataSource, а не обычный Source. (REQ-540) Доступ разделён по группам subject.
sources:
- id: federal-data
type: govdata
subject: COMMERCE
domain_id: federal-analytics
api_key: ${env:GOVDATA_API_KEY} # optional
start_year: 2020 # optional year filter
end_year: 2024 # optional year filter
Каждый subject соответствует одной или нескольким схемам GovData. Настройка источника govdata с указанием subject автоматически открывает все схемы этого subject. (REQ-540)
| Subject | Схемы |
|---|---|
COMMERCE |
sec, patents |
ECONOMY |
econ, econ_reference |
EDUCATION |
census, edu |
HEALTH |
health |
CYBER |
cyber_threat, cyber_vuln |
PUBLIC_SAFETY |
crime |
ENVIRONMENT |
lands |
WEATHER |
weather |
ENERGY |
energy |
GOVERNMENT |
fedregister, fec |
Схемы ref и geo всегда включены как связующие схемы — они не настраиваются и не перечислены выше. (REQ-541) Используйте subject ALL, чтобы предоставить доступ ко всем схемам. [tool-verified: provisa/core/models.py:961-963]
Kafka [tool-verified: provisa/federation/trino_connectors.py:497-502, provisa/api/app_loaders.py:113-118]¶
Строка kafka в sources: предназначена только для регистрации. Метод details() её коннектора возвращает {} — реальная конфигурация находится в блоке kafka_sources[] верхнего уровня, а не в записи sources:. Kafka всегда является VIRTUAL_SOURCE (маршрутизируется через движок; без прямого пула). [tool-verified: provisa/transpiler/router.py:44-63]
kafka_sources:
- id: event-stream
bootstrap_servers: kafka:9092
schema_registry_url: http://schema-registry:8081 # optional
topics:
- id: order-created
topic: orders.events
default_window: 1h # auto-injected time bound
schema_source: manual # manual, registry, or sample
value_format: json
discriminator: # filter shared topic by message type
field: event_type
value: OrderCreated
columns:
- name: event_type
type: varchar
- name: order_id
type: integer
- name: amount
type: double
- name: metadata
type: varchar # raw JSON for complex nested data
- id: order-shipped
topic: orders.events # same physical topic
default_window: 1h
discriminator:
field: event_type
value: OrderShipped
columns:
- name: event_type
type: varchar
- name: order_id
type: integer
- name: shipped_at
type: timestamp
Временное окно — default_window ограничивает каждый запрос недавним периодом времени, предотвращая неограниченное чтение из высоконагруженных топиков. (REQ-148) Формат: 1h, 30m, 7d, 60s. По умолчанию 1h. Автоматически подставляется как WHERE _timestamp >= CURRENT_TIMESTAMP - INTERVAL '1' HOUR. Клиенты могут переопределить это собственным фильтром _timestamp в аргументе where GraphQL.
Дискриминатор — Несколько конфигураций топиков могут указывать на один и тот же физический топик Kafka с разными значениями discriminator, порождая отдельные типы GraphQL. (REQ-149) Дискриминатор автоматически подставляется как условие WHERE.
Источник схемы
| Значение | Поведение |
|---|---|
registry |
Получить схему из Confluent Schema Registry |
manual |
Определить столбцы прямо в конфигурации (Schema Registry не нужен) |
sample |
Автоматически определить схему по примерам сообщений |
Snowflake [tool-verified: provisa/executor/drivers/snowflake.py:48-62]¶
account в federation_hints обязателен. warehouse, role и schema опциональны.
sources:
- id: my-snowflake
type: snowflake
host: org.snowflakecomputing.com
username: svc_provisa
password: ${env:SNOWFLAKE_PASSWORD}
database: MY_DB
federation_hints:
account: myorg-myaccount # required
warehouse: COMPUTE_WH
role: PROVISA_ROLE
schema: PUBLIC # remote schema override
Databricks [tool-verified: provisa/executor/drivers/databricks.py:34-52]¶
http_path в federation_hints обязателен. password содержит personal access token. catalog опционален (передаётся в SQL/hints, а не в поле database).
sources:
- id: my-databricks
type: databricks
host: my-workspace.azuredatabricks.net
password: ${env:DATABRICKS_TOKEN}
federation_hints:
http_path: /sql/1.0/warehouses/xxxx # required
catalog: my_unity_catalog # optional
BigQuery [tool-verified: provisa/federation/connector_duckdb.py:238]¶
project в federation_hints обязателен. Аутентификация использует GOOGLE_APPLICATION_CREDENTIALS (путь к файлу ключа сервисного аккаунта) или Application Default Credentials в окружении движка.
Fabric / Synapse [tool-verified: provisa/core/models.py:56-57]¶
Оба используют T-SQL поверх TDS с аутентификацией Azure AD. Аутентифицируйтесь через az login (для разработки) или управляемое удостоверение (для продакшена) — движок читает учётные данные через DefaultAzureCredential из azure-identity. Данные подключения берутся из переменных окружения: FABRIC_SQL_SERVER / FABRIC_DATABASE (Fabric) или SYNAPSE_SQL_SERVER / SYNAPSE_DATABASE (Synapse), либо через PROVISA_ENGINE_URL.
sources:
- id: my-fabric
type: fabric
# host/database read from FABRIC_SQL_SERVER / FABRIC_DATABASE when not set here
ClickHouse [tool-verified: provisa/executor/drivers/clickhouse.py:49-59]¶
secure в federation_hints включает TLS на HTTP-интерфейсе. Порт по умолчанию 8123 (без шифрования) или 8443 (при secure: "true"). schema в federation_hints переопределяет удалённую схему. [tool-verified: provisa/federation/connector_duckdb.py:378-379]
sources:
- id: my-clickhouse
type: clickhouse
host: ch.example.com
password: ${env:CLICKHOUSE_PASSWORD}
federation_hints:
secure: "true" # uses port 8443; omit to use 8123
schema: analytics
Delta Lake / Iceberg [tool-verified: provisa/federation/connector_duckdb.py:291-327]¶
path — это URI таблицы (S3, GCS, ADLS или локальный). Доступ к объектному хранилищу требует учётных данных в federation_hints. Для Cloudflare R2 добавьте account_id.
sources:
- id: events-delta
type: delta_lake
path: s3://my-bucket/data/events
federation_hints:
access_key_id: ${env:S3_ACCESS_KEY}
secret_access_key: ${env:S3_SECRET}
- id: r2-parquet
type: parquet
path: s3://my-bucket/data/events.parquet
federation_hints:
access_key_id: ${env:R2_ACCESS_KEY}
secret_access_key: ${env:R2_SECRET}
account_id: ${env:R2_ACCOUNT_ID} # Cloudflare R2 account (S3-compatible)
Hive / Hive S3 [tool-verified: provisa/federation/trino_connectors.py:244-363]¶
host и port указывают на Hive Thrift metastore (порт по умолчанию 9083). Для hive задайте mapping["storage"], чтобы выбрать бэкенд объектного хранилища. Отсутствующие обязательные ключи приводят к явной ошибке — без запасных значений. [tool-verified: provisa/federation/trino_connectors.py:328-331]
hive_s3 — отдельный тип, который всегда объявляет хранилище S3 (REQ-229); mapping.storage не нужен.
sources:
- id: hive-s3-lake
type: hive
host: metastore.internal
port: 9083
mapping:
storage: s3
endpoint: https://s3.us-east-1.amazonaws.com
access_key_id: ${env:AWS_ACCESS_KEY_ID}
secret_access_key: ${env:AWS_SECRET_ACCESS_KEY}
region: us-east-1
path_style: true # required for MinIO and non-AWS S3-compatible endpoints
- id: hive-adls-lake
type: hive
host: metastore.internal
port: 9083
mapping:
storage: adls
storage_account: mystorageaccount
access_key: ${env:ADLS_ACCESS_KEY}
# sas_token: ${env:ADLS_SAS_TOKEN} # alternative to access_key
Допустимые значения mapping.storage: hadoop (по умолчанию), hdfs, local, s3, azure, adls. Ключи mapping для S3: endpoint, access_key_id, secret_access_key, region, path_style. Ключи mapping для ADLS: storage_account, access_key или sas_token.
Redis [tool-verified: provisa/core/trino_catalog_files.py:54-75]¶
Использует DSL mapping. mongodb и cassandra используют обычные поля подключения и НЕ используют DSL сопоставления.
sources:
- id: my-redis
type: redis
host: redis.internal
port: 6379
password: ${env:REDIS_PASSWORD}
mapping:
tables:
- name: sessions
key_pattern: "sessions:*"
key_column: key # default "key"
value_type: hash # hash | string | zset | list; default hash
columns:
- name: user_id
data_type: VARCHAR
field: user_id # Redis hash field name
- name: expires_at
data_type: BIGINT
field: expires_at
Elasticsearch [tool-verified: provisa/core/trino_catalog_files.py:78-104]¶
sources:
- id: my-es
type: elasticsearch
host: es.internal
port: 9200
username: elastic
password: ${env:ES_PASSWORD}
mapping:
tls: true
tables:
- name: logs
index: app-logs-*
discover: false
columns:
- name: timestamp
data_type: TIMESTAMP
path: "@timestamp"
- name: level
data_type: VARCHAR
path: level
- name: message
data_type: VARCHAR
path: message
Prometheus [tool-verified: provisa/core/trino_catalog_files.py:107-124]¶
mapping.url переопределяет host:port, когда заданы оба.
sources:
- id: my-prometheus
type: prometheus
mapping:
url: http://prometheus.internal:9090
tables:
- name: http_requests
metric: http_requests_total
labels_as_columns: [method, status, handler]
value_column: value # default "value"
default_range: 1h # default "1h"
Google Sheets [tool-verified: provisa/federation/connector_duckdb.py:273-275]¶
spreadsheet_id в federation_hints обязателен. Аутентификация использует SECRET gsheet DuckDB, подготавливаемый в момент присоединения.
sources:
- id: my-sheet
type: google_sheets
federation_hints:
spreadsheet_id: 1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms
Файловые источники (csv / parquet / sqlite / files)¶
path обязателен. files обходит каталог в поисках файлов CSV, Parquet, XLSX и JSON, представляя каждый как таблицу. Все файловые источники VIRTUAL (маршрутизируются через движок; без прямого пула). [tool-verified: provisa/transpiler/router.py:44-48]
sources:
- id: orders-csv
type: csv
path: /data/orders.csv
- id: data-lake-dir
type: files
path: /data/lake/ # directory; each file becomes a table
Наборы данных Kaggle нельзя добавить через этот файл — они требуют действующего токена и выбора набора данных, доступного в форме источников (Sources → Subscriptions → Kaggle). Источник Kaggle, экспортированный в YAML, выглядит как type: files с kaggle_owner и kaggle_ref в federation_hints. Для повторной загрузки из Kaggle нужна мутация refreshKaggleSource или поток обновления в UI, а не правка YAML. См. Наборы данных Kaggle в справочнике по типам источников.
API / удалённые источники¶
openapi — задайте base_url как базовый URL OpenAPI. Обнаружение схемы читает спецификацию OpenAPI при запуске.
graphql_remote — задайте base_url. Опциональные ключи mapping: headers (словарь статических заголовков), forward_client_headers (bool), timeout_seconds (int). [tool-verified: provisa/hasura_v2/mapper.py:129-152]
sources:
- id: orders-gql
type: graphql_remote
base_url: https://orders.internal/graphql
mapping:
headers:
X-Api-Key: ${env:ORDERS_API_KEY}
forward_client_headers: true
timeout_seconds: 30
airport — base_url — это расположение сервера Arrow Flight. Расширение DuckDB airport (REQ-899). [tool-verified: provisa/federation/connector_duckdb.py:285-288]
websocket / rss — используют host, port, path и federation_hints. [tool-verified: provisa/api/data/subscribe.py:85-129]
sources:
- id: market-feed
type: websocket
host: feed.example.com
port: 443
path: /ws/v1
federation_hints:
use_ssl: "true"
subscribe_payload: '{"action":"subscribe","channels":["ticker"]}'
event_path: data
- id: news-rss
type: rss
host: feeds.example.com
port: 443
path: /rss/latest
federation_hints:
use_ssl: "true"
poll_interval: "300" # seconds
# feed_url: https://... # overrides host/port/path when set
sharepoint [tool-verified: provisa/federation/trino_connectors.py:394-423]
sources:
- id: my-sharepoint
type: sharepoint
base_url: https://myorg.sharepoint.com/sites/data
username: ${env:SP_CLIENT_ID}
password: ${env:SP_CLIENT_SECRET}
database: ${env:SP_TENANT_ID}
mapping:
auth_type: CLIENT_CREDENTIALS # default
# certificate_path: /path/to/cert.pem
# certificate_password: ${env:CERT_PASSWORD}
splunk [tool-verified: provisa/federation/trino_connectors.py:426-457]
sources:
- id: my-splunk
type: splunk
host: splunk.internal
port: 8089
password: ${env:SPLUNK_TOKEN}
database: search # Splunk app name (optional)
mapping:
use_token: true # default; false = username/password auth
datamodel_filter: "" # optional Splunk Data Model filter
disable_ssl_validation: false
Проверки качества данных (soda / great_expectations)¶
[tool-verified: provisa/dq/registration.py, provisa/events/source_loader.py make_dq_loader]
Источник-проверка указывает на собственный эндпоинт pgwire Provisa, поэтому один драйвер postgres сканирует федеративное представление таблицы, поддерживаемой Snowflake или Iceberg. Личность сканирования объявляется, а не наследуется — политика применяется именно к этому соединению, и отфильтрованный набор строк не должен приводить к незаметно проходящей проверке. Ключи подключения берутся из mapping: host, port, database, user, password.
sources:
- id: dq
type: soda # or great_expectations
domain_id: sales-analytics
mapping:
host: localhost
port: 5439 # Provisa's pgwire endpoint
database: provisa
user: dq_scanner
password: ${env:PROVISA_DQ_PASSWORD}
Каждая таблица результатов содержит dq_contract — YAML-контракт Soda или JSON-набор Great Expectations, дословно. Столбцы, watermark и продвижения выводятся из него; полное описание вывода см. в разделе Проверки качества данных.
Выбор на этапе установки. Проверка не подключается статически — сканирование выполняется в дочернем интерпретаторе, и библиотека устанавливается только тогда, когда оператор её называет. Каждый путь установщика (install.sh, packaging/linux/first-launch.sh и мастер для macOS через PROVISA_DQ_CHECKER) записывает выбор в ~/.provisa/config.yaml:
scripts/provisa читает этот ключ и экспортирует PROVISA_EXTRAS, который docker-compose.app.yml передаёт как build-аргумент в ARG PROVISA_EXTRAS файла Dockerfile: [tool-verified: scripts/provisa:69-79]
dq_checker |
PROVISA_EXTRAS (уровень Docker) |
Установка в нативный venv |
|---|---|---|
none |
firebase,vector |
provisa[embedded] |
soda |
firebase,vector,soda |
provisa[embedded,soda] |
gx |
firebase,vector,gx |
provisa[embedded,gx] |
Установка демо-набора данных повышает none до gx и сообщает об этом, потому что демо-конфигурация регистрирует набор Great Expectations поверх pet_store.pets, и его карточке качества иначе было бы нечего показывать. Указание soda оставляет soda без изменений.
Доступ к демо через pip, минуя установщик, пропускает этот шаг мастера, поэтому extra demo несёт ту же проверку: pip install 'provisa[embedded,demo]' — именно это нужно provisa run --demo для работы сканирования. Без этого сканирование сообщает data-quality checker 'great_expectations' is not installed, называя команду установки.
Любое другое значение останавливает запуск, вместо того чтобы стартовать без проверки, которую запросил оператор. Extra soda подтягивает soda-postgres; gx подтягивает great-expectations[postgresql]. Soda Core распространяется под Elastic License 2.0 — config/capabilities.yaml помечает этот вариант как cloud_eligible: false, и облачная плоскость его отклоняет.
Домены¶
Именование¶
naming:
convention: apollo_graphql # snake, hasura_graphql, apollo_graphql (default)
domain_prefix: true # prepend domain_id__ to all GraphQL names
rules:
- pattern: "^prod_pg_"
replace: ""
Соглашение об именовании¶
Механизм именования — единственный источник истины для имён, видимых клиенту; физические имена столбцов бэкенда клиентам никогда не раскрываются. (REQ-194) Каждый язык запросов выводит имя столбца из его column.alias, если он задан, иначе — из физического имени столбца по настроенному соглашению. (REQ-194)
Соглашение GraphQL — одно из трёх предустановленных перечислений. (REQ-416) Старые произвольные строки (none, snake_case, camelCase, PascalCase) объявлены устаревшими. (REQ-416)
| Пресет | По умолчанию | Имена типов | Имена полей | Имена мутаций |
|---|---|---|---|---|
apollo_graphql |
да | PascalCase | camelCase | camelCase |
hasura_graphql |
PascalCase | camelCase | snake_case | |
snake |
PascalCase | snake_case | snake_case |
Соглашение GraphQL по умолчанию — apollo_graphql, которое даёт имена полей и мутаций в camelCase. (REQ-194, REQ-416) Соглашение SQL отдельное, по умолчанию snake_case, применяется через apply_sql_name(); соглашение GraphQL применяется через apply_gql_name(), а имя CQL выводится из имени GraphQL. (REQ-194)
domain_prefix: bool — независимая опция, действующая вне зависимости от выбранного пресета. (REQ-416)
Явный column.alias — каноническое имя: SQL использует его дословно без применения соглашения, GraphQL применяет к нему своё соглашение, а CQL выводится из имени GraphQL. (REQ-194)
Переопределение на уровне источника:
Переопределение на уровне таблицы:
tables:
- source_id: legacy-db
table: orders
naming_convention: snake # overrides source for this table
Префикс домена¶
Когда domain_prefix: true, ко всем именам полей и типов GraphQL добавляется идентификатор домена через разделитель из двойного подчёркивания: (REQ-154)
| Таблица | Домен | Имя поля |
|---|---|---|
orders |
sales-analytics |
sales_analytics__orders |
customer_segments |
customer-insights |
customer_insights__customer_segments |
Это предотвращает коллизии имён, когда в разных доменах есть таблицы с одинаковым именем, и делает запросы самодокументируемыми.
Правила именования¶
Regex-правила, применяемые к именам таблиц при генерации имён полей GraphQL. Применяются по порядку до разрешения уникальности. (REQ-542)
Таблицы¶
tables:
- source_id: sales-pg
domain_id: sales-analytics
schema: public
table: orders
alias: purchase_orders # optional: override GraphQL name
description: "Customer purchase orders" # optional: GraphQL description
columns:
- name: id
visible_to: [admin, analyst]
writable_by: [] # read-only (empty = no writes)
- name: email
visible_to: [admin, analyst]
writable_by: [admin] # only admin can mutate
unmasked_to: [admin] # admin sees raw, analyst sees masked
mask_type: regex
mask_pattern: "^(.{2}).*(@.*)$"
mask_replace: "$1***$2"
alias: email_address # optional: override GraphQL field name
description: "Primary email address" # optional: appears in SDL
- name: amount
visible_to: [admin]
writable_by: [admin]
unmasked_to: [admin]
mask_type: constant
mask_value: "0"
- name: created_at
visible_to: [admin, analyst]
writable_by: [] # nobody can write
unmasked_to: [admin]
mask_type: truncate
mask_precision: month
column_presets: # auto-set values on insert/update
- column: created_by
source: header # from request header
name: X-User-ID
- column: updated_at
source: now # current timestamp
Псевдонимы¶
Псевдонимы таблиц и столбцов переопределяют имя GraphQL по умолчанию. (REQ-155) Полезно для:
- Переименования непонятных имён в базе данных (например,
tbl_cust_seg→customer_segments) - Избегания сокращений в слое API
- Создания чистого предметно-ориентированного словаря
Описания¶
Описания таблиц и столбцов включаются в сгенерированный SDL GraphQL. (REQ-156) Они отображаются в проводнике документации GraphiQL и в запросах интроспекции. Задавайте их в конфигурационном YAML или через панель администрирования.
Path (вычисляемое извлечение из JSON)¶
Столбцы могут извлекать значения из исходного столбца JSON/JSONB с помощью path в точечной нотации. (REQ-151) Это полезно для слабоструктурированных данных в сообщениях Kafka, документах MongoDB или столбцах JSONB PostgreSQL.
columns:
- name: payload
type: varchar
visible_to: [] # hide the raw JSON column
- name: order_id
type: integer
path: payload.order_id # extracts from payload column
visible_to: [admin, analyst]
- name: customer_name
type: varchar
path: payload.customer.name
visible_to: [admin, analyst]
Формат path — source_column.key1.key2.... Компилятор генерирует json_extract_scalar(source_column, '$.key1.key2') в SQL. (REQ-151)
Влияние на маршрутизацию: столбцы с path используют операторы JSON PostgreSQL (->>), которые нативно поддерживаются прямой маршрутизацией PG. (REQ-152) Для источников, отличных от PostgreSQL (MySQL, SQL Server и т. д.), запросы со столбцами path автоматически маршрутизируются через движок федерации. (REQ-152) На мутации это не влияет, поскольку столбцы path — вычисляемые поля только для чтения. (REQ-153)
Типы маскирования¶
| Тип | Поля | Описание |
|---|---|---|
regex |
pattern, replace |
REGEXP_REPLACE (только строковые столбцы) |
constant |
value |
Замена литералом (NULL, 0, MAX, MIN, произвольное значение) |
truncate |
precision |
DATE_TRUNC (только столбцы даты/времени) |
Связи (Relationships)¶
relationships:
- id: orders-to-customers
source_table_id: orders
target_table_id: customers
source_column: customer_id
target_column: id
cardinality: many-to-one # or: one-to-many
- id: orders-to-reviews
source_table_id: orders # sales-pg source
target_table_id: product_reviews # reviews-mongo source
source_column: product_id
target_column: product_id
cardinality: one-to-many
materialize: true # auto-create MV for this cross-source join
refresh_interval: 600 # refresh every 10 minutes
Автоматическая материализация¶
Установите materialize: true на связи, чтобы автоматически сгенерировать материализованное представление для межисточниковых JOIN. (REQ-158) Это позволяет избежать дорогостоящих федеративных запросов за счёт предварительного вычисления результата JOIN.
- Материализованные представления генерируются только для межисточниковых связей (JOIN в пределах одного источника уже быстрые) (REQ-159)
- Для связи, поддерживаемой через junction-таблицу, материализованное представление покрывает двухшаговый обход — переход к источнику, переход к junction, дискриминатор и собственные столбцы junction как атрибуты ребра. Junction считается отдельным звеном, поэтому ребро межисточниковое, если любая из трёх таблиц находится в другом источнике (REQ-1586)
- Материализованное представление изначально устаревшее и заполняется фоновым циклом обновления (REQ-160)
- Мутации любой из таблиц-источников помечают материализованное представление как устаревшее для повторного обновления (REQ-543)
refresh_intervalпо умолчанию 300 секунд (5 минут) (REQ-543)
Роли¶
roles:
- id: admin
capabilities:
- source_registration
- table_registration
- relationship_registration
- security_config
- query_development
- full_results
- admin
domain_access: ["*"]
- id: analyst
capabilities: [query_development]
domain_access: [sales-analytics]
- id: junior_analyst
capabilities: []
domain_access: [sales-analytics]
parent_role_id: analyst # inherits query_development + sales-analytics
Роли с parent_role_id наследуют возможности, доступ к доменам, права на столбцы и объекты, а также правила безопасности на уровне строк от родителя, при этом собственное правило безопасности на уровне строк дочерней роли для таблицы имеет приоритет. (REQ-215, REQ-1677) Цепочка разворачивается при запуске. (REQ-215)
Возможности (Capabilities)¶
| Возможность | Описание |
|---|---|
source_registration |
Регистрация источников данных |
table_registration |
Регистрация таблиц |
relationship_registration |
Определение связей |
security_config |
Настройка безопасности на уровне строк, маскирования |
query_development |
Выполнение запросов |
full_results |
Обход ограничений выборки |
admin |
Все возможности |
Правила безопасности на уровне строк (RLS)¶
rls_rules:
- table_id: orders
role_id: analyst
filter: "region = current_setting('provisa.user_region')"
Материализованные представления¶
materialized_views:
- id: mv-orders-customers
source_tables: [orders, customers]
join_pattern:
left_table: orders
left_column: customer_id
right_table: customers
right_column: id
join_type: left
# REQ-1586: add via_table with via_left_column/via_right_column (and
# via_type_column/via_type_value when the junction is discriminated) to
# cover a two-hop junction traversal instead of a direct join.
target_catalog: postgresql
target_schema: mv_cache
refresh_interval: 300
enabled: true
Представления (управляемые вычисляемые наборы данных)¶
Представления — это вычисляемые наборы данных, определённые на SQL, с полным управлением на уровне столбцов. (REQ-133) Это управляемый механизм добавления агрегаций, преобразований и производных метрик в модель. (REQ-136)
views:
- id: monthly-revenue
sql: |
SELECT DATE_TRUNC('month', created_at) AS month,
region,
SUM(amount) AS revenue,
COUNT(*) AS order_count
FROM orders
GROUP BY 1, 2
description: "Monthly revenue by region"
domain_id: sales-analytics
materialize: true
refresh_interval: 3600
columns:
- name: month
visible_to: [admin, analyst]
- name: region
visible_to: [admin, analyst]
- name: revenue
visible_to: [admin]
- name: order_count
visible_to: [admin, analyst]
| Поле | Обязательно | Описание |
|---|---|---|
id |
Да | Уникальный идентификатор представления |
sql |
Да | SQL-инструкция SELECT, определяющая представление |
domain_id |
Да | Домен для видимости схемы |
materialize |
Нет | true = периодическое обновление через CTAS, false = живое федеративное представление |
refresh_interval |
Нет | Секунды между обновлениями (только для материализованных, по умолчанию 300) |
description |
Нет | Отображается в SDL GraphQL |
alias |
Нет | Переопределяет имя GraphQL |
columns |
Да | Определения столбцов с видимостью, маскированием, описаниями |
Материализованное или живое¶
materialize: true: Provisa создаёт таблицу через CTAS и обновляет её по расписанию. (REQ-135) Быстрее запросы, но данные могут устаревать доrefresh_intervalсекунд.materialize: false: Provisa создаёт федеративное представление. (REQ-135) Запросы всегда возвращают актуальные данные, но могут выполняться медленнее для сложных агрегаций.
Представления проходят тот же конвейер управления, что и таблицы, — безопасность на уровне строк, маскирование, выборка и видимость на основе ролей. (REQ-134) Это гарантирует, что новая семантика не может быть добавлена в платформу без надзора со стороны дата-стюарда. (REQ-136)
Представления только для чтения¶
И представления с materialize: true, и с materialize: false предоставляют свой тип GraphQL только для запросов. Для отношений, поддерживаемых view_sql, не генерируются мутации insert, upsert, update или delete. (REQ-1157) [tool-verified: provisa/compiler/schema_gen.py:184, provisa/compiler/schema_types.py:79]
Кеш¶
Иерархия кеша¶
Порядок разрешения TTL (наиболее конкретное значение побеждает): таблица > источник > глобальное значение по умолчанию. (REQ-544) Используется первое ненулевое значение.
cache:
enabled: true
redis_url: ${env:REDIS_URL}
default_ttl: 300 # global fallback: 5 minutes
sources:
- id: sales-pg
cache_enabled: true # toggle caching for all tables in this source
cache_ttl: 600 # source override: 10 minutes
tables:
- source_id: sales-pg
table: orders
cache_ttl: 60 # table override: 1 minute (frequently changing)
- source_id: sales-pg
table: customers
# no cache_ttl → inherits source TTL (600s)
Установка cache_enabled: false на источнике отключает кеширование для всех таблиц этого источника независимо от TTL на уровне таблицы. (REQ-544) Ключи кеша всегда включают role_id и значения контекста безопасности на уровне строк для разделения по соображениям безопасности. (REQ-544)
Включение для отдельного запроса¶
Кеш ответов выключен для каждого запроса, который его не запрашивает. (REQ-544) Запрос включает его так:
| Интерфейс | Включение |
|---|---|
GraphQL (/data/graphql, Arrow Flight) |
@cached на операции, при необходимости @cached(ttl: 60) |
SQL (pgwire, Flight SQL, /data/sql) |
строка комментария -- @provisa cache=true или -- @provisa cache_ttl=60 в инструкции |
Cypher (/data/cypher, Neo4j Query API, Bolt, Arrow Flight) |
строка комментария // @provisa cache=true или // @provisa cache_ttl=60 в запросе |
| gRPC (и HTTP-прокси gRPC) | метаданные вызова (заголовки на прокси) x-provisa-cache: true или x-provisa-cache-ttl: 60 |
REST, JSON:API и, как альтернатива указанию в тексте: GraphQL по HTTP, /data/cypher, Neo4j Query API |
заголовок запроса Cache-Control: max-age=60 (или max-stale=60) либо x-provisa-cache: true / x-provisa-cache-ttl: 60 |
ttl, не являющийся целым числом, приводит к ошибке запроса. Запрос, который указывает включение дважды (в тексте и в заголовке или в двух заголовках) с разными значениями, завершается ошибкой 400; ни одному значению предпочтение не отдаётся. Cache-Control: no-cache или no-store означает отсутствие кеша, как без заголовка. [tool-verified: provisa/compiler/directives.py cache_hint_for, cache_hint_from_grpc_metadata, request_cache_hint]
Без подсказки запрос не читает кеш и не пишет в него. С ней по-прежнему решают настройки выше: результат кешируется, только если у каждого читаемого источника cache_enabled: true, а разрешённый TTL каждой таблицы больше 0. Запись живёт ttl запроса, если он указан, иначе — кратчайший разрешённый TTL прочитанных таблиц. (REQ-544)
Подсказка лишь соглашается на более старые данные ради скорости. Она никогда не делает чтение более свежим, чем позволяют настройки оператора: свежесть загрузки и реплики (cache_ttl, change_signal), row_materialize, снимки load_protected и проверки свежести действуют для запроса с подсказкой точно так же, как без неё. См. раздел о свежести и нагрузке в этом документе. (REQ-544)
@noCache и -- @provisa no_cache=true больше не существуют: при выключенном по умолчанию кеше обходить нечего.
Запись делает недействительной каждую запись кеша, которую пишущая организация хранит для записанных таблиц; записи другой организации для той же таблицы не затрагиваются. Если инвалидация не удалась, запрос завершается ошибкой, а не оставляет устаревшие записи. (REQ-544, REQ-595)
Актуальность и нагрузка: кто решает¶
Три стороны влияют на то, насколько свежим будет результат и какую нагрузку запрос создаст на системы за ним. (REQ-030)
- Исходный источник. В идеале он сам управляет своим противодавлением: лимиты соединений, тайм-ауты операторов, реплики для чтения.
- Оператор. Защищает платформу, то есть сам Provisa, от противодавления. Если источник не может защитить себя, оператор защищает и его. Настройки для этого задаются на источниках и таблицах:
load_protected,replicate,federation_hintsисточника, порог перенаправления больших результатов, кластер Kafka, в который пишут sink-и, и зарегистрированный watermark каждой таблицы. - Конечный пользователь. Выбирает между скоростью и актуальностью, запрос за запросом.
Настройки оператора являются нижней границей. Запрос может сдвинуться выше неё, к более старым данным или меньшей нагрузке; включение кэша ответов — обычный пример. Опуститься ниже он не может никогда. Подсказка в запросе, которая сделала бы это, отклоняется с ошибкой, называющей настройку оператора; её не применяют и не отбрасывают молча.
| Входные данные запроса | Что разрешено | Отклоняется, когда |
|---|---|---|
@route(engine: DIRECT), -- @provisa route=direct |
Выбрать прямой драйвер для одного источника | таблица, которую читает запрос, имеет load_protected или replicate: 0 |
@join, @reorder, @broadcastSize, /*+ ... */ |
Задать свойство сессии движка, не заданное в federation_hints источника |
меняет свойство, заданное оператором |
X-Provisa-Redirect-Threshold, @redirect(threshold:) |
Перенаправить результат раньше | значение выше порога оператора |
@sink(broker:), брокер в X-Provisa-Sink |
Повторить брокер оператора | указан другой брокер или KAFKA_BOOTSTRAP_SERVERS не настроен |
@watermark в подписке |
Повторить зарегистрированный watermark таблицы | указан другой столбец или у таблицы его нет |
@cached, -- @provisa cache=true |
Отдать более старый результат из кэша | никогда; запись кэша не бывает свежее чтения, которое её сохранило |
Отказы возвращают HTTP 403 с кодом query.operator_floor, SQLSTATE 42501 через pgwire и PERMISSION_DENIED через Flight и gRPC. (REQ-030)
Таблица с load_protected или replicate: 0 никогда не читается запросом напрямую ни через один транспорт. Запросы читают её реплику. Источник читают только репликация и её обновления: обновление выполняется, когда этого требует cache_ttl или проверка актуальности; без них реплика строится один раз и далее обновляется только через поток изменений или планировщик. (REQ-1907) (REQ-1141, REQ-826) [tool-verified: tests/integration/test_operator_floor_e2e.py] Для такой таблицы с off_peak_window (у таблицы или её источника, в часовом поясе off_peak_tz) обновление выполняется только пока окно открыто: обновление, наступившее или запрошенное вне окна, ждёт его следующего открытия, а окно без cache_ttl обновляет таблицу один раз за открытие. Первое построение никогда не откладывается, потому что чтения таблицы ждут его. [tool-verified: provisa/federation/replica_builds.py _deferred_until, _next_refresh_at; tests/integration/test_off_peak_window_refresh_e2e.py]
Настройка replicate¶
replicate — целое число на таблице. Таблица без значения берёт значение своего источника, а если не задано ни то ни другое, действует глобальный порог. Реплика — это копия таблицы источника, хранящаяся в хранилище движка и обновляемая по настройкам актуальности таблицы; это не непрерывный поток изменений. (REQ-826) [tool-verified: provisa/core/replicate.py]
| Значение | Название | Смысл |
|---|---|---|
| не задано | По умолчанию | Действует глобальный порог |
-1 |
Никогда | Читается напрямую везде, где есть прямой путь. Реплицируется только на движке, который не может читать источник на месте |
N больше 0 |
Hot-N | Читается напрямую, пока таблица не превысит N проверенных политиками запросов за интервал, затем обслуживается из реплики |
0 |
Всегда | Чтение идёт из реплики |
Гарантией является только «Всегда». «Никогда» и значения Hot действуют по возможности. load_protected вместе с replicate: -1 отклоняется при загрузке конфигурации и при сохранении. У источника с replicate: 0 нет прямого подключения ни на одном движке, поэтому каждая его таблица обслуживается из своей реплики.
Нижняя граница оценивается по таблицам, которые читает запрос. Запрос, не читающий ни одной таблицы, обслуживаемой из реплики, сохраняет прямой маршрут, даже если у его источника есть другие реплицируемые таблицы. [tool-verified: provisa/federation/registry_view.py operator_floor]
Реплика индексируется по объявленному первичному ключу и по столбцам, по которым соединяются объявленные связи; индексы строятся после её загрузки. Где эти индексы ускоряют соединения, где хранить реплики и как выбирать их актуальность — см. Replicas. (REQ-2015) [tool-verified: provisa/federation/replica_indexes.py]
Hot-репликация¶
Таблица, у которой replicate не задан или равен N больше 0, читается напрямую, пока не станет загруженной.
replication:
hot_threshold: 100 # statements per interval for a table left at Default
hot_interval: 60 # seconds: the window the count is taken over, and how often it is judged
hot_max_rows: 10000000 # a larger table is not replicated for being busy
| Настройка | Переменная окружения | По умолчанию |
|---|---|---|
replication.hot_threshold |
PROVISA_REPLICATION_HOT_THRESHOLD |
100 |
replication.hot_interval |
PROVISA_REPLICATION_HOT_INTERVAL |
60 |
replication.hot_max_rows |
PROVISA_REPLICATION_HOT_MAX_ROWS |
10000000 |
Все три — настройки оператора: admin UI показывает их в разделе Hot Tables, а сохранённое значение применяется при следующей оценке.
Как считается таблица:
- Проверенный политиками запрос засчитывает каждую читаемую таблицу один раз, сколько бы раз он её ни читал.
- Запрос, обслуженный из кэша ответов, не засчитывается. Он не нагрузил источник.
- Запрос, отклонённый политиками доступа, не засчитывается.
Таблица повышается, когда её счётчик достигает её порога (её собственного N, иначе порога её источника, иначе hot_threshold), и понижается, когда счётчик опускается ниже половины порога. Повышение запрашивает построение реплики; до его завершения таблица читается напрямую, затем из реплики. Понижение сразу возвращает чтение к источнику.
Таблица не повышается, если в ней больше строк, чем hot_max_rows, если её сигнал изменений — ttl или ttl_probe, а ни у неё, ни у её источника не объявлен cache_ttl, или если её уже ведёт горячий уровень Redis. Сводка таблицы в admin UI указывает, какой из случаев имеет место.
Счётчики хранятся в Redis. При общем Redis (cache.redis_url) они охватывают все процессы развёртывания. При встроенном Redis они ведутся по процессам, поэтому повышение работает только когда запросы обслуживает один рабочий процесс; при нескольких рабочих процессах и без общего Redis ничего не повышается, о чём говорится в сводке. [tool-verified: provisa/federation/replica_hot.py]
Аутентификация¶
auth:
provider: simple # none, firebase, keycloak, oauth, simple
superuser:
username: admin
password: ${env:PROVISA_SUPERUSER_PASSWORD}
simple:
allow: true
jwt_secret: ${env:PROVISA_JWT_SECRET}
users:
- username: admin
password_hash: "$2b$12$..."
roles: [admin]
role_mapping:
- claim: groups
contains: data-analysts
provisa_role: analyst
default_role: analyst
Типы провайдеров аутентификации¶
| Провайдер | Сценарий использования | Проверка токена |
|---|---|---|
simple |
Локальная разработка/тестирование. Пользователи определены в YAML. | JWT, подписанный PROVISA_JWT_SECRET |
firebase |
Firebase Authentication (все методы). | verify_id_token() SDK firebase-admin |
keycloak |
Keycloak OIDC. Сопоставление тенанта и клиентских ролей. | Проверка JWT на основе JWKS |
oauth |
Обобщённый OIDC (Okta, Azure AD, Auth0, PingFederate). | JWKS с discovery URL |
basic |
Автономные развёртывания. Учётные записи хранятся в собственном хранилище Provisa. | Пароль bcrypt или SCRAM-SHA-256 на pgwire |
Учётные данные суперпользователя (блок superuser) работают с любым провайдером и всегда разрешаются в роль admin со всеми возможностями. (REQ-125) Используется для первоначальной настройки до подключения внешней аутентификации.
SCRAM-SHA-256 (auth.scram)¶
Заставляет pgwire анонсировать SASL с SCRAM-SHA-256, так что пароль доказывается, а не передаётся открытым текстом. (REQ-1394) Это применяется только к провайдеру basic — ни один другой провайдер не хранит верификаторы RFC 5802, необходимые для SCRAM, — и привязка канала не предлагается.
Верификаторы нельзя получить из существующих хешей bcrypt. Верификатор записывается всякий раз, когда пароль проходит в открытом виде, поэтому первое SCRAM-соединение каждого пользователя следует за его следующей регистрацией, входом, сменой пароля или сбросом администратором. До этого момента соединения этого пользователя используют резервный обмен открытым текстом по TLS; протокол не раскрывает, кто уже перешёл на SCRAM.
Ограничение частоты попыток входа (auth.login_throttle)¶
auth:
login_throttle:
max_attempts: 5 # failures within the window before lockout
window_seconds: 300 # how far back failures are counted
lockout_seconds: 900 # how long a locked-out subject is refused
Включено по умолчанию с указанными значениями; блок только настраивает их. (REQ-1393) Счётчик находится на уровне проверки учётных данных, поэтому неудачи через HTTP, pgwire и Bolt накапливаются для одного и того же субъекта, и блокировка действует на всех поверхностях. Она действует в рамках процесса: несколько воркеров API каждый допускают до max_attempts.
Персональные токены доступа¶
Персональные токены доступа не требуют блока конфигурации — они всегда принимаются, и хранилище создаётся вместе с остальной схемой плоскости управления. (REQ-1263) Настраивается срок действия, который пользователь может запросить при выпуске: от 1 до 366 дней или "без срока действия" для токена, который не истекает. См. Модель безопасности.
Взаимный TLS (Mutual TLS)¶
Проверка клиентских сертификатов настраивается через переменную окружения, а не в provisa.yaml, наряду с настройками сертификатов TLS, которые она расширяет. (REQ-1228)
| Переменная | По умолчанию | Значение |
|---|---|---|
PROVISA_MTLS_CLIENT_CA |
не задано | Пакет PEM с CA, которым разрешено подписывать клиентские сертификаты. Установка этой переменной включает проверку клиентских сертификатов |
PROVISA_MTLS_MODE |
required, как только задан CA |
required или optional |
PROVISA_MTLS_BIND_PRINCIPAL |
false |
Требовать, чтобы общее имя (common name) сертификата совпадало с именем пользователя, от имени которого аутентифицируется соединение |
Для каждого протокола можно задать отдельное переопределение по той же схеме именования, что и настройки TLS. Режим, заданный без CA, или режим, не являющийся ни одним из допустимых значений, приводит к отказу от запуска, а не к обслуживанию соединений, которые оператор считает проверенными.
Адресация организации через TLS¶
Настраивать ничего не нужно. В развёртывании с несколькими организациями pgwire и Bolt читают организацию из имени хоста, к которому обратился клиент, переданного в TLS ClientHello, точно так же, как HTTP читает его из заголовка Host. (REQ-1234) Клиент, подключающийся к acme.provisa.dev, запрашивает организацию acme; запрос отклоняется, если аутентифицированный субъект не является её участником. Подключение по IP-адресу не запрашивает организацию, что соответствует любому соединению в развёртывании с одной организацией.
Полный пример конфигурации аутентификации (закомментировано)¶
# auth:
# provider: firebase
#
# superuser:
# username: admin
# password: ${env:PROVISA_SUPERUSER_PASSWORD}
#
# firebase:
# project_id: ${env:FIREBASE_PROJECT_ID}
# service_account_key: ${env:FIREBASE_SERVICE_ACCOUNT}
#
# # keycloak:
# # server_url: https://keycloak.example.com
# # # kc-tenant: set to your Keycloak tenant name (e.g. provisa)
# # client_id: provisa-app
# # client_secret: ${env:KEYCLOAK_CLIENT_SECRET}
#
# # oauth:
# # discovery_url: https://login.example.com/.well-known/openid-configuration
# # client_id: provisa
# # client_secret: ${env:OAUTH_CLIENT_SECRET}
# # role_claim: groups
# # audience: provisa-api
#
# role_mapping:
# - claim: custom_claims.role
# value: admin
# provisa_role: admin
# - claim: groups
# contains: data-analysts
# provisa_role: analyst
# default_role: analyst
Мутации Upsert¶
Для таблиц с первичным ключом Provisa автоматически генерирует поля мутации upsert_<table>. (REQ-212) Они компилируются в upsert на целевом диалекте — INSERT ... ON CONFLICT (pk) DO UPDATE SET ... в PostgreSQL, ON DUPLICATE KEY UPDATE в MySQL. (REQ-212)
Столбцы конфликта выводятся из метаданных первичного ключа. (REQ-212) Применяются все правила видимости столбцов и разрешений на запись.
Distinct On¶
Аргумент distinct_on выбирает первую строку для каждого отдельного значения указанных столбцов. (REQ-213) Доступен для корневых полей запроса.
{
orders(distinct_on: [region], order_by: [{region: asc, created_at: desc}]) {
region
amount
created_at
}
}
Компилируется в SELECT DISTINCT ON (region) ... в PostgreSQL. (REQ-213) Для диалектов, отличных от PG, используется резервный вариант с оконными функциями. (REQ-213)
Пресеты столбцов (Column Presets)¶
Автоматически подставляют значения в столбцы при insert/update. (REQ-214) Определяются для каждой таблицы в конфигурации.
tables:
- source_id: sales-pg
table: orders
column_presets:
- column: created_by
source: header # from request header
name: X-User-ID
- column: updated_at
source: now # current timestamp
- column: source_system
source: literal # constant value
value: "provisa"
| Источник | Поведение |
|---|---|
header |
Подставляет значение из именованного HTTP-заголовка запроса |
now |
Подставляет NOW() (текущую метку времени) |
literal |
Подставляет константное значение |
Пресетные столбцы подставляются на этапе компиляции мутации, до генерации SQL. (REQ-214) Они не видны во входном типе мутации. (REQ-214)
Наследуемые роли¶
Роли могут наследоваться от одной родительской роли через parent_role_id. (REQ-215) Цепочка разворачивается при запуске. (REQ-215) Дочерняя роль обладает объединением возможностей и доступа к доменам своих предков; столбец, метрика, функция или вебхук, предоставленные предку, предоставляются и дочерней роли; а правила безопасности на уровне строк предка применяются к дочерней роли для каждой таблицы, начиная с ближайшей роли, при этом собственное правило дочерней роли для таблицы заменяет родительское. (REQ-1677)
roles:
- id: admin
capabilities: [admin]
domain_access: ["*"]
- id: analyst
capabilities: [query_development]
domain_access: [sales-analytics]
- id: junior_analyst
capabilities: []
domain_access: []
parent_role_id: analyst # inherits query_development + sales-analytics
- id: intern
capabilities: []
domain_access: []
parent_role_id: junior_analyst # inherits from junior_analyst (and transitively analyst)
Поддерживается многоуровневое наследование. (REQ-215) Явные возможности и domain_access дочерней роли объединяются с родительскими. (REQ-215) Родитель должен быть существующей ролью, не может быть самой ролью и не может замыкать цикл; каждое из этих условий проверяется и отклоняется при сохранении. (REQ-1677)
Запланированные триггеры¶
Триггеры на основе cron, вызывающие URL вебхука по расписанию. (REQ-216) Использует APScheduler. (REQ-216)
scheduled_triggers:
- name: daily-report
cron: "0 8 * * *" # 8:00 AM daily
webhook_url: https://hooks.example.com/daily-report
enabled: true
- name: hourly-sync
cron: "0 * * * *" # every hour
webhook_url: https://hooks.example.com/sync
enabled: false
Запланированные задачи управляются через панель администрирования (переключатель включения/выключения) или административную мутацию toggle_scheduled_task. (REQ-216)
Формат OrderBy¶
OrderBy использует формат {column: direction} с перечислением направления из 6 значений: (REQ-200, REQ-201)
| Направление | SQL |
|---|---|
asc |
ASC |
desc |
DESC |
asc_nulls_first |
ASC NULLS FIRST |
asc_nulls_last |
ASC NULLS LAST |
desc_nulls_first |
DESC NULLS FIRST |
desc_nulls_last |
DESC NULLS LAST |
Сортировка по связям поддерживается через вложенные объекты: (REQ-202)
Наблюдаемость¶
observability:
endpoint: "http://localhost:4319" # OTLP collector; env OTEL_EXPORTER_OTLP_ENDPOINT overrides
service_name: provisa # env OTEL_SERVICE_NAME overrides
sample_rate: 1.0 # 0.0–1.0; TraceIdRatioBased sampler
log_level: WARNING # env OTEL_LOG_LEVEL overrides
compact_batch_size: 1000
telemetry_filter:
redact_sql_literals: false # strip literal values from db.statement before export
redact_attributes: [] # attribute keys dropped entirely before export
# support_endpoint: "" # env PROVISA_SUPPORT_OTLP_ENDPOINT; off by default
support_telemetry_filter:
redact_sql_literals: true # default on — strip literals before sending to support
redact_attributes: [] # additional keys dropped before sending to support
Фильтры телеметрии [tool-verified]¶
Provisa использует два независимых пути экспорта OTLP: ваш внутренний коллектор и опциональный эндпоинт поддержки Provisa. (REQ-545) У каждого пути свой фильтр. Фильтры выполняются внутри оборачивающего _FilteringExporter перед тем, как спаны покидают процесс, — исходные объекты спанов никогда не изменяются. (REQ-546) [tool-verified: provisa/api/otel_setup.py lines 156–207]
telemetry_filter — управляет тем, что попадает в ваш внутренний коллектор.
| Ключ | Тип | По умолчанию | Описание |
|---|---|---|---|
redact_sql_literals |
bool | false |
Заменяет строковые и числовые литералы в db.statement на ? |
redact_attributes |
list[str] | [] |
Ключи атрибутов, полностью удаляемые из каждого спана |
support_telemetry_filter — управляет тем, что попадает на эндпоинт поддержки Provisa. Удаление SQL-литералов по умолчанию включено (true) на этом пути, поскольку данные запросов принадлежат вам. (REQ-547) [tool-verified: provisa/api/otel_setup.py line 240]
| Ключ | Тип | По умолчанию | Описание |
|---|---|---|---|
redact_sql_literals |
bool | true |
Заменяет строковые и числовые литералы в db.statement на ? |
redact_attributes |
list[str] | [] |
Ключи атрибутов, полностью удаляемые из каждого спана |
Пример редактирования db.statement — при redact_sql_literals: true этот атрибут спана:
становится:
Эндпоинт поддержки [tool-verified]¶
support_endpoint (или переменная окружения PROVISA_SUPPORT_OTLP_ENDPOINT) пересылает телеметрию в службу поддержки Provisa для диагностики. (REQ-548) Если не задано, никакие данные не покидают вашу инфраструктуру через этот путь. (REQ-548) Фильтр поддержки применяется независимо от внутреннего фильтра — вы можете удалять SQL-литералы из обоих экспортов, при этом всё равно делясь со службой поддержки данными о времени выполнения спанов и ошибках. (REQ-545) [tool-verified: provisa/api/otel_setup.py lines 238–288]
Определение протокола эндпоинта [tool-verified]¶
Provisa выбирает OTLP/HTTP или OTLP/gRPC на основе схемы URL эндпоинта. (REQ-549) URL, начинающиеся с http:// или https://, используют OTLP/HTTP, с автоматическим добавлением /v1/traces, /v1/metrics и /v1/logs. (REQ-549) Любая другая схема использует OTLP/gRPC с insecure=True. (REQ-549) [tool-verified: provisa/api/otel_setup.py lines 60–70]
Движок федерации¶
Настройка движка федерации опциональна. По умолчанию используется duckdb — без конфигурации, в процессе, без необходимости во внешнем сервисе (REQ-989). Выберите другой движок, если вам нужен масштаб MPP или вы хотите переиспользовать существующее хранилище данных.
Приоритет: переменная окружения PROVISA_ENGINE → сохранённое поле конфигурации federation_engine в панели администрирования → duckdb. Изменения вступают в силу при перезапуске сервиса. [tool-verified: engine.py build_engine]
Обзор движков [tool-verified: engine.py ENGINE_REGISTRY, _ENGINE_BUILDERS]¶
| Ключ движка | Название | Диалект | MPP | Механизм внешней связи | Аутентификация |
|---|---|---|---|---|---|
trino |
Provisa Federation Engine | Trino SQL | Да | Каталоги Trino (широкий набор коннекторов) | Учётные данные JDBC |
trino-byo |
Trino | Trino SQL | Да | Так же, как trino; неуправляемый координатор |
Учётные данные JDBC |
pg |
PostgreSQL | PostgreSQL | Нет | FDW / pg_duckdb | Учётные данные PostgreSQL |
duckdb |
DuckDB | DuckDB | Нет | Нативный ATTACH расширения | Нет (в процессе) |
clickhouse |
ClickHouse (встроенный) | ClickHouse | Да | Табличные движки S3 / IcebergS3 / DeltaLake | chdb (в процессе, без аутентификации) |
clickhouse-server |
ClickHouse (сервер / облако) | ClickHouse | Да | Табличные движки S3 / IcebergS3 / DeltaLake | Учётные данные ClickHouse |
snowflake |
Snowflake | Snowflake | Да | Внешний stage + внешняя таблица | PROVISA_ENGINE_URL |
databricks |
Databricks | Databricks SQL | Да | Внешние таблицы Unity Catalog через REST | PROVISA_ENGINE_URL (bearer-токен + http_path) |
bigquery |
BigQuery | BigQuery | Да | Внешние таблицы BigQuery / BigLake | GOOGLE_APPLICATION_CREDENTIALS |
fabric |
Microsoft Fabric | T-SQL | Да | OneLake shortcuts → OPENROWSET | Azure AD (az login или управляемое удостоверение) |
synapse |
Azure Synapse | T-SQL | Да | ADLS OPENROWSET / внешние таблицы | Azure AD |
mysql |
MySQL | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
mariadb |
MariaDB | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
oracle |
Oracle Database | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
mssql |
Microsoft SQL Server | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
db2 |
IBM Db2 | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
redshift |
Amazon Redshift | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
greenplum |
Greenplum | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
cockroachdb |
CockroachDB | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
yugabytedb |
YugabyteDB | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
opengauss |
openGauss | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
tidb |
TiDB | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
singlestore |
SingleStore | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
vertica |
Vertica | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
exasol |
Exasol | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
teradata |
Teradata Vantage | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
saphana |
SAP HANA | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
sapase |
SAP ASE (Sybase) | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
sqlanywhere |
SAP SQL Anywhere | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
monetdb |
MonetDB | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
firebird |
Firebird | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
sqlalchemy |
Другая реляционная база данных (по URL подключения) | По диалекту | Нет | Нет (только приземление данных) | Учётные данные по диалекту |
Справочник по движкам¶
trino / trino-byo¶
trino — управляемый координатор Provisa; trino-byo подключается к вашему собственному кластеру Trino. Оба используют Trino SQL и обладают самым широким охватом типов источников.
Хранилище материализации по умолчанию — TENANT_DATABASE_URL (PostgreSQL).
pg¶
Выполняет федерацию через расширения postgres_fdw (SQL/MED) и pg_duckdb. Однонодовый режим; без MPP. Лучше всего подходит, если ваши данные уже находятся в PostgreSQL и вы хотите соединять несколько удалённых источников.
Хранилище материализации по умолчанию — TENANT_DATABASE_URL.
duckdb¶
В процессе; без внешнего сервиса. Движок по умолчанию (REQ-989). PROVISA_DATA_DIR определяет, где находится встроенное хранилище (по умолчанию ~/.provisa).
Хранилище материализации по умолчанию — ~/.provisa/materialize.duckdb — единственный движок с хранилищем по умолчанию, отличным от PostgreSQL.
clickhouse (встроенный) / clickhouse-server¶
clickhouse использует chdb (в процессе). clickhouse-server подключается к внешнему экземпляру ClickHouse или ClickHouse Cloud. Оба читают Delta Lake, Iceberg и Hudi напрямую через нативные табличные движки ClickHouse.
# External server
PROVISA_ENGINE=clickhouse-server
PROVISA_ENGINE_URL="clickhouse://user:pass@host:9000/db"
Хранилище материализации по умолчанию — TENANT_DATABASE_URL.
snowflake¶
Движок как хранилище данных: Snowflake выполняет запросы; Provisa передаёт данные источников через внешние stage.
Хранилище материализации по умолчанию — TENANT_DATABASE_URL.
databricks¶
Внешние таблицы Unity Catalog соединяют источники, управляемые Provisa, с Databricks SQL.
PROVISA_ENGINE=databricks
PROVISA_ENGINE_URL="databricks://token:TOKEN@my-workspace.azuredatabricks.net?http_path=/sql/1.0/warehouses/xxxx"
Хранилище материализации по умолчанию — TENANT_DATABASE_URL.
bigquery¶
Внешние таблицы BigQuery и BigLake. Проект берётся из URL или GOOGLE_CLOUD_PROJECT; аутентификация через ключ сервисного аккаунта.
PROVISA_ENGINE=bigquery
PROVISA_ENGINE_URL="bigquery://my-project?location=US"
# GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json
Хранилище материализации по умолчанию — TENANT_DATABASE_URL.
fabric / synapse¶
Оба используют T-SQL поверх TDS с аутентификацией Azure AD (az login или управляемое удостоверение). Опустите PROVISA_ENGINE_URL, чтобы читать данные подключения из переменных окружения.
PROVISA_ENGINE=fabric
# FABRIC_SQL_SERVER=... FABRIC_DATABASE=...
# or: PROVISA_ENGINE_URL set explicitly
PROVISA_ENGINE=synapse
# SYNAPSE_SQL_SERVER=... SYNAPSE_DATABASE=...
Хранилище материализации по умолчанию — TENANT_DATABASE_URL.
Реляционные движки (mysql, mariadb, oracle, mssql, db2, redshift, greenplum, cockroachdb, yugabytedb, opengauss, tidb, singlestore, vertica, exasol, teradata, saphana, sapase, sqlanywhere, monetdb, firebird) и sqlalchemy¶
Один ключ на каждую реляционную базу данных, доступную по сети, все работают на одной и той же среде выполнения "только приземление" (без федерации к внешним источникам): каждый источник приземляется в хранилище и запрашивается там же. Ключ выбирает базу данных; PROVISA_ENGINE_URL несёт DSN в формате, который принимает её диалект. sqlalchemy — универсальный вариант для базы данных без собственного ключа. Встроенные в файл хранилища (SQLite, Access) не предлагаются — сервер должен быть доступен по сети.
Хранилище материализации по умолчанию — TENANT_DATABASE_URL.
Хранилище материализации¶
Когда источник не может подключиться напрямую (нет коннектора ATTACH для выбранного движка), он приземляется в хранилище материализации движка. Порядок разрешения: явный PROVISA_MATERIALIZE_URL → объявленное значение по умолчанию движка → явная ошибка (без незаметного резервного варианта). [tool-verified: engine.py materialize_store]
DuckDB объявляет свой встроенный файл (~/.provisa/materialize.duckdb) как значение по умолчанию. Все остальные движки по умолчанию используют TENANT_DATABASE_URL (PostgreSQL). Переопределить можно для любого движка через PROVISA_MATERIALIZE_URL.
Хранилище определяет, что индексы реплики дают соединениям: хранилище PostgreSQL индексирует реплики, и движок, выполняющий в нём SQL, читает эти индексы, тогда как DuckDB соединяет реплики своего встроенного файла поверх копии, создаваемой на каждый запрос. См. Replicas. (REQ-2015)
Подсказки федерации для отдельных источников¶
Расширенные параметры подключения, которые не помещаются в стандартные поля host/port/user/password, задаются в federation_hints источника. Ключи подсказок для конкретных типов см. в справочнике по типам источников выше. Сводный пример:
sources:
- id: my-databricks
type: databricks
host: my-workspace.azuredatabricks.net
password: ${env:DATABRICKS_TOKEN}
federation_hints:
http_path: /sql/1.0/warehouses/xxxx # required for Databricks sources
- id: my-snowflake
type: snowflake
host: org.snowflakecomputing.com
username: svc_provisa
password: ${env:SNOWFLAKE_PASSWORD}
federation_hints:
account: myorg-myaccount
warehouse: COMPUTE_WH
- id: my-clickhouse
type: clickhouse
host: ch.example.com
port: 8123
password: ${env:CLICKHOUSE_PASSWORD}
federation_hints:
secure: "true" # enable TLS on the HTTP interface
- id: r2-parquet
type: parquet
path: s3://my-bucket/data/events.parquet
federation_hints:
access_key_id: ${env:R2_ACCESS_KEY}
secret_access_key: ${env:R2_SECRET}
account_id: ${env:R2_ACCOUNT_ID} # Cloudflare R2 account (S3-compatible)
Для источников Google Cloud задайте GOOGLE_APPLICATION_CREDENTIALS — путь к файлу ключа сервисного аккаунта. Для Fabric и Synapse аутентифицируйтесь через az login (для разработки) или управляемое удостоверение (для продакшена) — движок читает учётные данные через DefaultAzureCredential из azure-identity.
Переменные окружения¶
| Переменная | По умолчанию | Описание |
|---|---|---|
PROVISA_CONFIG |
config/provisa.yaml |
Путь к файлу конфигурации |
TENANT_DATABASE_URL |
postgresql+psycopg://provisa:provisa@localhost:5432/provisa |
URI хранилища плоскости управления (SQLAlchemy async); принимает sqlite+pysqlite://… / duckdb://… для встроенного desktop-хранилища (REQ-828, REQ-850) |
PLATFORM_DATABASE_URL |
— | URI реестра платформы (каталог тенантов, реестр движков); обязателен при запуске, без резервного варианта (REQ-837) |
PROVISA_REDIS_EMBEDDED |
— | 1/true использует встроенный fakeredis вместо сервера Redis — без Docker (REQ-829) |
PG_HOST |
localhost |
Хост PostgreSQL |
PG_PORT |
5432 |
Порт PostgreSQL |
PG_DATABASE |
provisa |
База данных PostgreSQL |
PG_USER |
provisa |
Пользователь PostgreSQL |
PG_PASSWORD |
provisa |
Пароль PostgreSQL |
PROVISA_ENGINE |
duckdb |
Ключ движка федерации (REQ-989, REQ-916) |
PROVISA_ENGINE_URL |
— | URL подключения для движков, управляемых через URL (Snowflake, Databricks, ClickHouse Server, BigQuery, SQLAlchemy) |
PROVISA_MATERIALIZE_URL |
— | Переопределяет DSN хранилища материализации (по умолчанию — объявленное значение движка) |
PROVISA_DATA_DIR |
~/.provisa |
Каталог данных для встроенного хранилища DuckDB (REQ-989) |
TRINO_HOST |
localhost |
Хост координатора Trino |
TRINO_PORT |
8080 |
HTTP-порт координатора Trino |
GOOGLE_APPLICATION_CREDENTIALS |
— | Путь к JSON-ключу сервисного аккаунта GCP (движок/источник BigQuery) |
GOOGLE_CLOUD_PROJECT |
— | Проект GCP по умолчанию (BigQuery; переопределяется URL) |
FABRIC_SQL_SERVER |
— | SQL-эндпоинт Fabric Warehouse (альтернатива PROVISA_ENGINE_URL) |
FABRIC_DATABASE |
— | Имя базы данных Fabric Warehouse |
SYNAPSE_SQL_SERVER |
— | Serverless SQL-эндпоинт Synapse |
SYNAPSE_DATABASE |
— | Имя базы данных Synapse |
REDIS_URL |
— | URL подключения к Redis |
PROVISA_SAMPLE_SIZE |
10000 |
Ограничение выборки по умолчанию |
PROVISA_DEFAULT_ROW_LIMIT |
100 |
Ограничение количества строк, когда запрос не задаёт явный LIMIT |
PROVISA_RETRY_BUDGET_SECS |
30 |
Бюджет повторных попыток чтения уровня 1 в секундах; экспоненциальная задержка с полным джиттером (REQ-703) |
ZAYCHIK_PORT |
8480 |
Порт прокси Zaychik Flight SQL |
FLIGHT_PORT |
8815 |
Порт сервера Provisa Arrow Flight |
GRPC_PORT |
50051 |
Порт сервера Provisa Protobuf gRPC |
PROVISA_REDIRECT_ENABLED |
false |
Включает серверное перенаправление по порогу |
PROVISA_REDIRECT_THRESHOLD |
1000 |
Пороговое значение количества строк по умолчанию |
PROVISA_REDIRECT_FORMAT |
parquet |
Формат перенаправления по умолчанию |
PROVISA_REDIRECT_BUCKET |
provisa-results |
Bucket S3 для перенаправленных результатов |
PROVISA_REDIRECT_ENDPOINT |
— | URL S3-совместимого эндпоинта |
PROVISA_REDIRECT_ACCESS_KEY |
— | Ключ доступа S3 |
PROVISA_REDIRECT_SECRET_KEY |
— | Секретный ключ S3 |
PROVISA_REDIRECT_TTL |
3600 |
TTL подписанного URL (секунды) |
PROVISA_MTLS_CLIENT_CA |
— | Пакет PEM с CA, которым разрешено подписывать клиентские сертификаты; установка этой переменной включает проверку клиентских сертификатов на pgwire, Bolt, gRPC и Flight (REQ-1228) |
PROVISA_MTLS_MODE |
required, как только задан CA |
required или optional; любое другое значение приводит к отказу от запуска (REQ-1228) |
PROVISA_MTLS_BIND_PRINCIPAL |
false |
Требовать, чтобы общее имя (common name) сертификата совпадало с аутентифицирующимся именем пользователя (REQ-1228) |
PROVISA_BOLT_ALLOWED_ORIGINS |
— | Список сайтов через запятую, которым разрешено открывать WebSocket-соединение Bolt из браузера; если не задано, отклоняется любое происхождение (origin) браузера (REQ-802) |
PROVISA_EXTRAS |
firebase,vector |
Extras Pyproject, встроенные в образ приложения; scripts/provisa выводит их из dq_checker в ~/.provisa/config.yaml (REQ-1443) |
PROVISA_DQ_CHECKER |
none |
Только для установщика: none/soda/gx, считывается first-launch.sh в неинтерактивном режиме и записывается в config.yaml как dq_checker (REQ-1443) |
ANTHROPIC_API_KEY |
— | Ключ Claude API (обнаружение) |
OTEL_EXPORTER_OTLP_ENDPOINT |
— | Переопределяет observability.endpoint |
OTEL_SERVICE_NAME |
provisa |
Переопределяет observability.service_name |
OTEL_LOG_LEVEL |
WARNING |
Переопределяет observability.log_level |
OTEL_COMPACT_BATCH_SIZE |
10 |
Переопределяет observability.compact_batch_size |
OTEL_SPAN_EXPORT_DELAY_MILLIS |
1000 |
Задержка сброса пакетного процессора спанов |
PROVISA_SUPPORT_OTLP_ENDPOINT |
— | Переопределяет observability.support_endpoint |