Первоначальная настройка
Эти шаги выполняются один раз при первоначальной настройке проекта. Для быстрого старта см. Quick Start
Архитектура платформы
Интеграционная платформа состоит из 3 проектов:
| Проект | Описание | Хостинг |
|---|---|---|
| integ-core | Монорепозиторий с пакетами, интеграциями и Gateway | Cloudflare Workers |
| integ-api | API прокси: авторизация, MCP протокол, оркестрация | DigitalOcean VPS |
| integ-admin | Admin UI для управления интеграциями | DigitalOcean VPS |
┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐
│ integ-admin │────►│ integ-api │────►│ integ-core │
│ (UI) │ │ (Proxy) │ │ (Workers) │
│ VPS │ │ VPS │ │ Cloudflare Edge │
└─────────────┘ └─────────────┘ └─────────────────────┘Этот документ описывает настройку integ-core. Для настройки integ-api и integ-admin см. документацию в соответствующих репозиториях.
Обзор integ-core
Этот документ описывает одноразовую настройку инфраструктуры:
- Cloudflare Account и Workers
- D1 базы данных
- KV хранилища
- Doppler проект
- CI/CD (GitHub Actions)
- ACCESS_TOKEN для авторизации
1. Cloudflare Setup
1.1 Создать Cloudflare Account
- Зарегистрироваться на cloudflare.com
- Настроить домен
happ.tools - Получить API Token с правами Workers/D1/KV
1.2 Установить Wrangler CLI
npm install -g wrangler
wrangler login1.3 Создать D1 базы данных
Создаём 2 отдельные базы для dev и prod окружений:
# База для DEV окружения
wrangler d1 create integ-db-dev
# База для PROD окружения
wrangler d1 create integ-db-prodСохранить database_id из вывода каждой команды:
✅ Successfully created DB 'integ-db-dev'
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
✅ Successfully created DB 'integ-db-prod'
database_id = "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"1.4 Миграции
Миграции (включая создание таблицы creds) применяются автоматически при вызове POST /{integration}/setup. SQL-файлы и ручные команды wrangler d1 execute / wrangler d1 migrations apply не используются.
Все миграции (глобальные и integration-specific) являются code-based и управляются через
@happ-integ/core.
1.5 Указать ID баз для dev/prod
ID баз указываются в wrangler.toml.tpl или CI/CD pipeline (не в Doppler):
# templates/base/wrangler.toml.tpl или integrations/*/wrangler.toml.tpl
[[d1_databases]]
binding = "INTEG_DB"
database_name = "integ-db"
database_id = "{{D1_DB_ID}}" # Для CI/CD можно заменить на реальный IDЛокальная разработка: При запуске
pnpm start <integration>скриптgenerate:env localавтоматически подставляет placeholder ID. SQLite база создаётся вdata/miniflare/.
1.6 Создать KV Namespaces
Создаём 2 отдельных namespace для dev и prod окружений:
# KV для DEV окружения
wrangler kv namespace create integ-kv-dev
# KV для PROD окружения
wrangler kv namespace create integ-kv-prodСохранить id из вывода каждой команды:
🌀 Creating namespace with title "integ-kv-dev"
✨ Success!
[[kv_namespaces]]
binding = "INTEG_KV"
id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
🌀 Creating namespace with title "integ-kv-prod"
✨ Success!
[[kv_namespaces]]
binding = "INTEG_KV"
id = "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"1.7 Обновить wrangler.toml.tpl
Для dev/prod добавьте реальные ID в wrangler.toml.tpl:
name = "integ-[NAME]"
main = "dist/worker.js"
compatibility_date = "2024-01-01"
# Для локальной разработки
[[d1_databases]]
binding = "INTEG_DB"
database_name = "integ-db"
database_id = "00000000-0000-0000-0000-000000000001"
[[kv_namespaces]]
binding = "INTEG_KV"
id = "00000000000000000000000000000002"
preview_id = "00000000000000000000000000000002"
# DEV окружение
[env.dev]
name = "integ-[NAME]-dev"
[[env.dev.d1_databases]]
binding = "INTEG_DB"
database_name = "integ-db-dev"
database_id = "РЕАЛЬНЫЙ-UUID-DEV-БАЗЫ" # ← из wrangler d1 create integ-db-dev
[[env.dev.kv_namespaces]]
binding = "INTEG_KV"
id = "РЕАЛЬНЫЙ-UUID-DEV-KV" # ← из wrangler kv namespace create integ-kv-dev
# PRODUCTION окружение
[env.production]
name = "integ-[NAME]"
[[env.production.d1_databases]]
binding = "INTEG_DB"
database_name = "integ-db-prod"
database_id = "РЕАЛЬНЫЙ-UUID-PROD-БАЗЫ" # ← из wrangler d1 create integ-db-prod
[[env.production.kv_namespaces]]
binding = "INTEG_KV"
id = "РЕАЛЬНЫЙ-UUID-PROD-KV" # ← из wrangler kv namespace create integ-kv-prod💡 Для локальной разработки: ID
00000000-0000-0000-0000-000000000001(D1) и00000000000000000000000000000002(KV) используются для local dev — Miniflare создаёт локальные SQLite/KV вdata/miniflare/.NAME — плейсхолдер, заменяется на имя интеграции при генерации.
Примечание: Routes не используются — интеграции вызываются через Gateway по Service Bindings. Публичные домены настраиваются только для Gateway через Custom Domains.
Проверка
После выполнения всех шагов Cloudflare Setup, проверить что всё работает:
# Проверить авторизацию Wrangler
wrangler whoami
# Проверить D1 базы
wrangler d1 list
# Проверить KV namespaces
wrangler kv namespace list
# Проверить что таблица creds создана
wrangler d1 execute integ-db --command "SELECT name FROM sqlite_master WHERE type='table' AND name='creds'"Если всё работает, должны увидеть:
- Ваше имя/аккаунт в
wrangler whoami - Список баз в
wrangler d1 list(integ-db) - Список KV namespaces в
wrangler kv namespace list - Таблица
credsв результате SELECT запроса
2. Doppler Setup
2.1 Создать Doppler проект
- Зарегистрироваться на doppler.com
- Создать проект
integ-core - Создать environments:
local,dev,prod
2.2 Настроить секреты
Добавить в каждый environment:
CRYPTO_KEY— Ключ для шифрования credentials в D1CRYPTO_SALT— Соль для шифрованияOPENAI_API_KEY— API ключ OpenAIGROQ_API_KEY— API ключ GroqQDRANT_URL— URL Qdrant кластераQDRANT_API_KEY— API ключ Qdrant
2.3 Сгенерировать CRYPTO_KEY и CRYPTO_SALT
# Сгенерировать 32-байтный ключ
openssl rand -base64 32
# Сгенерировать соль (16+ символов)
openssl rand -base64 242.4 Создать doppler.yaml
# doppler.yaml (уже в репозитории)
setup:
project: integ-core
config: localПроверка
После выполнения всех шагов Doppler Setup:
# Проверить что Doppler настроен
doppler configs
# Проверить список секретов в dev
doppler secrets --config dev
# Проверить список секретов в prod
doppler secrets --config prod
# Проверить конкретный секрет (должен вернуть значение)
doppler secrets get CRYPTO_KEY --config devЕсли всё работает:
doppler configsпокажет доступные configs (local, dev, prod)doppler secretsпокажет список всех секретов в конфигеdoppler secrets getвернёт значение конкретного секрета (не будет ошибки)
3. CI/CD Setup (GitHub Actions)
3.1 Добавить GitHub Secrets
В настройках репозитория (Settings → Secrets → Actions):
CLOUDFLARE_WORKERS_API_TOKEN— API Token для Workers (D1, KV, deploy)CLOUDFLARE_PAGES_API_TOKEN— API Token для Pages (документация)CLOUDFLARE_ACCOUNT_ID— ID аккаунта CloudflareDEV_DOPPLER_TOKEN— Doppler Service Token для devPROD_DOPPLER_TOKEN— Doppler Service Token для prod
3.2 Деплой с Turborepo Cache
Деплой происходит автоматически через Turbo cache. Turbo сам определяет, какие пакеты изменились, и деплоит только их.
Как работает:
- Push в
dev→ Turbo проверяет кэш → деплоит только изменённые пакеты - Push в
main→ Turbo проверяет кэш → деплоит только изменённые пакеты
Примеры:
- Изменили
integrations/sofa/→ деплоится только sofa (gateway из кэша) - Изменили
packages/llm/→ деплоятся все интеграции зависящие от llm - Изменили
workers/gateway/→ деплоится только gateway
Workflows:
.github/workflows/deploy-to-dev.yml— деплой в dev при push вdev.github/workflows/deploy-to-prod.yml— деплой в prod при push вmain
Порядок деплоя:
- Checkout code
- Restore Turbo cache (
actions/cache) - Build all packages (
turbo build) - Deploy all (
turbo deploy:dev --filter='./integrations/*' --filter='integ-gateway') - Health check
- Verify deployment
Проверка
После добавления GitHub Secrets, проверить через GitHub UI:
- Перейти в репозиторий → Settings → Secrets and variables → Actions
- Должны быть видны 4 секрета
- Проверить что workflow работает:
- Сделать push в ветку
devилиmain(с изменением вintegrations/илиpackages/) - Перейти в репозиторий → Actions
- Должен запуститься workflow "Deploy to Dev" или "Deploy to Prod"
- Если workflow зелёный ✅ — всё настроено правильно
- Сделать push в ветку
4. DNS и Custom Domains
4.1 Архитектура Gateway
Проект использует Gateway Worker как единую точку входа:
integ.happ.tools/*
│
▼
┌───────────────────────┐
│ integ-gateway │
│ ───────────────── │
│ • Auth (x-access) │
│ • Rate limiting │
│ • Trace ID │
│ • Routing │
└───────────┬───────────┘
│
Service Bindings (внутренние вызовы)
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ integ-sofa │ │ integ-prom │ │ ... │
└────────────┘ └────────────┘ └────────────┘Домены:
integ.happ.tools→ Gateway (prod)integ.dev.happ.tools→ Gateway (dev)
URL структура:
/health— health check gateway/sofa/*→ Worker integ-sofa/prom/*→ Worker integ-prom
4.2 Добавить домен в Cloudflare
- Перейти в Cloudflare Dashboard
- Add a site → ввести
happ.tools - Выбрать план (Free подойдёт)
- Изменить nameservers у регистратора домена на те, что показал Cloudflare
4.3 Custom Domains для Gateway (ВАЖНО!)
⚠️ Этот шаг выполняется вручную после первого деплоя Gateway!
Проект использует Custom Domains (не Routes) для подключения доменов к Gateway Worker. Custom Domains — рекомендуемый способ от Cloudflare:
| Способ | DNS | SSL | Рекомендация |
|---|---|---|---|
| Routes (старый) | Вручную | Вручную | ❌ Устаревший |
| Custom Domains | Автоматически | Автоматически | ✅ Рекомендуемый |
После первого деплоя Gateway выполнить:
- Перейти в Cloudflare Dashboard → Workers & Pages
- Выбрать
integ-gateway-dev(илиinteg-gateway) - Settings → Domains & Routes → + Add → Custom domain
- Ввести домен:
- Для dev:
integ.dev.happ.tools - Для prod:
integ.happ.tools
- Для dev:
- Cloudflare автоматически создаст DNS запись и настроит SSL
┌─────────────────────────────────────────────────────────────┐
│ Cloudflare Workers Dashboard │
│ │
│ integ-gateway-dev │
│ ├── Settings │
│ │ └── Domains & Routes │
│ │ ├── workers.dev: Inactive │
│ │ └── Custom domains: │
│ │ └── ✅ integ.dev.happ.tools ← добавить сюда │
│ └── ... │
└─────────────────────────────────────────────────────────────┘Почему не Routes? Routes требуют ручной настройки DNS и могут конфликтовать с Custom Domains. В
wrangler.tomlroutes не используются — домены настраиваются через Dashboard.
4.4 Service Bindings
Gateway связывается с интеграциями через Service Bindings:
# workers/gateway/wrangler.toml
[[env.production.services]]
binding = "SOFA"
service = "integ-sofa"
[[env.dev.services]]
binding = "SOFA"
service = "integ-sofa-dev"Интеграции не имеют публичных доменов — вызываются через Gateway по Service Bindings.
ℹ️ При добавлении новой интеграции — см. Quick Start → Создание интеграции
4.5 Деплой
🚀 Деплой происходит автоматически через CI/CD!
См. раздел 4. CI/CD Setup
- Push в
devbranch → Автодеплой интеграций + Gateway в dev - Push в
mainbranch → Автодеплой интеграций + Gateway в production
Порядок деплоя в CI/CD:
- Сначала деплоятся все интеграции (они должны существовать для Service Bindings)
- Потом деплоится Gateway
⚠️ После первого деплоя:
При первом деплое Gateway будет доступен только по *.workers.dev URL. Чтобы он работал на кастомном домене:
- Добавить Custom Domain через Cloudflare Dashboard (см. раздел 5.3)
- Дождаться активации DNS (1-2 минуты)
4.6 Проверка
# Health check Gateway
curl https://integ.happ.tools/health
# Запрос к интеграции (через Gateway)
curl -H "x-access-token: YOUR_TOKEN" https://integ.happ.tools/sofa/webhook/webinar-call-originate5. Архитектура секретов
Проект использует два типа секретов:
5.1 Глобальные секреты (Doppler → CF Workers)
Одинаковые для всех интеграций. Хранятся в Doppler, синхронизируются в CF Workers env vars.
Список глобальных секретов:
CRYPTO_KEY— ключ для шифрования уникальных секретовCRYPTO_SALT— соль для шифрованияDATABASE_URL— Neon PostgreSQLOPENAI_API_KEY— OpenAI APIGROQ_API_KEY— Groq APIQDRANT_URL— Qdrant cluster URLQDRANT_API_KEY— Qdrant API key
Синхронизация (автоматически при деплое):
# Из директории интеграции:
cd integrations/sofa
pnpm sync-secrets:dev # dev окружение
pnpm sync-secrets:prod # production окружениеℹ️ Синхронизация запускается автоматически при
deploy:devиdeploy:prod
5.2 Уникальные секреты (D1 integ-db)
Специфичные для каждой интеграции. Хранятся в D1 зашифрованными (AES-256-GCM).
Примеры:
| Интеграция | Ключ | Описание |
|---|---|---|
sofa | NETHUNT_API_KEY | API ключ NetHunt |
sofa | NETHUNT_EMAIL | Email для NetHunt |
booking | BOOKING_SECRET | Секрет для booking API |
Использование в коде:
import { Creds } from "@happ-integ/creds";
const creds = new Creds({
d1: env.DB,
masterKey: env.CRYPTO_KEY,
salt: env.CRYPTO_SALT,
});
// Получить все секреты интеграции
const secrets = await creds.get<{
NETHUNT_API_KEY: string;
NETHUNT_EMAIL: string;
}>("sofa");
console.log(secrets.NETHUNT_API_KEY);Управление уникальными секретами:
// Установить секрет (через Admin UI или CLI)
await creds.set("sofa", "NETHUNT_API_KEY", "secret-value");
// Удалить секрет
await creds.delete("sofa", "NETHUNT_API_KEY");
// Список всех ключей интеграции
const keys = await creds.listKeys("sofa");5.3 Проверка
# Проверить глобальные секреты в CF Workers
cd integrations/sofa
wrangler secret list --env dev
# Должны быть:
# - CRYPTO_KEY
# - CRYPTO_SALT
# - DATABASE_URL
# - OPENAI_API_KEY
# - GROQ_API_KEYУникальные секреты проверяются через Admin UI или в коде через creds.listKeys('sofa')
6. ACCESS_TOKEN для Gateway
ACCESS_TOKEN — токен авторизации между integ-api и Gateway Worker. Все запросы к Gateway должны содержать заголовок x-access-token.
6.1 Сгенерировать токен
# Генерация случайного токена (32 байта = 64 hex символа)
openssl rand -hex 326.2 Добавить в Doppler
Добавить токен в Doppler → integ-core:
| Environment | Ключ | Значение |
|---|---|---|
dev | ACCESS_TOKEN | ваш_токен_для_dev |
prod | ACCESS_TOKEN | ваш_токен_для_prod |
Важно: Используйте разные токены для dev и prod окружений.
6.3 Синхронизировать в Gateway Worker
cd workers/gateway
# Dev
doppler secrets download --config dev --format json --no-file | \
jq -r '.ACCESS_TOKEN' | \
wrangler secret put ACCESS_TOKEN --env dev
# Production
doppler secrets download --config prod --format json --no-file | \
jq -r '.ACCESS_TOKEN' | \
wrangler secret put ACCESS_TOKEN --env productionУбедитесь, что
jqустановлен:brew install jq(macOS) илиapt install jq(Linux)
6.4 Использование
Все запросы от integ-api к Gateway должны содержать заголовок:
curl -H "x-access-token: ВАШ_ACCESS_TOKEN" \
https://integ.happ.tools/sofa/webhook/webinar-call-originate6.5 Проверка
cd workers/gateway
# Проверить что токен добавлен
wrangler secret list --env dev | grep ACCESS_TOKEN
wrangler secret list --env production | grep ACCESS_TOKENПримечание: Если
ACCESS_TOKENне настроен, Gateway пропускает авторизацию (удобно для локальной разработки). В production обязательно настройте токен!
7. Logging и Alerting Setup
7.1 Cloudflare Workers Logs
Логирование уже настроено в wrangler.toml каждой интеграции:
[observability.logs]
enabled = true
head_sampling_rate = 1
invocation_logs = trueПараметры:
enabled: включить сбор логовhead_sampling_rate: 1 = собирать 100% логов (0.1 = 10%, и т.д.)invocation_logs: логировать вызовы workers
Эти логи будут доступны в Cloudflare Dashboard → Workers → Logs.
7.2 Slack Webhook - создание incoming webhook
- Перейти в Slack: Browse → поиск "Incoming Webhooks" → откройте приложение
- Нажать "Add New Webhook to Workspace"
- Выбрать канал для алертов (например
#alerts-integили создать новый) - Нажать "Add Incoming Webhooks Integration"
- Скопировать Webhook URL (выглядит как
https://hooks.slack.com/services/T.../B.../...)
Сохранить этот URL — он понадобится на следующем шаге.
7.3 Cloudflare Notification Destination
- Перейти в Cloudflare Dashboard
- Перейти в Notifications (слева в боковом меню)
- Выбрать Destinations (вкладка)
- Нажать "Create" → выбрать "Webhook"
- Заполнить поля:
- Name:
Slack Alerts - URL: вставить ваш Slack Webhook URL (из шага 8.2)
- Secret: оставить пустым (Slack не требует)
- Name:
- Нажать "Save and test" (должна придти тестовая ошибка в Slack)
7.4 Alert Policy - настройка алертов на ошибки Workers
- В Notifications выбрать вкладку Alert Policies
- Нажать "Create"
- Выбрать тип alert: Workers → Workers Error
- Настроить параметры:
- Alert Name:
Workers Error Alert - Products: Workers
- Alert Type: Workers Error
- Script: выбрать интеграции (или оставить All scripts для всех):
integ-sofa-dev+integ-sofa(для Dev и Production)- Или оставить All scripts чтобы отслеживать все интеграции
- Notification Destinations: выбрать созданный
Slack Alertswebhook
- Alert Name:
- Нажать "Save"
Результат: При ошибке в Workers автоматически придёт сообщение в Slack.
7.5 Структурированное логирование в коде
В файлах интеграции используйте функции logError() и logInfo() для логирования:
// В handlers используйте ctx.log из handler context
import { defineHandler } from "@happ-integ/core";
export const myHandler = defineHandler({
name: "my-handler",
endpoint: "POST /webhook/my-handler",
async handler({ payload, ctx }) {
ctx.log("info", "handler:start", { phone: payload.phone_number });
try {
// ... бизнес-логика ...
ctx.log("info", "handler:success", { phone: payload.phone_number });
return { success: true };
} catch (error) {
ctx.log("error", "handler:error", { error: String(error) });
return { success: false };
}
},
});Примечание: Логирование через ctx.log() автоматически добавляет traceId, handler, timestamp и другие метаданные. Используйте формат "context:event" для первого аргумента.
7.6 Проверка что алерты работают
- Деплой интеграции:
cd integrations/sofa
pnpm build
pnpm deploy:dev- Отправить тестовый запрос с ошибкой:
# Запрос без обязательного параметра (это вызовет ошибку)
curl -X POST https://integ.dev.happ.tools/sofa/webhook/webinar-call-originate \
-H "x-access-token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{}' # Пусто - вызовет ошибку (phone_number is required)Проверить логи в Cloudflare Dashboard:
- Перейти в Workers and Pages →
integ-sofa-dev→ Logs - Должны видеть JSON логи с
level: "error", контекстом и деталями
- Перейти в Workers and Pages →
Проверить Slack:
- В канале
#alerts-integдолжно появиться сообщение об ошибке
- В канале
7.7 Просмотр логов по трассе
Каждый запрос имеет traceId для отслеживания через все сервисы:
# В логах вы увидите:
{
"level": "error",
"context": "webhook",
"traceId": "550e8400-e29b-41d4-a716-446655440000",
"message": "Request failed",
"timestamp": "2024-01-01T12:00:00Z",
"action": "init"
}Используйте этот traceId для поиска всех логов этого запроса:
- Cloudflare Dashboard → Workers → Logs
- В поле поиска введите:
550e8400-e29b-41d4-a716-446655440000 - Должны увидеть все логи этого запроса во всех сервисах
Проверка
После выполнения всех шагов Setup:
# Проверить что интеграция деплоена
wrangler deployments list --name integ-sofa-dev
# Проверить что Slack webhook работает
# (должны видеть сообщение "Test message" в Slack)
# Проверить что Alert Policy создана
# Cloudflare Dashboard → Notifications → Alert Policies
# Должна быть `Workers Error Alert` в спискеЧеклист готовности
- [ ] Cloudflare account настроен
- [ ] D1 база создана (
integ-db) - [ ] Миграции применены
- [ ] KV namespace создан
- [ ]
wrangler.tomlобновлён с реальными ID - [ ] Doppler проект создан с 3 environments
- [ ] Секреты добавлены в Doppler
- [ ] GitHub Secrets добавлены
- [ ] Секреты синхронизированы в CF Workers
- [ ]
ACCESS_TOKENдобавлен в Gateway Worker - [ ] Logging и Alerting настроены:
- [ ] Slack Incoming Webhook создан
- [ ] Cloudflare Notification Destination добавлена
- [ ] Alert Policy для Workers Errors создана
- [ ] Custom Domains настроены для Gateway (после первого деплоя):
- [ ]
integ.dev.happ.tools→integ-gateway-dev - [ ]
integ.happ.tools→integ-gateway
- [ ]
Финальная проверка
Детальные проверки каждого компонента уже описаны в соответствующих разделах. Эта секция для быстрой общей проверки что всё работает вместе.
Быстрая проверка перед началом работы:
# 1. Doppler работает
doppler secrets --config dev
# 2. Wrangler авторизован в Cloudflare
wrangler whoami
# 3. D1 база доступна и содержит таблицу credentials
wrangler d1 execute integ-db --command "SELECT 1"
# 4. KV доступен
wrangler kv namespace listЕсли все команды выполнены успешно — инфраструктура готова к использованию!
Следующие шаги
После выполнения этих шагов:
- ✅ Можно приступать к работе по Quick Start
- ✅ Деплой через CI/CD работает автоматически
- ✅ Новые интеграции создаются через
pnpm generate:integration